Techwebs & Experi-Sci (#17987)

* Techwebs

* Add basic stock parts

* Techweb production machines

* Circuit Imprinter

* More work

* More designs

* More designs, nodes'

* More more

* Better sorting for designs

* Add the exosuit fab'

* More conversions

* More and more and more

* mechfab parts

* Modsuit Designs

* Pinnace baron

* Equipment

* more mechfab

* vehicles

* more mecha

* Micro mechs

* Update mechfab_designs.dm

* no time

* zero

* Update mechfab_designs.dm

* Prosthetics Fabricator and fixes

* Update maps to use new parts

* Whoops, fix a few maps

* Fix lint error

* Port scene tools

* Fireworks~~

* Don't label the sex toys as sex toys

* Fixup maps in TGM format

26517b7122: maps/virgo_minitest/virgo_minitest-1.dmm

Automatically commited by: tools\mapmerge2\fixup.py

* Significant portion of designs converted

* Fix paths

* Fix tgui lints

* Just a whole bunch of designs

* Almost doneeee

* ALL DESIGNS CONVERTED

* Merk all of the old stuff

* Fix a few errors

* Fix more errors

* MORE FIX

* Make server control work

* Undo changes to archive

* Fix a TODO

* Make disks work

* Start the long process of finishing the node tree

* One more oops

* All mechfab designs

* Add departmental protolathes

* Down to 200 designs unsorted

* FINISH TECHWEBS

* Fuck whoops

* Remove the debug verbs

* Little map tweaks

* Fix mousedrop

* More map fixes

* Upstream bug lmao

* guess CI hates this

* Fixup maps in TGM format

fe062e7bc4: maps/tether/tether-03-surface3.dmm

Automatically commited by: tools\mapmerge2\fixup.py

* I gotta stop committing this

* Change scree requested

* Make science able to print implants too

* Fix ghost spawns

* Move NSFW gun

* Merk partbundles, make janus module work

* Pretty animation when you complete the tree :)

* Don't display designs you can't print

* Move security protolathes to warden's office

* Make servers recover from power failure gracefully

* Make fabricators drop their mats on the ground when destroyed

* Ore Silo

* Make CI happy

* Fixup maps in TGM format

fe062e7bc4: maps/tether/tether-05-station1.dmm

Automatically commited by: tools\mapmerge2\fixup.py

* Fix MC crash

* Make experiscanner work for borgs

* I REALLY gotta stop committing this

* Make scientists and the RD spawn with an experiscanner

* Lock NIFs behind scanning mice

* Make Biome happy

* Allow scanning Cocoa and Kendrick in case they can't find mice

* Change from Kendrick to Ratthew, ;help maint, or Brick

* Change the name of the /rat/pet class so the experiscanner is more helpful

* Add departmental_flags to a bunch of things

* Remove a few things from security's techfab

* Add a second engineering lathe to atmos

* Fix runtime recycling rig modules, add name to cost sequence

* Add a discount experiment for scanning slime cores

* Change some fluff and shuffle chameleon clothes to bluespace yadayada

* Make closets alt click immune

* Do a bunch of sorting

* Silly

* Hopefully fix all infinite material bugs in techwebs

* bad merge

* quick ai fix

* fix some robot stuff

* axe downlaod fully

* list

* no ref

* easier readable

---------

Co-authored-by: C.L. <killer65311@gmail.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
ShadowLarkens
2025-07-26 06:30:08 +02:00
committed by GitHub
co-authored by C.L. Kashargul
parent 93efaa653a
commit b60cd47309
271 changed files with 19410 additions and 11158 deletions
-17
View File
@@ -62,23 +62,6 @@
#define SMITE_SPICEREQUEST "Give Them Spice (Harmless)"
#define SMITE_PEPPERNADE "Give Them Spice (Extra Spicy)"
#define MODIFIY_ROBOT_MODULE_ADD "Add a Module"
#define MODIFIY_ROBOT_MODULE_REMOVE "Remove a Module"
#define MODIFIY_ROBOT_APPLY_UPGRADE "Apply an Upgrade"
#define MODIFIY_ROBOT_SUPP_ADD "Add Upgrade Support"
#define MODIFIY_ROBOT_SUPP_REMOVE "Remove Upgrade Support"
#define MODIFIY_ROBOT_RADIOC_ADD "Add a Radio Channel"
#define MODIFIY_ROBOT_RADIOC_REMOVE "Remove a Radio Channel"
#define MODIFIY_ROBOT_COMP_ADD "Replace a Component"
#define MODIFIY_ROBOT_COMP_REMOVE "Remove a Component"
#define MODIFIY_ROBOT_SWAP_MODULE "Swap a Robot Module"
#define MODIFIY_ROBOT_RESET_MODULE "Fully Reset Robot Module"
#define MODIFIY_ROBOT_TOGGLE_ERT "Toggle ERT Module Overwrite"
#define MODIFIY_ROBOT_LIMIT_MODULES_ADD "Restrict Modules to"
#define MODIFIY_ROBOT_LIMIT_MODULES_REMOVE "Remove from restricted Modules"
#define MODIFIY_ROBOT_TOGGLE_STATION_ACCESS "Toggle All Station Access Codes"
#define MODIFIY_ROBOT_TOGGLE_CENT_ACCESS "Toggle Central Access Codes"
#define ADMIN_QUE(user) "(<a href='byond://?_src_=holder;[HrefToken(TRUE)];adminmoreinfo=\ref[user]'>?</a>)"
#define ADMIN_FLW(user) "(<a href='byond://?_src_=holder;[HrefToken(TRUE)];adminplayerobservefollow=\ref[user]'>FLW</a>)"
#define ADMIN_PP(user) "(<a href='byond://?_src_=holder;[HrefToken(TRUE)];adminplayeropts=\ref[user]'>PP</a>)"
+23
View File
@@ -92,3 +92,26 @@
break; \
} \
}
/**
* Splits a stack. we don't use /obj/item/stack/proc/split_stack because Byond complains that should only be called asynchronously.
* This proc is also more faster because it doesn't deal with mobs, copying evidences or refreshing atom storages
* Has special internal uses for e.g. by the material container & RPED
*
* Arguments:
* - [target][obj/item/stack]: the stack to split
* - [amount]: amount to split by
*/
/proc/fast_split_stack(obj/item/stack/target, amount)
if(!target.use(amount))
return null
. = new target.type(target.drop_location(), amount)
//Special return values of [/datum/component/material_container/insert_item]
/// No material was found inside them item
#define MATERIAL_INSERT_ITEM_NO_MATS -1
/// The container does not have the space for the item
#define MATERIAL_INSERT_ITEM_NO_SPACE -2
/// The item material type was not accepted or other reasons
#define MATERIAL_INSERT_ITEM_FAILURE 0
@@ -0,0 +1,15 @@
//Material Container Signals
/// Called from datum/component/material_container/proc/can_hold_material() : (mat)
#define COMSIG_MATCONTAINER_MAT_CHECK "matcontainer_mat_check"
#define MATCONTAINER_ALLOW_MAT (1<<0)
/// Called from datum/component/material_container/proc/user_insert() : (target_item, user)
#define COMSIG_MATCONTAINER_PRE_USER_INSERT "matcontainer_pre_user_insert"
#define MATCONTAINER_BLOCK_INSERT (1<<1)
/// Called from datum/component/material_container/proc/insert_item() : (item, primary_mat, mats_consumed, material_amount, context)
#define COMSIG_MATCONTAINER_ITEM_CONSUMED "matcontainer_item_consumed"
/// Called from datum/component/material_container/proc/retrieve_sheets() : (new_sheets, context)
#define COMSIG_MATCONTAINER_SHEETS_RETRIEVED "matcontainer_sheets_retrieved"
//mat container signals but from the ore silo's perspective
/// Called from /obj/machinery/ore_silo/on_item_consumed() : (container, item_inserted, last_inserted_id, mats_consumed, amount_inserted)
#define COMSIG_SILO_ITEM_CONSUMED "silo_item_consumed"
@@ -0,0 +1,2 @@
///from /obj/machinery/computer/arcade/prizevend(mob/user, prizes = 1)
#define COMSIG_ARCADE_PRIZEVEND "arcade_prizevend"
@@ -0,0 +1,5 @@
/// Called when a techweb design is researched (datum/design/researched_design, custom)
#define COMSIG_TECHWEB_ADD_DESIGN "techweb_add_design"
/// Called when a techweb design is removed (datum/design/removed_design, custom)
#define COMSIG_TECHWEB_REMOVE_DESIGN "techweb_remove_design"
+41
View File
@@ -0,0 +1,41 @@
#define EXPERIMENT_CONFIG_ATTACKSELF "experiment_config_attackself"
#define EXPERIMENT_CONFIG_ALTCLICK "experiment_config_altclick"
// #define EXPERIMENT_CONFIG_CLICK "experiment_config_click"
#define EXPERIMENT_CONFIG_UI "experiment_config_ui"
/// Boolean stage, complete/incomplete. No specific progress to report.
#define EXPERIMENT_BOOL_STAGE "bool"
/// Integer stages, should be whole numbers with total being included
/// to support rendering ``value of total``, or something akin to it.
#define EXPERIMENT_INT_STAGE "integer"
/// Float stages, the value should be between 0 and 1 representing percent completion
#define EXPERIMENT_FLOAT_STAGE "float"
/// Detail stages, only provide more textual information and have no inherent progress
#define EXPERIMENT_DETAIL_STAGE "detail"
/// Macro for defining a progress stage
#define EXPERIMENT_PROGRESS(type, desc, values...) list(list(type, desc, values))
/// Macro for boolean stages
#define EXPERIMENT_PROG_BOOL(desc, complete) EXPERIMENT_PROGRESS(EXPERIMENT_BOOL_STAGE, desc, complete)
/// Macro for integer stages
#define EXPERIMENT_PROG_INT(desc, complete, total) EXPERIMENT_PROGRESS(EXPERIMENT_INT_STAGE, desc, complete, total)
/// Macro for float stages
#define EXPERIMENT_PROG_FLOAT(desc, complete) EXPERIMENT_PROGRESS(EXPERIMENT_FLOAT_STAGE, desc, complete)
/// Macro for non-valued stages, details for exp stages
#define EXPERIMENT_PROG_DETAIL(desc, complete) EXPERIMENT_PROGRESS(EXPERIMENT_DETAIL_STAGE, desc, complete)
/// Destructive experiments which will destroy the sample
#define EXPERIMENT_TRAIT_DESTRUCTIVE (1 << 0)
/// Used by scanning experiments: instead of storing refs or be a number, the list for scanned atoms is used as typecache
#define EXPERIMENT_TRAIT_TYPECACHE (1 << 1)
/// Will always attempt to action every experiment eligible with a single input,
/// no experiment selection required
#define EXPERIMENT_CONFIG_ALWAYS_ACTIVE (1 << 0)
/// Experiment handlers with this flag will not automatically connect to the first techweb they find
/// on initialization
#define EXPERIMENT_CONFIG_NO_AUTOCONNECT (1 << 1)
/// Experiment handlers with this flag won't pester the user of objects not pertinent to the test or if no experiment is selected
#define EXPERIMENT_CONFIG_SILENT_FAIL (1 << 2)
/// Experiment handlers with this flag will bypass any delay when trying to scan something
#define EXPERIMENT_CONFIG_IMMEDIATE_ACTION (1 << 3)
+11
View File
@@ -423,3 +423,14 @@
#define JOB_BORER "Borer"
#define JOB_EMERGENCY_RESPONSE_TEAM "Emergency Response Team"
#define JOB_MAINT_LURKER "Maintenance Lurker"
#define DEPARTMENT_BITFLAG_SECURITY (1<<0)
#define DEPARTMENT_BITFLAG_COMMAND (1<<1)
#define DEPARTMENT_BITFLAG_SERVICE (1<<2)
#define DEPARTMENT_BITFLAG_CARGO (1<<3)
#define DEPARTMENT_BITFLAG_ENGINEERING (1<<4)
#define DEPARTMENT_BITFLAG_SCIENCE (1<<5)
#define DEPARTMENT_BITFLAG_MEDICAL (1<<6)
#define DEPARTMENT_BITFLAG_SILICON (1<<7)
#define DEPARTMENT_BITFLAG_ASSISTANT (1<<8)
#define DEPARTMENT_BITFLAG_CAPTAIN (1<<9)
+2
View File
@@ -1,3 +1,5 @@
#define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text)
#define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text)
#define READ_FILE(file, text) DIRECT_INPUT(file, text)
#define INVESTIGATE_RESEARCH "research"
+2
View File
@@ -118,3 +118,5 @@
#define MATCONTAINER_SILENT (1<<3)
#define GET_MATERIAL_REF(arguments...) _GetMaterialRef(list(##arguments))
/// Makes sure only integer values are used when consuming, removing & checking for mats
#define OPTIMAL_COST(cost)(max(1, round(cost)))
+90
View File
@@ -1,4 +1,5 @@
#define SHEET_MATERIAL_AMOUNT 2000
#define MAX_STACK_SIZE 50
#define TECH_MATERIAL "materials"
#define TECH_ENGINEERING "engineering"
@@ -18,3 +19,92 @@
#define MECHFAB 0x0004 //Mechfab
#define CHASSIS 0x0008 //For protolathe, but differently
#define PROSFAB 0x0010 //For prosthetics fab
#define AUTOLATHE 0x0020 //For autolathe
/// For instances where we don't want a design showing up due to it being for debug/sanity purposes
#define DESIGN_ID_IGNORE "IGNORE_THIS_DESIGN"
//! Techweb names for new point types. Can be used to define specific point values for specific types of research (science, security, engineering, etc.)
#define TECHWEB_POINT_TYPE_GENERIC "General Research"
//! Amount of points required to unlock nodes of corresponding tiers
#define TECHWEB_TIER_1_POINTS 40
#define TECHWEB_TIER_2_POINTS 80
#define TECHWEB_TIER_3_POINTS 120
#define TECHWEB_TIER_4_POINTS 160
#define TECHWEB_TIER_5_POINTS 200
//! Amount of points gained per second by a single R&D server, see: [research][code/controllers/subsystem/research.dm]
#define TECHWEB_SINGLE_SERVER_INCOME 1
//! Swab cell line types
#define CELL_LINE_TABLE_SLUDGE "cell_line_sludge_table"
#define CELL_LINE_TABLE_MOLD "cell_line_mold_table"
#define CELL_LINE_TABLE_MOIST "cell_line_moist_table"
#define CELL_LINE_TABLE_BLOB "cell_line_blob_table"
#define CELL_LINE_TABLE_CLOWN "cell_line_clown_table"
#define CELL_LINE_TABLE_ALGAE "cell_line_algae_table"
//! Biopsy cell line types
#define CELL_LINE_TABLE_BEAR "cell_line_bear_table"
#define CELL_LINE_TABLE_BLOBBERNAUT "cell_line_blobbernaut_table"
#define CELL_LINE_TABLE_BLOBSPORE "cell_line_blobspore_table"
#define CELL_LINE_TABLE_CARP "cell_line_carp_table"
#define CELL_LINE_TABLE_CAT "cell_line_cat_table"
#define CELL_LINE_TABLE_CHICKEN "cell_line_chicken_table"
#define CELL_LINE_TABLE_COCKROACH "cell_line_cockroach_table"
#define CELL_LINE_TABLE_CORGI "cell_line_corgi_table"
#define CELL_LINE_TABLE_COW "cell_line_cow_table"
#define CELL_LINE_TABLE_MOONICORN "cell_line_moonicorn_table"
#define CELL_LINE_TABLE_GELATINOUS "cell_line_gelatinous_table"
#define CELL_LINE_TABLE_GLOCKROACH "cell_line_glockroach_table"
#define CELL_LINE_TABLE_GRAPE "cell_line_grape_table"
#define CELL_LINE_TABLE_HAUBEROACH "cell_line_hauberoach_table"
#define CELL_LINE_TABLE_MEGACARP "cell_line_megacarp_table"
#define CELL_LINE_TABLE_MOUSE "cell_line_mouse_table"
#define CELL_LINE_TABLE_PINE "cell_line_pine_table"
#define CELL_LINE_TABLE_PUG "cell_line_pug_table"
#define CELL_LINE_TABLE_SLIME "cell_line_slime_table"
#define CELL_LINE_TABLE_SNAKE "cell_line_snake_table"
#define CELL_LINE_TABLE_SNAIL "cell_line_snail_table"
#define CELL_LINE_TABLE_VATBEAST "cell_line_vatbeast_table"
#define CELL_LINE_TABLE_NETHER "cell_line_nether_table"
#define CELL_LINE_TABLE_GLUTTON "cell_line_glutton_table"
#define CELL_LINE_TABLE_CLOWNANA "cell_line_clownana_table"
#define CELL_LINE_TABLE_LONGFACE "cell_line_longface_table"
#define CELL_LINE_TABLE_FROG "cell_line_frog_table"
#define CELL_LINE_TABLE_AXOLOTL "cell_line_axolotl_table"
#define CELL_LINE_TABLE_WALKING_MUSHROOM "cell_line_walking_mushroom_table"
#define CELL_LINE_TABLE_QUEEN_BEE "cell_line_bee_queen_table"
#define CELL_LINE_TABLE_BUTTERFLY "cell_line_butterfly_table"
#define CELL_LINE_TABLE_MEGA_ARACHNID "cell_line_table_mega_arachnid"
//! All cell virus types
#define CELL_VIRUS_TABLE_GENERIC "cell_virus_generic_table"
#define CELL_VIRUS_TABLE_GENERIC_MOB "cell_virus_generic_mob_table"
//! General defines for vatgrowing
/// Past how much growth can the other cell_lines affect a finished cell line negatively
#define VATGROWING_DANGER_MINIMUM 30
//Defines how many percent of vat grown atoms come out as hue shifted color mutants. A flat chance for now, maybe in the future dependant on the cell line.
#define CYTO_SHINY_CHANCE 15
#define SCIPAPER_COOPERATION_INDEX 1
#define SCIPAPER_FUNDING_INDEX 2
#define SCIENTIFIC_COOPERATION_PURCHASE_MULTIPLIER 0.01
/// How much money is one point of gain worth.
#define SCIPAPER_GAIN_TO_MONEY 125
///Connects the 'server_var' to a valid research server on your Z level.
///Used for machines in LateInitialize, to ensure that RND servers are loaded first.
#define CONNECT_TO_RND_SERVER_ROUNDSTART(server_var, holder) do { \
var/list/found_servers = SSresearch.get_available_servers(get_turf(holder)); \
var/obj/machinery/rnd/server/selected_server = length(found_servers) ? found_servers[1] : null; \
if (selected_server) { \
server_var = selected_server.stored_research; \
}; \
else { \
var/datum/techweb/station_fallback_web = locate(/datum/techweb/science) in SSresearch.techwebs; \
server_var = station_fallback_web; \
}; \
} while (FALSE)
@@ -0,0 +1,223 @@
// Weapon Categories
#define RND_CATEGORY_WEAPONS "/Weaponry"
#define RND_SUBCATEGORY_WEAPONS_FIRING_PINS "/Firing Pins"
#define RND_SUBCATEGORY_WEAPONS_AMMO "/Ammunition"
#define RND_SUBCATEGORY_WEAPONS_PARTS "/Weapon Parts"
#define RND_SUBCATEGORY_WEAPONS_RANGED "/Ranged Weapons"
#define RND_SUBCATEGORY_WEAPONS_MELEE "/Melee Weapons"
#define RND_SUBCATEGORY_WEAPONS_KITS "/Weapon Fabrication Kits"
// Wiremod Categories
#define RND_CATEGORY_CIRCUITRY "/Circuitry"
#define RND_CATEGORY_CIRCUITRY_CORE "/Core"
#define RND_SUBCATEGORY_CIRCUITRY_COMPONENTS "/Circuit Components"
#define RND_SUBCATEGORY_CIRCUITRY_BCI_COMPONENTS "/Circuit BCI Components"
#define RND_SUBCATEGORY_CIRCUITRY_SHELLS "/Circuit Shells"
// Tool Categories
#define RND_CATEGORY_TOOLS "/Tools"
#define RND_SUBCATEGORY_TOOLS_MEDICAL "/Medical Tools"
#define RND_SUBCATEGORY_TOOLS_MEDICAL_ADVANCED "/Medical Tools (Advanced)"
#define RND_SUBCATEGORY_TOOLS_MEDICAL_ALIEN "/Medical Tools (Alien)"
#define RND_SUBCATEGORY_TOOLS_ENGINEERING "/Engineering Tools"
#define RND_SUBCATEGORY_TOOLS_ENGINEERING_ADVANCED "/Engineering Tools (Advanced)"
#define RND_SUBCATEGORY_TOOLS_ENGINEERING_ALIEN "/Engineering Tools (Alien)"
#define RND_SUBCATEGORY_TOOLS_SERVICE "/Service Tools"
#define RND_SUBCATEGORY_TOOLS_BOTANY "/Botany Tools"
#define RND_SUBCATEGORY_TOOLS_BOTANY_ADVANCED "/Botany Tools (Advanced)"
#define RND_SUBCATEGORY_TOOLS_JANITORIAL "/Janitorial Tools"
#define RND_SUBCATEGORY_TOOLS_PLUMBING "/Plumbing Tools"
#define RND_SUBCATEGORY_TOOLS_ATMOSPHERICS "/Atmospherics Tools"
#define RND_SUBCATEGORY_TOOLS_MINING "/Mining Tools"
#define RND_SUBCATEGORY_TOOLS_CARGO "/Cargo Tools"
#define RND_SUBCATEGORY_TOOLS_PKA_MODS "/PKA Modkits"
#define RND_SUBCATEGORY_TOOLS_SECURITY "/Security Tools"
#define RND_SUBCATEGORY_TOOLS_MISC "/Miscellaneous Tools"
#define RND_CATEGORY_CONSTRUCTION "/Construction"
#define RND_SUBCATEGORY_CONSTRUCTION_MOUNTS "/Frames & Mounts"
#define RND_SUBCATEGORY_CONSTRUCTION_ELECTRONICS "/Electronics"
#define RND_SUBCATEGORY_CONSTRUCTION_MACHINERY "/Machinery"
#define RND_SUBCATEGORY_CONSTRUCTION_MATERIALS "/Materials & Alloys"
#define RND_SUBCATEGORY_CONSTRUCTION_LIGHTING "/Lighting"
#define RND_SUBCATEGORY_CONSTRUCTION_ASSEMBLIES "/Electrical Assemblies"
#define RND_CATEGORY_COMPUTER "/Computer Boards"
#define RND_SUBCATEGORY_COMPUTER_ENTERTAINMENT "/Service Consoles"
#define RND_SUBCATEGORY_COMPUTER_MEDICAL "/Medical Consoles"
#define RND_SUBCATEGORY_COMPUTER_ROBOTICS "/Robotics Consoles"
#define RND_SUBCATEGORY_COMPUTER_GENETICS "/Genetics Consoles"
#define RND_SUBCATEGORY_COMPUTER_RECORDS "/Records Consoles"
#define RND_SUBCATEGORY_COMPUTER_COMMAND "/Command Consoles"
#define RND_SUBCATEGORY_COMPUTER_SECURITY "/Security Consoles"
#define RND_SUBCATEGORY_COMPUTER_RESEARCH "/Research Consoles"
#define RND_SUBCATEGORY_COMPUTER_ENGINEERING "/Engineering & Atmospherics Consoles"
#define RND_SUBCATEGORY_COMPUTER_CARGO "/Cargo Consoles"
#define RND_CATEGORY_MACHINE "/Machine Boards"
#define RND_SUBCATEGORY_MACHINE_ATMOS "/Atmospherics Machines"
#define RND_SUBCATEGORY_MACHINE_KITCHEN "/Kitchen Machines"
#define RND_SUBCATEGORY_MACHINE_BAR "/Bar Machines"
#define RND_SUBCATEGORY_MACHINE_BOTANY "/Botany Machines"
#define RND_SUBCATEGORY_MACHINE_ENGINEERING "/Engineering Machines"
#define RND_SUBCATEGORY_MACHINE_RESEARCH "/Research Machines"
#define RND_SUBCATEGORY_MACHINE_MEDICAL "/Medical Machines"
#define RND_SUBCATEGORY_MACHINE_CHEMISTRY "/Chemistry Machines"
#define RND_SUBCATEGORY_MACHINE_SECURITY "/Security Machines"
#define RND_SUBCATEGORY_MACHINE_CARGO "/Cargo Machines"
#define RND_SUBCATEGORY_MACHINE_TELEPORT "/Teleportation Machines"
#define RND_SUBCATEGORY_MACHINE_ROBOTICS "/Robotics Machines"
#define RND_SUBCATEGORY_MACHINE_GENETICS "/Genetics Machines"
#define RND_SUBCATEGORY_MACHINE_FAB "/Fabricators"
#define RND_SUBCATEGORY_MACHINE_SERVICE "/Service Machines"
#define RND_SUBCATEGORY_MACHINE_TELECOMMS "/Telecommunications Machines"
#define RND_CATEGORY_EQUIPMENT "/Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_SERVICE "/Service Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_JOKE "/Top-Secret Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_CHEMISTRY "/Chemistry Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_MEDICAL "/Medical Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_SECURITY "/Security Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_TELECOMMS "/Communications Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_BLUESPACE "/Bluespace Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_ENGINEERING "/Engineering Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_ATMOSPHERICS "/Atmospherics Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_SCIENCE "/Science Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_GAS_TANKS "/Gas Tanks"
#define RND_SUBCATEGORY_EQUIPMENT_GAS_TANKS_EQUIPMENT "/Gas Tank Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_XENOBIOLOGY "/Xenobiology Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_GENETICS "/Genetics Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_JANITOR "/Janitorial Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_KITCHEN "/Bar & Kitchen Equipment"
#define RND_SUBCATEGORY_EQUIPMENT_MISC "/Miscellaneous Equipment"
#define RND_CATEGORY_FIREWORKS "/Fireworks"
#define RND_CATEGORY_AI "/Artificial Intelligence"
#define RND_SUBCATEGORY_AI_CORE "/AI Construction"
#define RND_SUBCATEGORY_AI_CORE_MODULES "/Core AI Modules"
#define RND_SUBCATEGORY_AI_DANGEROUS_MODULES "/Dangerous AI Modules"
#define RND_SUBCATEGORY_AI_LAW_MANIPULATION "/AI Law Manipulation"
#define RND_SUBCATEGORY_AI_MISC "/Miscellaneous AI Items"
#define RND_SUBCATEGORY_AI_UPGRADES "/AI Upgrades"
#define RND_CATEGORY_MODULAR_COMPUTERS "/Modular Computers"
#define RND_SUBCATEGORY_MODULAR_COMPUTERS_FRAMES "/Frames"
#define RND_SUBCATEGORY_MODULAR_COMPUTERS_PARTS "/Parts"
#define RND_CATEGORY_STOCK_PARTS "/Stock Parts"
#define RND_SUBCATEGORY_STOCK_PARTS_MISC "/Miscellaneous Parts"
#define RND_SUBCATEGORY_STOCK_PARTS_TURBINE "/Turbine Parts"
#define RND_SUBCATEGORY_STOCK_PARTS_TELECOMMS "/Telecommunications Parts"
#define RND_SUBCATEGORY_STOCK_PARTS_1 "/Tier 1 Parts"
#define RND_SUBCATEGORY_STOCK_PARTS_2 "/Tier 2 Parts"
#define RND_SUBCATEGORY_STOCK_PARTS_3 "/Tier 3 Parts"
#define RND_SUBCATEGORY_STOCK_PARTS_4 "/Tier 4 Parts"
#define RND_SUBCATEGORY_STOCK_PARTS_5 "/Tier 5 Parts"
#define RND_SUBCATEGORY_STOCK_PARTS_EXCHANGERS "/Exchange Devices"
#define RND_CATEGORY_SYNDICATE "/Illegal Designs"
#define RND_CATEGORY_EXOSUIT_BOARDS "/Exosuit Boards"
#define RND_SUBCATEGORY_EXOSUIT_BOARDS_RIPLEY "/Ripley"
#define RND_SUBCATEGORY_EXOSUIT_BOARDS_ODYSSEUS "/Odysseus"
#define RND_SUBCATEGORY_EXOSUIT_BOARDS_GYGAX "/Gygax"
#define RND_SUBCATEGORY_EXOSUIT_BOARDS_DURAND "/Durand"
#define RND_SUBCATEGORY_EXOSUIT_BOARDS_HONK "/H.O.N.K."
#define RND_SUBCATEGORY_EXOSUIT_BOARDS_PHAZON "/Phazon"
#define RND_SUBCATEGORY_EXOSUIT_BOARDS_CLARKE "/Clarke"
#define RND_SUBCATEGORY_EXOSUIT_BOARDS_SAVANNAH_IVANOV "/Savannah-Ivanov"
#define RND_CATEGORY_MECHFAB_RIPLEY "/Ripley"
#define RND_CATEGORY_MECHFAB_PADDY "/Paddy"
#define RND_CATEGORY_MECHFAB_ODYSSEUS "/Odysseus"
#define RND_CATEGORY_MECHFAB_GYGAX "/Gygax"
#define RND_CATEGORY_MECHFAB_DURAND "/Durand"
#define RND_CATEGORY_MECHFAB_HONK "/H.O.N.K."
#define RND_CATEGORY_MECHFAB_PHAZON "/Phazon"
#define RND_CATEGORY_MECHFAB_JANUS "/Janus"
#define RND_CATEGORY_MECHFAB_CLARKE "/Clarke"
#define RND_CATEGORY_MECHFAB_SAVANNAH_IVANOV "/Savannah-Ivanov"
#define RND_CATEGORY_MECHFAB_JUSTICE "/Justice"
#define RND_CATEGORY_MECHFAB_PINNACE "/Pinnace"
#define RND_CATEGORY_MECHFAB_BARON "/Baron"
#define RND_CATEGORY_MECHFAB_GOPHER "/Gopher"
#define RND_CATEGORY_MECHFAB_POLECAT "/Polecat"
#define RND_CATEGORY_MECHFAB_WEASEL "/Weasel"
#define RND_SUBCATEGORY_MECHFAB_CHASSIS "/Chassis"
#define RND_SUBCATEGORY_MECHFAB_VEHICLE "/Vehicle"
#define RND_SUBCATEGORY_MECHFAB_SUPPORTED_EQUIPMENT "/Supported Equipment"
#define RND_SUBCATEGORY_MECHFAB_CONTROL_INTERFACES "/Control Interfaces"
#define RND_CATEGORY_MECHFAB_EQUIPMENT "/Exosuit Equipment"
#define RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MINING "/Mining Equipment"
#define RND_SUBCATEGORY_MECHFAB_EQUIPMENT_WEAPONS "/Weapons & Ammunition"
#define RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MODULES "/Armor & Repair Modules"
#define RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MISC "/Miscellaneous"
#define RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL "/Medical"
#define RND_SUBCATEGORY_MECHFAB_EQUIPMENT_HONK "/Clown Designs"
#define RND_SUBCATEGORY_MECHFAB_EQUIPMENT_CONTROL_INTERFACES "/Control Interfaces"
#define RND_CATEGORY_MECHFAB_CYBORG "/Cyborg"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_CHASSIS "/Cyborg Chassis"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_COMPONENTS "/Components"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_CELLS "/Power Cells"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_CONTROL_INTERFACES "/Control Interfaces"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_INTERNALS "/Internals"
#define RND_CATEGORY_MECHFAB_CYBORG_MODULES "/Cyborg Modules"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_ALL "/All Cyborgs"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_MEDICAL "/Medical Cyborgs"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_ENGINEERING "/Engineering Cyborgs"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_JANITOR "/Janitorial Cyborgs"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_SECURITY "/Security Cyborgs"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_MINING "/Mining Cyborgs"
#define RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_SERVICE "/Service Cyborgs"
#define RND_CATEGORY_PROSFAB "/Prosthetics"
#define RND_SUBCATEGORY_PROSFAB_EXTERNAL "/External"
#define RND_SUBCATEGORY_PROSFAB_INTERNAL "/Internal"
#define RND_SUBCATEGORY_PROSFAB_MISC "/Misc"
#define RND_CATEGORY_PROSFAB_PAI "/pAI"
#define RND_CATEGORY_MODSUITS "/MOD Suits"
#define RND_SUBCATEGORY_MODUITS_CHASSIS "/Chassis"
#define RND_SUBCATEGORY_MODSUITS_PLATING "/Plating"
#define RND_SUBCATEGORY_MODSUITS_MISC "/Misc"
#define RND_CATEGORY_MODSUIT_MODULES "/MOD Modules"
#define RND_SUBCATEGORY_MODSUIT_MODULES_GENERAL "/General Modules"
#define RND_SUBCATEGORY_MODSUIT_MODULES_ENGINEERING "/Engineering Modules"
#define RND_SUBCATEGORY_MODSUIT_MODULES_MEDICAL "/Medical Modules"
#define RND_SUBCATEGORY_MODSUIT_MODULES_SCIENCE "/Science Modules"
#define RND_SUBCATEGORY_MODSUIT_MODULES_SECURITY "/Security Modules"
#define RND_SUBCATEGORY_MODSUIT_MODULES_SUPPLY "/Supply Modules"
#define RND_SUBCATEGORY_MODSUIT_MODULES_SERVICE "/Service Modules"
#define RND_CATEGORY_CYBERNETICS "/Cybernetics"
#define RND_SUBCATEGORY_CYBERNETICS_ORGANS_1 "/Tier 1 Cybernetic Organs"
#define RND_SUBCATEGORY_CYBERNETICS_ORGANS_2 "/Tier 2 Cybernetic Organs"
#define RND_SUBCATEGORY_CYBERNETICS_ORGANS_3 "/Tier 3 Cybernetic Organs"
#define RND_SUBCATEGORY_CYBERNETICS_ORGANS_COMBAT "/Combat Cybernetic Organs"
#define RND_SUBCATEGORY_CYBERNETICS_ORGANS_MISC "/Miscellaneous Cybernetic Organs"
#define RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_COMBAT "/Cybernetic Combat Implants"
#define RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_HEALTH "/Cybernetic Health Implants"
#define RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_TOOLS "/Cybernetic Implanting Tools"
#define RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_UTILITY "/Cybernetic Utility Implants"
#define RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_MISC "/Cybernetic Miscellaneous Implants"
#define RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_SECURITY "/Cybernetic Security Implants"
#define RND_SUBCATEGORY_CYBERNETICS_ADVANCED_LIMBS "/Cybernetic Advanced Limbs"
// Limb Categories
#define RND_CATEGORY_LIMBS_DIGITIGRADE "digitigrade"
#define RND_CATEGORY_LIMBS_OTHER "Other Limbs"
/// Biogenerator Categories
#define RND_CATEGORY_BIO_FOOD "Food"
#define RND_CATEGORY_BIO_CHEMICALS "Chemicals"
#define RND_CATEGORY_BIO_MATERIALS "Materials"
// Meta categories
#define RND_CATEGORY_INITIAL "initial"
#define RND_CATEGORY_HACKED "hacked"
#define RND_CATEGORY_IMPORTED "/Imported Designs"
+134
View File
@@ -0,0 +1,134 @@
#define TECHWEB_NODE_AI "ai"
#define TECHWEB_NODE_AI_LAWS "ai_laws"
#define TECHWEB_NODE_ALIEN_ENGI "alien_engi"
#define TECHWEB_NODE_ALIEN_SURGERY "alien_surgery"
#define TECHWEB_NODE_ALIENTECH "alientech"
#define TECHWEB_NODE_ANOMALY_RESEARCH "anomaly_research"
#define TECHWEB_NODE_ANOMALY_SHELLS "anomaly_shells"
#define TECHWEB_NODE_APPLIED_BLUESPACE "applied_bluespace"
#define TECHWEB_NODE_ATMOS "atmos"
#define TECHWEB_NODE_AUGMENTATION "augmentation"
#define TECHWEB_NODE_AUS_SECURITY "aus_security"
#define TECHWEB_NODE_BASIC_ARMS "basic_arms"
#define TECHWEB_NODE_BCI "bci"
#define TECHWEB_NODE_BEAM_WEAPONS "beam_weapons"
#define TECHWEB_NODE_BIO_SCAN "bio_scan"
#define TECHWEB_NODE_BITRUNNING "bitrunning"
#define TECHWEB_NODE_MECH_EQUIP_BLUESPACE "mech_equip_bluespace"
#define TECHWEB_NODE_BLUESPACE_THEORY "bluespace_theory"
#define TECHWEB_NODE_BLUESPACE_TRAVEL "bluespace_travel"
#define TECHWEB_NODE_BORG_ENGI "borg_engi"
#define TECHWEB_NODE_BORG_MEDICAL "borg_medical"
#define TECHWEB_NODE_BORG_MINING "borg_mining"
#define TECHWEB_NODE_BORG_SERVICES "borg_services"
#define TECHWEB_NODE_BORG_SYNDI "borg_syndi"
#define TECHWEB_NODE_BORG_UTILITY "borg_utility"
#define TECHWEB_NODE_BOTANY_EQUIP "botany_equip"
#define TECHWEB_NODE_CAFETERIA_EQUIP "cafeteria_equip"
#define TECHWEB_NODE_CHEM_SYNTHESIS "chem_synthesis"
#define TECHWEB_NODE_CIRCUIT_SHELLS "circuit_shells"
#define TECHWEB_NODE_COMBAT_IMPLANTS "combat_implants"
#define TECHWEB_NODE_CONSOLES "consoles"
#define TECHWEB_NODE_CONSTRUCTION "construction"
#define TECHWEB_NODE_CRYOSTASIS "cryostasis"
#define TECHWEB_NODE_CYBER_IMPLANTS "cyber_implants"
#define TECHWEB_NODE_CYBER_ORGANS "cyber_organs"
#define TECHWEB_NODE_CYBER_ORGANS_ADV "cyber_organs_adv"
#define TECHWEB_NODE_CYBER_ORGANS_UPGRADED "cyber_organs_upgraded"
#define TECHWEB_NODE_CYBERNETICS "cybernetics"
#define TECHWEB_NODE_CYTOLOGY "cytology"
#define TECHWEB_NODE_DONK_PRODUCTS "donk_products"
#define TECHWEB_NODE_ELECTRIC_WEAPONS "electric_weapons"
#define TECHWEB_NODE_ENERGY_MANIPULATION "energy_manipulation"
#define TECHWEB_NODE_EXODRONE "exodrone"
#define TECHWEB_NODE_EXOTIC_AMMO "exotic_ammo"
#define TECHWEB_NODE_EXP_TOOLS "exp_tools"
#define TECHWEB_NODE_EXPLOSIVES "explosives"
#define TECHWEB_NODE_EXTREME_OFFICE "extreme_office"
#define TECHWEB_NODE_FIREWORKS "fireworks"
#define TECHWEB_NODE_FISHING_EQUIP "fishing_equip"
#define TECHWEB_NODE_FISHING_EQUIP_ADV "fishing_equip_adv"
#define TECHWEB_NODE_FOOD_PROC "food_proc"
#define TECHWEB_NODE_FUNDIMENTAL_SCI "fundimental_sci"
#define TECHWEB_NODE_FUSION "fusion"
#define TECHWEB_NODE_GAMING "gaming"
#define TECHWEB_NODE_GAS_COMPRESSION "gas_compression"
#define TECHWEB_NODE_GENE_ENGINEERING "gene_engineering"
#define TECHWEB_NODE_HOLOGRAPHICS "holographics"
#define TECHWEB_NODE_HUD "hud"
#define TECHWEB_NODE_HYDROPONICS "hydroponics"
#define TECHWEB_NODE_INTERGRATED_TOOLSETS "intergrated_toolsets"
#define TECHWEB_NODE_INTERROGATION "interrogation"
#define TECHWEB_NODE_ILLEGAL_SCENETOOLS "illegal_scenetools"
#define TECHWEB_NODE_LIGHT_APPS "light_apps"
#define TECHWEB_NODE_LOW_PRESSURE_EXCAVATION "low_pressure_excavation"
#define TECHWEB_NODE_MARINE_UTIL "marine_util"
#define TECHWEB_NODE_MATERIAL_PROC "material_proc"
#define TECHWEB_NODE_MECH_ASSAULT "mech_assault"
#define TECHWEB_NODE_MECH_ASSEMBLY "mech_assembly"
#define TECHWEB_NODE_MECH_CLOWN "mech_clown"
#define TECHWEB_NODE_MECH_COMBAT "mech_combat"
#define TECHWEB_NODE_MECH_ENERGY_GUNS "mech_energy_guns"
#define TECHWEB_NODE_MECH_EQUIPMENT "mech_equipment"
#define TECHWEB_NODE_MECH_FIGHTER "mech_fighter"
#define TECHWEB_NODE_MECH_FIREARMS "mech_firearms"
#define TECHWEB_NODE_MECH_HEAVY "mech_heavy"
#define TECHWEB_NODE_MECH_HEAVY_ARMS "mech_heavy_arms"
#define TECHWEB_NODE_MECH_INFILTRATOR "mech_infiltrator"
#define TECHWEB_NODE_MECH_LIGHT "mech_light"
#define TECHWEB_NODE_MECH_MEDICAL "mech_medical"
#define TECHWEB_NODE_MECH_MINING "mech_mining"
#define TECHWEB_NODE_MEDBAY_EQUIP "medbay_equip"
#define TECHWEB_NODE_MEDBAY_EQUIP_ADV "medbay_equip_adv"
#define TECHWEB_NODE_MEDIGUN "medbay_medigun"
#define TECHWEB_NODE_MINING "mining"
#define TECHWEB_NODE_MINING_ADV "mining_adv"
#define TECHWEB_NODE_MOD_ANOMALY "mod_anomaly"
#define TECHWEB_NODE_MOD_ENGI "mod_engi"
#define TECHWEB_NODE_MOD_ENGI_ADV "mod_engi_adv"
#define TECHWEB_NODE_MOD_ENTERTAINMENT "mod_entertainment"
#define TECHWEB_NODE_MOD_EQUIP "mod_equip"
#define TECHWEB_NODE_MOD_EXPERIMENTAL "mod_experimental"
#define TECHWEB_NODE_MOD_MEDICAL "mod_medical"
#define TECHWEB_NODE_MOD_MEDICAL_ADV "mod_medical_adv"
#define TECHWEB_NODE_MOD_SECURITY "mod_security"
#define TECHWEB_NODE_MOD_SUIT "mod_suit"
#define TECHWEB_NODE_MODULAR_COMPUTER "modular_computer"
#define TECHWEB_NODE_NIF "nif"
#define TECHWEB_NODE_NIGHT_VISION "night_vision"
#define TECHWEB_NODE_NSFW "nsfwgun"
#define TECHWEB_NODE_OFFICE_EQUIP "office_equip"
#define TECHWEB_NODE_OLDSTATION_SURGERY "oldstation_surgery"
#define TECHWEB_NODE_PARTS "parts"
#define TECHWEB_NODE_PARTS_ADV "parts_adv"
#define TECHWEB_NODE_PARTS_HYPER "parts_hyper"
#define TECHWEB_NODE_PARTS_OMNI "parts_omni"
#define TECHWEB_NODE_PARTS_UPG "parts_upg"
#define TECHWEB_NODE_PASSIVE_IMPLANTS "passive_implants"
#define TECHWEB_NODE_PLASMA_CONTROL "plasma_control"
#define TECHWEB_NODE_PLASMA_MINING "plasma_mining"
#define TECHWEB_NODE_POSITRONIC_SPHERE "positronic_sphere"
#define TECHWEB_NODE_PROGRAMMED_ROBOT "programmed_robot"
#define TECHWEB_NODE_PROGRAMMED_SERVER "programmed_server"
#define TECHWEB_NODE_PROGRAMMING "programming"
#define TECHWEB_NODE_PROTEAN "protean"
#define TECHWEB_NODE_RCD_UPGRADE "rcd_upgrade"
#define TECHWEB_NODE_RIOT_SUPRESSION "riot_supression"
#define TECHWEB_NODE_ROBOTICS "robotics"
#define TECHWEB_NODE_SANITATION "sanitation"
#define TECHWEB_NODE_SCENE_TOOLS "scenetools"
#define TECHWEB_NODE_SEC_EQUIP "sec_equip"
#define TECHWEB_NODE_SELECTION "selection"
#define TECHWEB_NODE_SHUTTLE_ENG "shuttle_eng"
#define TECHWEB_NODE_SIZEPLAY "sizeplay"
#define TECHWEB_NODE_SPEC_ENG "spec_eng"
#define TECHWEB_NODE_STICKY_ADVANCED "sticky_advanced"
#define TECHWEB_NODE_SURGERY "surgery"
#define TECHWEB_NODE_SURGERY_ADV "surgery_adv"
#define TECHWEB_NODE_SURGERY_EXP "surgery_exp"
#define TECHWEB_NODE_SURGERY_TOOLS "surgery_tools"
#define TECHWEB_NODE_SYNDICATE_BASIC "syndicate_basic"
#define TECHWEB_NODE_TACKLE_ADVANCED "tackle_advanced"
#define TECHWEB_NODE_TELECOMS "telecoms"
#define TECHWEB_NODE_UNREGULATED_BLUESPACE "unregulated_bluespace"
#define TECHWEB_NODE_XENOBIOLOGY "xenobiology"
+1
View File
@@ -137,6 +137,7 @@ GLOBAL_LIST_INIT(runlevel_flags, list(
#define INIT_ORDER_ROBOT_SPRITES 34
#define INIT_ORDER_VIS 32
#define INIT_ORDER_MAPPING 25
#define INIT_ORDER_RESEARCH 24
#define INIT_ORDER_SOUNDS 23
#define INIT_ORDER_INSTRUMENTS 22
#define INIT_ORDER_DECALS 20
-1
View File
@@ -145,7 +145,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define SPECIES_TRAIT "species"
#define ORGAN_TRAIT "organ"
*/
#define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention
#define JOB_TRAIT "job"
#define TRAIT_MIME "mime" //Mime trait.
/*
+1 -1
View File
@@ -2,6 +2,6 @@
// Several things such as `type` or `REF(src)` may be used in the ADD_TRAIT() macro as the "source", but this file contains all of the defines for immutable static strings.
/// cannot be removed without admin intervention
// #define ROUNDSTART_TRAIT "roundstart"
#define ROUNDSTART_TRAIT "roundstart"
/// This trait comes from when a mob is currently typing.
#define CURRENTLY_TYPING_TRAIT "currently_typing"
+2
View File
@@ -15,3 +15,5 @@ GLOBAL_LIST_INIT(char_directory_gendertags, list("Male", "Female", "Feminine", "
GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes
GLOBAL_LIST_INIT(uplink_locations, list("PDA", "Headset", "None"))
GLOBAL_LIST_EMPTY(experiment_handlers)
+4
View File
@@ -0,0 +1,4 @@
///The global ore silo shared by all machines at round start
GLOBAL_DATUM(ore_silo_default, /obj/machinery/ore_silo)
///List of logs shared by all silos
GLOBAL_LIST_EMPTY(silo_access_logs)
+32
View File
@@ -367,6 +367,38 @@
if(M.client)
viewing += M.client
flick_overlay(I, viewing, duration, gc_after)
/**
* Helper atom that copies an appearance and exists for a period
*/
/atom/movable/flick_visual
/// Takes the passed in MA/icon_state, mirrors it onto ourselves, and displays that in world for duration seconds
/// Returns the displayed object, you can animate it and all, but you don't own it, we'll delete it after the duration
/atom/proc/flick_overlay_view_atom(mutable_appearance/display, duration)
if(!display)
return null
var/mutable_appearance/passed_appearance = \
istext(display) \
? mutable_appearance(icon, display, layer) \
: display
// If you don't give it a layer, we assume you want it to layer on top of this atom
// Because this is vis_contents, we need to set the layer manually (you can just set it as you want on return if this is a problem)
if(passed_appearance.layer == FLOAT_LAYER)
passed_appearance.layer = layer + 0.1
// This is faster then pooling. I promise
var/atom/movable/flick_visual/visual = new()
visual.appearance = passed_appearance
visual.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
// I hate /area
var/atom/movable/lies_to_children = src
lies_to_children.vis_contents += visual
QDEL_IN_CLIENT_TIME(visual, duration)
return visual
/area/flick_overlay_view_atom(mutable_appearance/display, duration)
return
/proc/isInSight(var/atom/A, var/atom/B)
var/turf/Aturf = get_turf(A)
+7
View File
@@ -188,6 +188,13 @@
/proc/log_asset(text)
WRITE_LOG(GLOB.diary, "ASSET: [text]")
/// Puts the text into the research html file, not log. See [INVESTIGATE_RESEARCH] for [/atom/proc/investigate_log]
/proc/log_research(text)
if(!text)
return
var/html_file = file("[GLOB.log_directory]/[INVESTIGATE_RESEARCH].html")
WRITE_FILE(html_file, "[time_stamp()] [text]<br>")
/proc/report_progress(var/progress_message)
admin_notice(span_boldannounce("[progress_message]"), R_DEBUG)
to_world_log(progress_message)
+77
View File
@@ -1595,3 +1595,80 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
return "CLIENT: [D]"
else
return "Unknown data type: [D]"
/**
* - is_valid_z_level
*
* Checks if source_loc and checking_loc is both on the station, or on the same z level.
* This is because the station's several levels aren't considered the same z, so multi-z stations need this special case.
*
* Args:
* source_loc - turf of the source we're comparing.
* checking_loc - turf we are comparing to source_loc.
*
* returns TRUE if connection is valid, FALSE otherwise.
*/
/proc/is_valid_z_level(turf/source_loc, turf/checking_loc)
return is_on_same_plane_or_station(source_loc.z, checking_loc.z)
/**
* divides a list of materials uniformly among all contents of the target_object recursively
* Used to set materials of printed items with their design cost by taking into consideration their already existing materials
* e.g. if 12 iron is to be divided uniformly among 2 objects A, B who's current iron contents are 3 & 7
* Then first we normalize those values i.e. find their weights to decide who gets an higher share of iron
* total_sum = 3 + 7 = 10, A = 3/10 = 0.3, B = 7/10 = 0.7
* Then we finally multiply those weights with the user value of 12 we get
* A = 0.3 * 12 = 3.6, B = 0.7 * 12 = 8.4 i.e. 3.6 + 8.4 = 12!!
* Off course we round the values so we don't have to deal with floating point materials so the actual value
* ends being less but that's not an issue
* Arguments
*
* * [custom_materials][list] - the list of materials to set for the object
* * multiplier - multiplier passed to set_custom_materials
* * [target_object][atom] - the target object who's custom materials we are trying to modify
*/
/proc/split_materials_uniformly(list/custom_materials, multiplier, obj/target_object)
target_object.set_custom_materials(custom_materials)
// if(!length(target_object.contents)) //most common case where the object is just 1 thing
// target_object.set_custom_materials(custom_materials, multiplier)
// return
// //Step 1: Get recursive contents of all objects, only filter obj cause that what's material container accepts
// var/list/reccursive_contents = target_object.get_all_contents_type(/obj/item)
// //Step 2: find the sum of each material type per object and record their amounts into an 2D list
// var/list/material_map_sum = list()
// var/list/material_map_amounts = list()
// for(var/obj/object as anything in reccursive_contents)
// var/list/item_materials = object.matter
// for(var/mat as anything in custom_materials)
// var/mat_amount = 1 //no materials mean we assign this default amount
// if(length(item_materials))
// mat_amount = item_materials[mat] || 1 //if this object doesn't have our material type then assign a default value of 1
// //record the sum of mats for normalizing
// material_map_sum[mat] += mat_amount
// //record the material amount for each item into an 2D list
// var/list/mat_list_per_item = material_map_amounts[mat]
// if(isnull(mat_list_per_item))
// material_map_amounts[mat] = list(mat_amount)
// else
// mat_list_per_item += mat_amount
// //Step 3: normalize & scale material_map_amounts with material_map_sum
// for(var/mat as anything in material_map_amounts)
// var/mat_sum = material_map_sum[mat]
// var/list/mat_per_item = material_map_amounts[mat]
// for(var/i in 1 to mat_per_item.len)
// mat_per_item[i] = (mat_per_item[i] / mat_sum) * custom_materials[mat]
// //Step 4 flatten the 2D list and assign the final values to each atom
// var/index = 1
// for(var/obj/object as anything in reccursive_contents)
// var/list/final_material_list = list()
// for(var/mat as anything in material_map_amounts)
// var/list/mat_per_item = material_map_amounts[mat]
// final_material_list[mat] = mat_per_item[index]
// object.set_custom_materials(final_material_list, multiplier)
// index += 1
+2 -2
View File
@@ -79,7 +79,7 @@
if(A == loc || (A in loc) || (A in contents))
// No adjacency checks
var/resolved = A.attackby(W, src, 1)
var/resolved = W.resolve_attackby(A, src, click_parameters = params)
if(!resolved && A && W)
W.afterattack(A,src,1,params)
return
@@ -91,7 +91,7 @@
if(isturf(A) || isturf(A.loc))
if(A.Adjacent(src) || (W && W.attack_can_reach(src, A, W.reach))) // see adjacent.dm, allows robots to use ranged melee weapons
SEND_SIGNAL(src, COMSIG_ROBOT_ITEM_ATTACK, W, src, params) //This is we ATTEMPTED to attack someone.
var/resolved = A.attackby(W, src, 1)
var/resolved = W.resolve_attackby(A, src, click_parameters = params)
if(!resolved && A && W)
W.afterattack(A, src, 1, params)
return
+358
View File
@@ -0,0 +1,358 @@
SUBSYSTEM_DEF(research)
name = "Research"
// priority = FIRE_PRIORITY_RESEARCH
init_order = INIT_ORDER_RESEARCH
wait = 10
// dependencies = list(
// /datum/controller/subsystem/processing/station,
// )
//TECHWEB STATIC
var/list/techweb_nodes = list() //associative id = node datum
var/list/techweb_designs = list() //associative id = node datum
var/list/list/datum/design_techweb/item_to_design = list() //typepath = list of design datums
///List of all techwebs, generating points or not.
///Autolathes, Mechfabs, and others all have shared techwebs, for example.
var/list/datum/techweb/techwebs = list()
var/datum/techweb_node/error_node/error_node //These two are what you get if a node/design is deleted and somehow still stored in a console.
var/datum/design_techweb/error_design/error_design
//ERROR LOGGING
///associative id = number of times
var/list/invalid_design_ids = list()
///associative id = number of times
var/list/invalid_node_ids = list()
///associative id = error message
var/list/invalid_node_boost = list()
///associative id = TRUE
var/list/techweb_nodes_starting = list()
///category name = list(node.id = TRUE)
var/list/techweb_categories = list()
///List of all items that can unlock a node. (node.id = list(items))
var/list/techweb_unlock_items = list()
///Node ids that should be hidden by default.
var/list/techweb_nodes_hidden = list()
///Node ids that are exclusive to the BEPIS.
var/list/techweb_nodes_experimental = list()
///path = list(point type = value)
var/list/techweb_point_items = list(
// /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_5_POINTS)
)
var/list/errored_datums = list()
///Associated list of all point types that techwebs will have and their respective 'abbreviated' name.
var/list/point_types = list(TECHWEB_POINT_TYPE_GENERIC = "Gen. Res.")
//----------------------------------------------
var/list/single_server_income = list(
TECHWEB_POINT_TYPE_GENERIC = TECHWEB_SINGLE_SERVER_INCOME,
)
//^^^^^^^^ ALL OF THESE ARE PER SECOND! ^^^^^^^^
//Aiming for 1.5 hours to max R&D
//[88nodes * 5000points/node] / [1.5hr * 90min/hr * 60s/min]
//Around 450000 points max???
/// The global list of raw anomaly types that have been refined, for hard limits.
// var/list/created_anomaly_types = list()
/// The hard limits of cores created for each anomaly type. For faster code lookup without switch statements.
// var/list/anomaly_hard_limit_by_type = list(
// /obj/item/assembly/signaler/anomaly/bluespace = MAX_CORES_BLUESPACE,
// /obj/item/assembly/signaler/anomaly/pyro = MAX_CORES_PYRO,
// /obj/item/assembly/signaler/anomaly/grav = MAX_CORES_GRAVITATIONAL,
// /obj/item/assembly/signaler/anomaly/vortex = MAX_CORES_VORTEX,
// /obj/item/assembly/signaler/anomaly/flux = MAX_CORES_FLUX,
// /obj/item/assembly/signaler/anomaly/hallucination = MAX_CORES_HALLUCINATION,
// /obj/item/assembly/signaler/anomaly/bioscrambler = MAX_CORES_BIOSCRAMBLER,
// /obj/item/assembly/signaler/anomaly/dimensional = MAX_CORES_DIMENSIONAL,
// /obj/item/assembly/signaler/anomaly/ectoplasm = MAX_CORES_ECTOPLASMIC,
// )
/// Lookup list for ordnance briefers.
var/list/ordnance_experiments = list()
/// Lookup list for scipaper partners.
var/list/datum/scientific_partner/scientific_partners = list()
/datum/controller/subsystem/research/Initialize()
initialize_all_techweb_designs()
initialize_all_techweb_nodes()
// populate_ordnance_experiments()
new /datum/techweb/science
new /datum/techweb/admin
// new /datum/techweb/oldstation
autosort_categories()
error_design = new
error_node = new
return SS_INIT_SUCCESS
/datum/controller/subsystem/research/fire()
for(var/datum/techweb/techweb_list as anything in techwebs)
if(!techweb_list.should_generate_points)
continue
var/list/bitcoins = list()
for(var/obj/machinery/rnd/server/miner as anything in techweb_list.techweb_servers)
if(miner.working)
bitcoins = single_server_income.Copy()
break //Just need one to work.
if(!isnull(techweb_list.last_income))
var/income_time_difference = world.time - techweb_list.last_income
techweb_list.last_bitcoins = bitcoins // Doesn't take tick drift into account
for(var/i in bitcoins)
bitcoins[i] *= (income_time_difference / 10) * techweb_list.income_modifier
techweb_list.add_point_list(bitcoins)
techweb_list.last_income = world.time
if(length(techweb_list.research_queue_nodes))
techweb_list.research_node_id(techweb_list.research_queue_nodes[1]) // Attempt to research the first node in queue if possible
for(var/node_id in techweb_list.research_queue_nodes)
var/datum/techweb_node/node = SSresearch.techweb_node_by_id(node_id)
if(node.is_free(techweb_list)) // Automatically research all free nodes in queue if any
techweb_list.research_node(node)
/datum/controller/subsystem/research/proc/autosort_categories()
for(var/i in techweb_nodes)
var/datum/techweb_node/I = techweb_nodes[i]
if(techweb_categories[I.category])
techweb_categories[I.category][I.id] = TRUE
else
techweb_categories[I.category] = list(I.id = TRUE)
/datum/controller/subsystem/research/proc/techweb_node_by_id(id)
return techweb_nodes[id] || error_node
/datum/controller/subsystem/research/proc/techweb_design_by_id(id)
return techweb_designs[id] || error_design
/datum/controller/subsystem/research/proc/on_design_deletion(datum/design_techweb/D)
for(var/i in techweb_nodes)
var/datum/techweb_node/TN = techwebs[i]
TN.on_design_deletion(TN)
for(var/i in techwebs)
var/datum/techweb/T = i
T.recalculate_nodes(TRUE)
/datum/controller/subsystem/research/proc/on_node_deletion(datum/techweb_node/TN)
for(var/i in techweb_nodes)
var/datum/techweb_node/TN2 = techwebs[i]
TN2.on_node_deletion(TN)
for(var/i in techwebs)
var/datum/techweb/T = i
T.recalculate_nodes(TRUE)
/datum/controller/subsystem/research/proc/initialize_all_techweb_nodes(clearall = FALSE)
if(islist(techweb_nodes) && clearall)
QDEL_LIST(techweb_nodes)
if(islist(techweb_nodes_starting && clearall))
techweb_nodes_starting.Cut()
var/list/returned = list()
for(var/path in subtypesof(/datum/techweb_node))
var/datum/techweb_node/TN = path
if(isnull(initial(TN.id)))
continue
TN = new path
if(returned[initial(TN.id)])
stack_trace("WARNING: Techweb node ID clash with ID [initial(TN.id)] detected! Path: [path]")
errored_datums[TN] = initial(TN.id)
continue
returned[initial(TN.id)] = TN
if(TN.starting_node)
techweb_nodes_starting[TN.id] = TRUE
for(var/id in techweb_nodes)
var/datum/techweb_node/TN = techweb_nodes[id]
TN.Initialize()
techweb_nodes = returned
if (!verify_techweb_nodes()) //Verify all nodes have ids and such.
stack_trace("Invalid techweb nodes detected")
calculate_techweb_nodes()
calculate_techweb_item_unlocking_requirements()
if (!verify_techweb_nodes()) //Verify nodes and designs have been crosslinked properly.
CRASH("Invalid techweb nodes detected")
/datum/controller/subsystem/research/proc/initialize_all_techweb_designs(clearall = FALSE)
if(islist(techweb_designs) && clearall)
item_to_design = list()
QDEL_LIST(techweb_designs)
var/list/returned = list()
for(var/path in subtypesof(/datum/design_techweb))
var/datum/design_techweb/DN = path
if(isnull(initial(DN.id)))
stack_trace("WARNING: Design with null ID detected. Build path: [initial(DN.build_path)]")
continue
else if(initial(DN.id) == DESIGN_ID_IGNORE)
continue
DN = new path
if(returned[initial(DN.id)])
stack_trace("WARNING: Design ID clash with ID [initial(DN.id)] detected! Path: [path]")
errored_datums[DN] = initial(DN.id)
continue
var/build_path = initial(DN.build_path)
if(!isnull(build_path))
if(!(build_path in item_to_design))
item_to_design[build_path] = list()
item_to_design[build_path] += DN
DN.InitializeMaterials() //Initialize the materials in the design
returned[initial(DN.id)] = DN
techweb_designs = returned
verify_techweb_designs()
/datum/controller/subsystem/research/proc/verify_techweb_nodes()
. = TRUE
for(var/n in techweb_nodes)
var/datum/techweb_node/N = techweb_nodes[n]
if(!istype(N))
WARNING("Invalid research node with ID [n] detected and removed.")
techweb_nodes -= n
research_node_id_error(n)
. = FALSE
for(var/p in N.prereq_ids)
var/datum/techweb_node/P = techweb_nodes[p]
if(!istype(P))
WARNING("Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.")
N.prereq_ids -= p
research_node_id_error(p)
. = FALSE
for(var/d in N.design_ids)
var/datum/design_techweb/D = techweb_designs[d]
if(!istype(D))
WARNING("Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.")
N.design_ids -= d
design_id_error(d)
. = FALSE
for(var/u in N.unlock_ids)
var/datum/techweb_node/U = techweb_nodes[u]
if(!istype(U))
WARNING("Invalid research unlock node with ID [u] detected in node [N.display_name]\[[N.id]\] removed.")
N.unlock_ids -= u
research_node_id_error(u)
. = FALSE
for(var/p in N.required_items_to_unlock)
if(!ispath(p))
N.required_items_to_unlock -= p
WARNING("[p] is not a valid path.")
node_boost_error(N.id, "[p] is not a valid path.")
. = FALSE
var/list/points = N.required_items_to_unlock[p]
if(!isnull(points))
N.required_items_to_unlock -= p
node_boost_error(N.id, "No valid list.")
WARNING("No valid list.")
. = FALSE
CHECK_TICK
/datum/controller/subsystem/research/proc/verify_techweb_designs()
for(var/d in techweb_designs)
var/datum/design_techweb/D = techweb_designs[d]
if(!istype(D))
stack_trace("WARNING: Invalid research design with ID [d] detected and removed.")
techweb_designs -= d
CHECK_TICK
/datum/controller/subsystem/research/proc/research_node_id_error(id)
if(invalid_node_ids[id])
invalid_node_ids[id]++
else
invalid_node_ids[id] = 1
/datum/controller/subsystem/research/proc/design_id_error(id)
if(invalid_design_ids[id])
invalid_design_ids[id]++
else
invalid_design_ids[id] = 1
/datum/controller/subsystem/research/proc/calculate_techweb_nodes()
for(var/design_id in techweb_designs)
var/datum/design_techweb/D = techweb_designs[design_id]
D.unlocked_by.Cut()
for(var/node_id in techweb_nodes)
var/datum/techweb_node/node = techweb_nodes[node_id]
node.unlock_ids = list()
for(var/i in node.design_ids)
var/datum/design_techweb/D = techweb_designs[i]
node.design_ids[i] = TRUE
D.unlocked_by += node.id
if(node.hidden)
techweb_nodes_hidden[node.id] = TRUE
if(node.experimental)
techweb_nodes_experimental[node.id] = TRUE
CHECK_TICK
generate_techweb_unlock_linking()
/datum/controller/subsystem/research/proc/generate_techweb_unlock_linking()
for(var/node_id in techweb_nodes) //Clear all unlock links to avoid duplication.
var/datum/techweb_node/node = techweb_nodes[node_id]
node.unlock_ids = list()
for(var/node_id in techweb_nodes)
var/datum/techweb_node/node = techweb_nodes[node_id]
for(var/prereq_id in node.prereq_ids)
var/datum/techweb_node/prereq_node = techweb_node_by_id(prereq_id)
prereq_node.unlock_ids[node.id] = node
/datum/controller/subsystem/research/proc/calculate_techweb_item_unlocking_requirements()
for(var/node_id in techweb_nodes)
var/datum/techweb_node/node = techweb_nodes[node_id]
for(var/path in node.required_items_to_unlock)
if(!ispath(path))
continue
if(length(techweb_unlock_items[path]))
techweb_unlock_items[path][node.id] = node.required_items_to_unlock[path]
else
techweb_unlock_items[path] = list(node.id = node.required_items_to_unlock[path])
CHECK_TICK
// /datum/controller/subsystem/research/proc/populate_ordnance_experiments()
// for (var/datum/experiment/ordnance/experiment_path as anything in subtypesof(/datum/experiment/ordnance))
// if (initial(experiment_path.experiment_proper))
// ordnance_experiments += new experiment_path()
// for(var/partner_path in subtypesof(/datum/scientific_partner))
// var/datum/scientific_partner/partner = new partner_path
// if(!partner.accepted_experiments.len)
// for (var/datum/experiment/ordnance/ordnance_experiment as anything in ordnance_experiments)
// partner.accepted_experiments += ordnance_experiment.type
// scientific_partners += partner
/**
* Goes through all techwebs and goes through their servers to find ones on a valid z-level
* Returns the full list of all techweb servers.
*/
/datum/controller/subsystem/research/proc/get_available_servers(turf/location)
var/list/local_servers = list()
if(!location)
return local_servers
for (var/datum/techweb/individual_techweb as anything in techwebs)
var/list/servers = find_valid_servers(location, individual_techweb)
if(length(servers))
local_servers += servers
return local_servers
/**
* Goes through an individual techweb's servers and finds one on a valid z-level
* Returns a list of existing ones, or an empty list otherwise.
* Args:
* - checking_web - The techweb we're checking the servers of.
*/
/datum/controller/subsystem/research/proc/find_valid_servers(turf/location, datum/techweb/checking_web)
var/list/valid_servers = list()
for(var/obj/machinery/rnd/server/server as anything in checking_web.techweb_servers)
if(!is_valid_z_level(get_turf(server), location))
continue
valid_servers += server
return valid_servers
// /// Returns true if you can make an anomaly core of the provided type
// /datum/controller/subsystem/research/proc/is_core_available(core_type)
// if (!ispath(core_type, /obj/item/assembly/signaler/anomaly))
// return FALSE // The fuck are you checking this random object for?
// var/already_made = created_anomaly_types[core_type] || 0
// var/hard_limit = anomaly_hard_limit_by_type[core_type]
// return already_made < hard_limit
// /// Increase our tracked number of cores of this type
// /datum/controller/subsystem/research/proc/increment_existing_anomaly_cores(core_type)
// var/existing = created_anomaly_types[core_type] || 0
// created_anomaly_types[core_type] = existing + 1
+13
View File
@@ -42,6 +42,7 @@ SUBSYSTEM_DEF(ticker)
var/obj/screen/cinematic = null
var/round_start_time = 0
var/list/round_start_events
@@ -178,6 +179,10 @@ var/global/datum/controller/subsystem/ticker/ticker
// data_core.manifest()
callHook("roundstart")
for(var/I in round_start_events)
var/datum/callback/cb = I
cb.InvokeAsync()
LAZYCLEARLIST(round_start_events)
spawn(0)//Forking here so we dont have to wait for this to finish
mode.post_setup()
@@ -588,3 +593,11 @@ var/global/datum/controller/subsystem/ticker/ticker
random_players = SSticker.random_players
round_start_time = SSticker.round_start_time
//These callbacks will fire after roundstart key transfer
/datum/controller/subsystem/ticker/proc/OnRoundstart(datum/callback/cb)
if(!HasRoundStarted())
LAZYADD(round_start_events, cb)
else
cb.InvokeAsync()
@@ -1,491 +0,0 @@
/*!
This datum should be used for handling mineral contents of machines and whatever else is supposed to hold minerals and make use of them.
Variables:
amount - raw amount of the mineral this container is holding, calculated by the defined value SHEET_MATERIAL_AMOUNT=2000.
max_amount - max raw amount of mineral this container can hold.
stack_type - type of the mineral sheet the container handles, used for output.
parent - object that this container is being used by, used for output.
MAX_STACK_SIZE - size of a stack of mineral sheets. Constant.
*/
/datum/component/material_container
/// The total amount of materials this material container contains
var/total_amount = 0
/// The maximum amount of materials this material container can contain
var/max_amount
/// Map of material ref -> amount
var/list/materials //Map of key = material ref | Value = amount
/// The list of materials that this material container can accept
var/list/allowed_materials
/// The typecache of things that this material container can accept
var/list/allowed_item_typecache
/// The last main material that was inserted into this container
var/last_inserted_id
/// A callback for checking wheter we can insert a material into this container
var/datum/callback/insertion_check
/// A callback invoked before materials are inserted into this container
var/datum/callback/precondition
/// A callback invoked after materials are inserted into this container
var/datum/callback/after_insert
/// The material container flags. See __DEFINES/materials.dm.
var/mat_container_flags
/// Sets up the proper signals and fills the list of materials with the appropriate references.
/datum/component/material_container/Initialize(list/init_mats, max_amt = 0, _mat_container_flags=NONE, list/allowed_mats=init_mats, list/allowed_items, datum/callback/_insertion_check, datum/callback/_precondition, datum/callback/_after_insert)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
materials = list()
max_amount = max(0, max_amt)
mat_container_flags = _mat_container_flags
allowed_materials = allowed_mats || list()
if(allowed_items)
if(ispath(allowed_items) && allowed_items == /obj/item/stack)
allowed_item_typecache = GLOB.typecache_stack
else
allowed_item_typecache = typecacheof(allowed_items)
insertion_check = _insertion_check
precondition = _precondition
after_insert = _after_insert
for(var/mat in init_mats) //Make the assoc list material reference -> amount
var/mat_ref = GET_MATERIAL_REF(mat)
if(isnull(mat_ref))
continue
var/mat_amt = init_mats[mat]
if(isnull(mat_amt))
mat_amt = 0
materials[mat_ref] += mat_amt
/datum/component/material_container/Destroy(force)
materials = null
allowed_materials = null
if(insertion_check)
QDEL_NULL(insertion_check)
if(precondition)
QDEL_NULL(precondition)
if(after_insert)
QDEL_NULL(after_insert)
return ..()
/datum/component/material_container/RegisterWithParent()
. = ..()
if(!(mat_container_flags & MATCONTAINER_NO_INSERT))
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(on_attackby))
if(mat_container_flags & MATCONTAINER_EXAMINE)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
/datum/component/material_container/vv_edit_var(var_name, var_value)
var/old_flags = mat_container_flags
. = ..()
if(var_name == NAMEOF(src, mat_container_flags) && parent)
if(!(old_flags & MATCONTAINER_EXAMINE) && mat_container_flags & MATCONTAINER_EXAMINE)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
else if(old_flags & MATCONTAINER_EXAMINE && !(mat_container_flags & MATCONTAINER_EXAMINE))
UnregisterSignal(parent, COMSIG_PARENT_EXAMINE)
if(old_flags & MATCONTAINER_NO_INSERT && !(mat_container_flags & MATCONTAINER_NO_INSERT))
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(on_attackby))
else if(!(old_flags & MATCONTAINER_NO_INSERT) && mat_container_flags & MATCONTAINER_NO_INSERT)
UnregisterSignal(parent, COMSIG_PARENT_ATTACKBY)
/datum/component/material_container/proc/on_examine(datum/source, mob/user, list/examine_texts)
SIGNAL_HANDLER
for(var/datum/material/M as anything in materials)
var/amt = materials[M]
if(amt)
examine_texts += span_notice("It has [amt] units of [lowertext(M.name)] stored.")
/// Proc that allows players to fill the parent with mats
/datum/component/material_container/proc/on_attackby(datum/source, obj/item/I, mob/living/user)
SIGNAL_HANDLER
var/list/tc = allowed_item_typecache
if(!(mat_container_flags & MATCONTAINER_ANY_INTENT) && user.a_intent != I_HELP)
return
if(tc && !is_type_in_typecache(I, tc))
if(!(mat_container_flags & MATCONTAINER_SILENT))
to_chat(user, span_warning("[parent] won't accept [I]!"))
return
. = COMPONENT_CANCEL_ATTACK_CHAIN
var/datum/callback/pc = precondition
if(pc && !pc.Invoke(user))
return
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
user_insert_stack(S, user, mat_container_flags)
return
var/material_amount = get_item_material_amount(I, mat_container_flags)
if(!material_amount)
to_chat(user, span_warning("[I] does not contain sufficient materials to be accepted by [parent]."))
return
if(!has_space(material_amount))
to_chat(user, span_warning("[parent] is full. Please remove materials from [parent] in order to insert more."))
return
user_insert(I, user, mat_container_flags)
/// Proc used for when player inserts a stack
/datum/component/material_container/proc/user_insert_stack(obj/item/stack/S, mob/living/user, breakdown_flags = mat_container_flags)
var/sheets = S.get_amount()
if(sheets < 1)
to_chat(user, span_warning("[S] does not contain sufficient materials to be accepted by [parent]."))
return
// Cache this since S may go away after use()
var/list/sheet_matter = S.matter
// Calculate total amount of material for one sheet
var/matter_per_sheet = 0
for(var/material in sheet_matter)
matter_per_sheet += sheet_matter[material]
// If any part of a sheet can't go in us, the whole sheet is invalid
if(!can_hold_material(GET_MATERIAL_REF(material)))
to_chat(user, span_warning("[parent] cannot contain [material]."))
return
// Our sheet had no material. Whoops.
if(!matter_per_sheet)
to_chat(user, span_warning("[S] does not contain any matter acceptable by [parent]."))
return
// If we can't fit the material for one sheet, we're full.
if(!has_space(matter_per_sheet))
to_chat(user, span_warning("[parent] is full. Please remove materials from [parent] in order to insert more."))
return
// Calculate the maximum amount of sheets we could possibly accept.
var/max_sheets = round((max_amount - total_amount) / matter_per_sheet)
if(max_sheets <= 0)
to_chat(user, span_warning("[parent] is full. Please remove materials from [parent] in order to insert more."))
return
// Calculate the amount of sheets we're actually going to use.
var/sheets_to_use = min(sheets, max_sheets)
// It shouldn't be possible to add more matter than our max
ASSERT((total_amount + (matter_per_sheet * sheets_to_use)) <= max_amount)
// Use the amount of sheets from the stack
if(!S.use(sheets_to_use))
to_chat(user, span_warning("Something went wrong with your stack. Split it manually and try again."))
return
// We're going to blindly insert all of the materials, our assertion above says it shouldn't be possible to overflow
var/inserted = 0
for(var/matter in sheet_matter)
var/datum/material/MAT = GET_MATERIAL_REF(matter)
inserted += insert_amount_mat(sheet_matter[matter] * sheets_to_use, MAT)
last_inserted_id = matter
// Tell the user and wrap up.
to_chat(user, span_notice("You insert a material total of [inserted] into [parent]."))
if(after_insert)
after_insert.Invoke(S, last_inserted_id, inserted)
/// Proc used for when player inserts materials
/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user, breakdown_flags = mat_container_flags)
set waitfor = FALSE
var/active_held = user.get_active_hand() // differs from I when using TK
if(!user.unEquip(I))
to_chat(user, span_warning("[I] is stuck to you and cannot be placed into [parent]."))
return
var/inserted = insert_item(I, breakdown_flags = mat_container_flags)
if(inserted)
to_chat(user, span_notice("You insert a material total of [inserted] into [parent]."))
qdel(I)
if(after_insert)
after_insert.Invoke(I, last_inserted_id, inserted)
else if(I == active_held)
user.put_in_active_hand(I)
/// Proc specifically for inserting items, returns the amount of materials entered.
/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1, breakdown_flags = mat_container_flags)
if(QDELETED(I))
return FALSE
multiplier = CEILING(multiplier, 0.01)
var/material_amount = get_item_material_amount(I, breakdown_flags)
if(!material_amount || !has_space(material_amount))
return FALSE
last_inserted_id = insert_item_materials(I, multiplier, breakdown_flags)
return material_amount
/**
* Inserts the relevant materials from an item into this material container.
*
* Arguments:
* - [source][/obj/item]: The source of the materials we are inserting.
* - multiplier: The multiplier for the materials being inserted.
* - breakdown_flags: The breakdown bitflags that will be used to retrieve the materials from the source
*/
/datum/component/material_container/proc/insert_item_materials(obj/item/source, multiplier = 1, breakdown_flags = mat_container_flags)
var/primary_mat
var/max_mat_value = 0
var/list/item_materials = source.get_material_composition(breakdown_flags)
for(var/MAT in item_materials)
if(!can_hold_material(MAT))
continue
materials[MAT] += item_materials[MAT] * multiplier
total_amount += item_materials[MAT] * multiplier
if(item_materials[MAT] > max_mat_value)
max_mat_value = item_materials[MAT]
primary_mat = MAT
return primary_mat
/**
* The default check for whether we can add materials to this material container.
*
* Arguments:
* - [mat][/atom/material]: The material we are checking for insertability.
*/
/datum/component/material_container/proc/can_hold_material(datum/material/mat)
if(mat in allowed_materials)
return TRUE
if(istype(mat) && ((mat.name in allowed_materials) || (mat.type in allowed_materials)))
allowed_materials += mat // This could get messy with passing lists by ref... but if you're doing that the list expansion is probably being taken care of elsewhere anyway...
return TRUE
if(insertion_check?.Invoke(mat))
allowed_materials += mat
return TRUE
return FALSE
/// For inserting an amount of material
/datum/component/material_container/proc/insert_amount_mat(amt, datum/material/mat)
if(amt <= 0 || !has_space(amt))
return 0
var/total_amount_saved = total_amount
if(mat)
if(!istype(mat))
mat = GET_MATERIAL_REF(mat)
materials[mat] += amt
total_amount += amt
else
var/num_materials = length(materials)
if(!num_materials)
return 0
amt /= num_materials
for(var/i in materials)
materials[i] += amt
total_amount += amt
return (total_amount - total_amount_saved)
/// Uses an amount of a specific material, effectively removing it.
/datum/component/material_container/proc/use_amount_mat(amt, datum/material/mat)
if(!istype(mat))
mat = GET_MATERIAL_REF(mat)
if(!mat)
return 0
var/amount = materials[mat]
if(amount < amt)
return 0
materials[mat] -= amt
total_amount -= amt
return amt
/// Proc for transfering materials to another container.
/datum/component/material_container/proc/transer_amt_to(datum/component/material_container/T, amt, datum/material/mat)
if(!istype(mat))
mat = GET_MATERIAL_REF(mat)
if((amt==0)||(!T)||(!mat))
return FALSE
if(amt<0)
return T.transer_amt_to(src, -amt, mat)
var/tr = min(amt, materials[mat], T.can_insert_amount_mat(amt, mat))
if(tr)
use_amount_mat(tr, mat)
T.insert_amount_mat(tr, mat)
return tr
return FALSE
/// Proc for checking if there is room in the component, returning the amount or else the amount lacking.
/datum/component/material_container/proc/can_insert_amount_mat(amt, datum/material/mat)
if(!amt || !mat)
return 0
if((total_amount + amt) <= max_amount)
return amt
else
return (max_amount - total_amount)
/// For consuming a dictionary of materials. mats is the map of materials to use and the corresponding amounts, example: list(M/datum/material/glass =100, datum/material/iron=200)
/datum/component/material_container/proc/use_materials(list/mats, multiplier=1)
if(!mats || !length(mats))
return FALSE
var/list/mats_to_remove = list() //Assoc list MAT | AMOUNT
for(var/datum/material/req_mat as anything in mats) //Loop through all required materials
var/imat = req_mat
if(!istype(req_mat))
req_mat = GET_MATERIAL_REF(req_mat) //Get the ref if necesary
if(!materials[req_mat]) //Do we have the resource?
return FALSE //Can't afford it
var/amount_required = mats[imat] * multiplier
if(!(materials[req_mat] >= amount_required)) // do we have enough of the resource?
return FALSE //Can't afford it
mats_to_remove[req_mat] += amount_required //Add it to the assoc list of things to remove
continue
var/total_amount_save = total_amount
for(var/i in mats_to_remove)
total_amount_save -= use_amount_mat(mats_to_remove[i], i)
return total_amount_save - total_amount
/// For spawning mineral sheets at a specific location. Used by machines to output sheets.
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, datum/material/M, atom/target = null)
if(!M.stack_type)
return 0 //Add greyscale sheet handling here later
if(sheet_amt <= 0)
return 0
if(!target)
var/atom/parent_atom = parent
target = parent_atom.drop_location()
if(materials[M] < (sheet_amt * SHEET_MATERIAL_AMOUNT))
sheet_amt = round(materials[M] / SHEET_MATERIAL_AMOUNT)
var/obj/item/stack/S = M.stack_type
var/max_stack_size = initial(S.max_amount)
var/count = 0
while(sheet_amt > max_stack_size)
new M.stack_type(target, max_stack_size, null, list((M) = SHEET_MATERIAL_AMOUNT))
count += max_stack_size
use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, M)
sheet_amt -= max_stack_size
if(sheet_amt >= 1)
new M.stack_type(target, sheet_amt, null, list((M) = SHEET_MATERIAL_AMOUNT))
count += sheet_amt
use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, M)
return count
/// Proc to get all the materials and dump them as sheets
/datum/component/material_container/proc/retrieve_all(target = null)
var/result = 0
for(var/MAT in materials)
var/amount = materials[MAT]
result += retrieve_sheets(amount2sheet(amount), MAT, target)
return result
/// Proc that returns TRUE if the container has space
/datum/component/material_container/proc/has_space(amt = 0)
return (total_amount + amt) <= max_amount
/// Checks if its possible to afford a certain amount of materials. Takes a dictionary of materials.
/datum/component/material_container/proc/has_materials(list/mats, multiplier=1)
if(!mats || !mats.len)
return FALSE
for(var/datum/material/req_mat as anything in mats) //Loop through all required materials
var/imat = req_mat
if(!istype(req_mat))
if(ispath(req_mat) || istext(req_mat)) //Is this an actual material, or is it a category?
req_mat = GET_MATERIAL_REF(req_mat) //Get the ref
// else // Its a category. (For example MAT_CATEGORY_RIGID)
// if(!has_enough_of_category(req_mat, mats[x], multiplier)) //Do we have enough of this category?
// return FALSE
// else
// continue
if(!has_enough_of_material(req_mat, mats[imat], multiplier))//Not a category, so just check the normal way
return FALSE
return TRUE
/// Returns all the categories in a recipe.
/datum/component/material_container/proc/get_categories(list/mats)
var/list/categories = list()
for(var/x in mats) //Loop through all required materials
if(!istext(x)) //This means its not a category
continue
categories += x
return categories
/// Returns TRUE if you have enough of the specified material.
/datum/component/material_container/proc/has_enough_of_material(datum/material/req_mat, amount, multiplier=1)
if(!materials[req_mat]) //Do we have the resource?
return FALSE //Can't afford it
var/amount_required = amount * multiplier
if(materials[req_mat] >= amount_required) // do we have enough of the resource?
return TRUE
return FALSE //Can't afford it
/// Returns TRUE if you have enough of a specified material category (Which could be multiple materials)
// /datum/component/material_container/proc/has_enough_of_category(category, amount, multiplier=1)
// for(var/i in SSmaterials.materials_by_category[category])
// var/datum/material/mat = i
// if(materials[mat] >= amount) //we have enough
// return TRUE
// return FALSE
/// Turns a material amount into the amount of sheets it should output
/datum/component/material_container/proc/amount2sheet(amt)
if(amt >= SHEET_MATERIAL_AMOUNT)
return round(amt / SHEET_MATERIAL_AMOUNT)
return FALSE
/// Turns an amount of sheets into the amount of material amount it should output
/datum/component/material_container/proc/sheet2amount(sheet_amt)
if(sheet_amt > 0)
return sheet_amt * SHEET_MATERIAL_AMOUNT
return FALSE
///returns the amount of material relevant to this container; if this container does not support glass, any glass in 'I' will not be taken into account
/datum/component/material_container/proc/get_item_material_amount(obj/item/I, breakdown_flags = mat_container_flags)
if(!istype(I) || !I.matter)
return 0
var/material_amount = 0
var/list/item_materials = I.get_material_composition(breakdown_flags)
for(var/MAT in item_materials)
if(!can_hold_material(MAT))
continue
material_amount += item_materials[MAT]
return material_amount
/// Returns the amount of a specific material in this container.
/datum/component/material_container/proc/get_material_amount(datum/material/mat)
if(!istype(mat))
mat = GET_MATERIAL_REF(mat)
return materials[mat]
/// List format is list(list(name = ..., amount = ..., ref = ..., etc.), list(...))
/datum/component/material_container/tgui_data(mob/user, skip_empty = FALSE)
var/list/data = list()
for(var/datum/material/material as anything in materials)
var/amount = materials[material]
if(amount == 0 && skip_empty)
continue
data += list(list(
"name" = material.name,
"ref" = REF(material),
"amount" = amount,
"sheets" = round(amount / SHEET_MATERIAL_AMOUNT),
"removable" = amount >= SHEET_MATERIAL_AMOUNT,
))
return data
@@ -0,0 +1,745 @@
/*!
This datum should be used for handling mineral contents of machines and whatever else is supposed to hold minerals and make use of them.
Variables:
amount - raw amount of the mineral this container is holding, calculated by the defined value SHEET_MATERIAL_AMOUNT=SHEET_MATERIAL_AMOUNT.
max_amount - max raw amount of mineral this container can hold.
sheet_type - type of the mineral sheet the container handles, used for output.
parent - object that this container is being used by, used for output.
MAX_STACK_SIZE - size of a stack of mineral sheets. Constant.
*/
//The full item was consumed
#define MATERIAL_INSERT_ITEM_SUCCESS 1
/datum/component/material_container
/// The maximum amount of materials this material container can contain
var/max_amount
/// Map of material ref -> amount
var/list/materials //Map of key = material ref | Value = amount
/// The list of materials that this material container can accept
var/list/allowed_materials
/// The typecache of things that this material container can accept
var/list/allowed_item_typecache
/// The last main material that was inserted into this container
var/last_inserted_id
/// Whether or not this material container allows specific amounts from sheets to be inserted
var/precise_insertion = FALSE
/// The material container flags. See __DEFINES/construction/materials.dm.
var/mat_container_flags
/// Signals that are registered with this contained
var/list/registered_signals
/// Sets up the proper signals and fills the list of materials with the appropriate references.
/datum/component/material_container/Initialize(
list/init_mats,
max_amt = 0,
_mat_container_flags = NONE,
list/allowed_mats = init_mats,
list/allowed_items,
list/container_signals
)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
materials = list()
max_amount = max(0, max_amt)
mat_container_flags = _mat_container_flags
allowed_materials = allowed_mats || list()
if(allowed_items)
if(ispath(allowed_items) && allowed_items == /obj/item/stack)
allowed_item_typecache = GLOB.typecache_stack
else
allowed_item_typecache = typecacheof(allowed_items)
for(var/mat in init_mats) //Make the assoc list material reference -> amount
var/mat_ref = GET_MATERIAL_REF(mat)
if(isnull(mat_ref))
continue
var/mat_amt = init_mats[mat]
if(isnull(mat_amt))
mat_amt = 0
materials[mat_ref] += mat_amt
if(length(container_signals))
for(var/signal in container_signals)
parent.RegisterSignal(src, signal, container_signals[signal])
/datum/component/material_container/Destroy(force)
materials = null
allowed_materials = null
return ..()
/datum/component/material_container/RegisterWithParent()
. = ..()
// can we insert into this container
if(!(mat_container_flags & MATCONTAINER_NO_INSERT))
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(on_attackby))
//to see available materials
if(mat_container_flags & MATCONTAINER_EXAMINE)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
//drop sheets when object is deconstructed but not deleted
RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, PROC_REF(drop_sheets))
/datum/component/material_container/UnregisterFromParent()
var/list/signals = list()
if(!(mat_container_flags & MATCONTAINER_NO_INSERT))
signals += COMSIG_PARENT_ATTACKBY
if(mat_container_flags & MATCONTAINER_EXAMINE)
signals += COMSIG_PARENT_EXAMINE
signals += COMSIG_OBJ_DECONSTRUCT
UnregisterSignal(parent, signals)
/datum/component/material_container/proc/drop_sheets()
SIGNAL_HANDLER
retrieve_all()
/datum/component/material_container/proc/on_examine(datum/source, mob/user, list/examine_texts)
SIGNAL_HANDLER
for(var/datum/material/M as anything in materials)
var/amt = materials[M]
if(amt)
examine_texts += span_notice("It has [amt] units of [lowertext(M.name)] stored.")
/datum/component/material_container/vv_edit_var(var_name, var_value)
var/old_flags = mat_container_flags
. = ..()
if(var_name == NAMEOF(src, mat_container_flags) && parent)
if(!(old_flags & MATCONTAINER_EXAMINE) && mat_container_flags & MATCONTAINER_EXAMINE)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
else if(old_flags & MATCONTAINER_EXAMINE && !(mat_container_flags & MATCONTAINER_EXAMINE))
UnregisterSignal(parent, COMSIG_PARENT_EXAMINE)
if(old_flags & MATCONTAINER_NO_INSERT && !(mat_container_flags & MATCONTAINER_NO_INSERT))
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(on_attackby))
else if(!(old_flags & MATCONTAINER_NO_INSERT) && mat_container_flags & MATCONTAINER_NO_INSERT)
UnregisterSignal(parent, COMSIG_PARENT_ATTACKBY)
/**
* 3 Types of Procs
* Material Insertion : Insert materials into the container
* Material Validation : Checks how much materials are available, Extracts materials from items if the container can hold them
* Material Removal : Removes material from the container
*
* Each Proc further belongs to a specific category
* LOW LEVEL: Procs that are used internally & should not be used anywhere else unless you know what your doing
* MID LEVEL: Procs that can be used by machines(like recycler, stacking machines) to bypass majority of checks
* HIGH LEVEL: Procs that can be used by anyone publicly and guarantees safety checks & limits
*/
//================================Material Insertion procs==============================
//======================================LOW LEVEL=========================================
/**
* Inserts the relevant materials from an item into this material container.
* This low level proc should not be used directly by anyone
*
* Arguments:
* - [source][/obj/item]: The source of the materials we are inserting.
* - multiplier: The multiplier for the materials extract from this item being inserted.
* - context: the atom performing the operation, this is the last argument sent in COMSIG_MATCONTAINER_ITEM_CONSUMED
* and is used mostly for silo logging, the silo resends this signal on the context to give it a
* chance to process the item
*/
/datum/component/material_container/proc/insert_item_materials(obj/item/source, multiplier = 1, atom/context = parent)
var/primary_mat
var/max_mat_value = 0
var/material_amount = 0
var/list/item_materials = source.get_material_composition(mat_container_flags)
var/list/mats_consumed = list()
for(var/MAT in item_materials)
if(!can_hold_material(MAT))
continue
var/mat_amount = OPTIMAL_COST(item_materials[MAT] * multiplier)
materials[MAT] += mat_amount
if(item_materials[MAT] > max_mat_value)
max_mat_value = item_materials[MAT]
primary_mat = MAT
mats_consumed[MAT] = mat_amount
material_amount += mat_amount
if(length(mats_consumed))
SEND_SIGNAL(src, COMSIG_MATCONTAINER_ITEM_CONSUMED, source, primary_mat, mats_consumed, material_amount, context)
return primary_mat
//===================================================================================
//===============================MID LEVEL===================================================
/**
* For inserting an amount of material. Use this to add materials to the container directly
*
* Arguments:
* - amt: amount of said material to insert
* - mat: the material type to insert
*/
/datum/component/material_container/proc/insert_amount_mat(amt, datum/material/mat)
if(amt <= 0)
return 0
amt = OPTIMAL_COST(amt)
if(!has_space(amt))
return 0
var/total_amount_saved = total_amount()
if(mat)
if(!istype(mat))
mat = GET_MATERIAL_REF(mat)
materials[mat] += amt
else
var/num_materials = length(materials)
if(!num_materials)
return 0
amt /= num_materials
for(var/i in materials)
materials[i] += amt
return (total_amount() - total_amount_saved)
/**
* Proc specifically for inserting items, use this when you want to insert any item into the container
* this bypasses most of the material flag checks so much be used by machines like recycler, stacking machine etc that
* does not care for such checks
*
* Arguments:
* - [weapon][obj/item]: the item you are trying to insert
* - multiplier: The multiplier for the materials being inserted
* - context: the atom performing the operation, this is the last argument sent in COMSIG_MATCONTAINER_ITEM_CONSUMED and is used mostly for silo logging
* * - delete_item: should we delete the item after its materials are consumed. does not apply to stacks if they were split due to lack of space
*/
/datum/component/material_container/proc/insert_item(obj/item/weapon, multiplier = 1, atom/context = parent, delete_item = TRUE)
if(QDELETED(weapon))
return MATERIAL_INSERT_ITEM_NO_MATS
multiplier = CEILING(multiplier, 0.01)
var/obj/item/target = weapon
var/material_amount = OPTIMAL_COST(get_item_material_amount(target, mat_container_flags) * multiplier)
if(!material_amount)
return MATERIAL_INSERT_ITEM_NO_MATS
var/obj/item/stack/item_stack
if(istype(target, /obj/item/stack) && !has_space(material_amount)) //not enough space split and feed as many sheets possible
item_stack = weapon
var/space_left = max_amount - total_amount()
if(!space_left)
return MATERIAL_INSERT_ITEM_NO_SPACE
var/material_per_sheet = material_amount / item_stack.amount
var/sheets_to_insert = round(space_left / material_per_sheet)
if(!sheets_to_insert)
return MATERIAL_INSERT_ITEM_NO_SPACE
target = fast_split_stack(item_stack, sheets_to_insert)
material_amount = get_item_material_amount(target, mat_container_flags) * multiplier
material_amount = OPTIMAL_COST(material_amount)
last_inserted_id = insert_item_materials(target, multiplier, context)
if(!isnull(last_inserted_id))
if(delete_item || target != weapon) //we could have split the stack ourselves
qdel(target) //item gone
return material_amount
else if(!isnull(item_stack) && item_stack != target) //insertion failed, merge the split stack back into the original
var/obj/item/stack/inserting_stack = target
item_stack.add(inserting_stack.amount)
qdel(inserting_stack)
return MATERIAL_INSERT_ITEM_FAILURE
//============================================================================================
//===================================HIGH LEVEL===================================================
/**
* inserts an item from the players hand into the container. Loops through all the contents inside recursively
* Does all explicit checking for mat flags & callbacks to check if insertion is valid
* This proc is what you should be using for almost all cases
*
* Arguments:
* * held_item - the item to insert
* * user - the mob inserting this item
* * context - the atom performing the operation, this is the last argument sent in COMSIG_MATCONTAINER_ITEM_CONSUMED and is used mostly for silo logging
*/
/datum/component/material_container/proc/user_insert(obj/item/held_item, mob/living/user, atom/context = parent)
set waitfor = FALSE
. = 0
//All items that do not have any contents
var/list/obj/item/items = list(held_item)
//is this the first item we are ever processing
var/first_checks = TRUE
//list of items to delete
var/list/obj/item/to_delete = list()
//The status of the last insert attempt
var/inserted = 0
//All messages to be displayed to chat
var/list/chat_msgs = list()
//differs from held_item when using TK
var/obj/item/active_held = user.get_active_hand()
while(items.len)
//no point inserting more items
if(inserted == MATERIAL_INSERT_ITEM_NO_SPACE)
break
//Pop the 1st item out from the list
var/obj/item/target_item = items[1]
items -= target_item
//e.g. projectiles inside bullets are not objects
if(!istype(target_item))
continue
//can't allow abstract items
if(target_item.abstract)
continue
// user defined conditions
if(SEND_SIGNAL(src, COMSIG_MATCONTAINER_PRE_USER_INSERT, target_item, user) & MATCONTAINER_BLOCK_INSERT)
continue
//item is either indestructible, not allowed for redemption or not in the allowed types
if(allowed_item_typecache && !is_type_in_typecache(target_item, allowed_item_typecache))
if(!(mat_container_flags & MATCONTAINER_SILENT))
var/list/status_data = chat_msgs["[MATERIAL_INSERT_ITEM_FAILURE]"] || list()
var/list/item_data = status_data[target_item.name] || list()
item_data["count"] += 1
status_data[target_item.name] = item_data
chat_msgs["[MATERIAL_INSERT_ITEM_FAILURE]"] = status_data
//storage items usually come here
//this is so players can insert items from their bags into machines for convinience
if(!target_item.contents.len)
continue
//at this point we can check if we have enough for all items & other stuff
if(first_checks)
//anything that isn't a stack cannot be split so find out if we have enough space, we don't want to consume half the contents of an object & leave it in a broken state
//for duffle bags and other storage items we can check for space 1 item at a time
if(!istype(target_item, /obj/item/stack))
var/total_amount = 0
for(var/obj/item/weapon as anything in target_item.get_all_contents_type(/obj/item))
total_amount += get_item_material_amount(weapon)
if(!has_space(total_amount))
if(!(mat_container_flags & MATCONTAINER_SILENT))
to_chat(user, span_warning("[parent] does not have enough space for [target_item]!"))
return
first_checks = FALSE
//if stack, check if we want to read precise amount of sheets to insert
var/obj/item/stack/item_stack = null
if(istype(target_item, /obj/item/stack) && precise_insertion)
var/atom/current_parent = parent
item_stack = target_item
var/requested_amount = tgui_input_number(user, "How much do you want to insert?", "Inserting [item_stack.singular_name]s", item_stack.amount, item_stack.amount)
if(!requested_amount || QDELETED(target_item) || QDELETED(user) || QDELETED(src))
continue
if(parent != current_parent || user.get_active_hand() != active_held)
continue
if(requested_amount != item_stack.amount) //only split if its not the whole amount
target_item = fast_split_stack(item_stack, requested_amount) //split off the requested amount
requested_amount = 0
//is this item a stack and was it split by the player?
var/was_stack_split = !isnull(item_stack) && item_stack != target_item
//if it was split then item_stack has the reference to the original stack/item
var/obj/item/original_item = was_stack_split ? item_stack : target_item
//if this item is not the one the player is holding then don't remove it from their hand
if(original_item != active_held)
original_item = null
if(!isnull(original_item) && !user.temporarilyRemoveItemFromInventory(original_item)) //remove from hand(if split remove the original stack else the target)
return
//insert the item
var/item_name = target_item.name
var/item_count = 1
var/is_stack = FALSE
var/obj/item/stack/the_stack
if(istype(target_item, /obj/item/stack))
the_stack = target_item
item_name = the_stack.singular_name
item_count = the_stack.amount
is_stack = TRUE
//we typically don't want to consume bags, boxes but only their contents. so we skip processing
inserted = !istype(target_item, /obj/item/storage) ? insert_item(target_item, 1, context, is_stack) : 0
if(inserted > 0)
. += inserted
inserted /= SHEET_MATERIAL_AMOUNT // display units inserted as sheets for improved readability
//collect all messages to print later
var/list/status_data = chat_msgs["[MATERIAL_INSERT_ITEM_SUCCESS]"] || list()
var/list/item_data = status_data[item_name] || list()
item_data["count"] += item_count
item_data["amount"] += inserted
item_data["stack"] = is_stack
status_data[item_name] = item_data
chat_msgs["[MATERIAL_INSERT_ITEM_SUCCESS]"] = status_data
//delete the item or merge stacks if any left over
if(is_stack)
//player split it & machine further split that due to lack of space? merge with remaining stack
if(!QDELETED(target_item) && was_stack_split)
var/obj/item/stack/inserting_stack = target_item
item_stack.add(inserting_stack.amount)
qdel(inserting_stack)
//was this the original item in the players hand? put what's left back in the player's hand
if(!QDELETED(original_item))
user.put_in_active_hand(original_item)
//skip processing children & other stuff. irrelevant for stacks
continue
//queue the object for deletion
to_delete += target_item
else
//collect all messages to print later
var/list/status_data = chat_msgs["[inserted]"] || list()
var/list/item_data = status_data[item_name] || list()
item_data["count"] += item_count
status_data[item_name] = item_data
chat_msgs["[inserted]"] = status_data
//player split the stack by the requested amount but even that split amount could not be salvaged. merge it back with the original
if(was_stack_split)
var/obj/item/stack/inserting_stack = target_item
item_stack.add(inserting_stack.amount)
qdel(inserting_stack)
//was this the original item in the players hand? put it back because we coudn't salvage it
if(!QDELETED(original_item))
user.put_in_active_hand(original_item)
//we can stop here as remaining items will fail to insert as well
if(inserted == MATERIAL_INSERT_ITEM_NO_SPACE)
break
//we failed to process the item so don't bother going into its contents
//but if we are dealing with storage items like bags, boxes etc then we make a exception
if(!istype(target_item, /obj/item/storage))
continue
//If any mats were consumed we can proceed to delete the parent
//If it has children then we will process them first in the 2nd round
//This is done so we don't delete the children when the parent is consumed
//We only do this on the 1st iteration so we don't re-iterate through its children again
if(target_item.contents.len)
//process children
items += target_item.contents
//we now summarize the chat msgs collected
if(!(mat_container_flags & MATCONTAINER_SILENT))
for(var/status as anything in chat_msgs)
var/list/status_data = chat_msgs[status]
for(var/item_name as anything in status_data)
//read the params
var/list/chat_data = status_data[item_name]
var/count = chat_data["count"]
var/amount = chat_data["amount"]
//decode the message
switch(text2num(status))
if(MATERIAL_INSERT_ITEM_SUCCESS) //no problems full item was consumed
if(chat_data["stack"])
var/sheets = min(count, amount) //minimum between sheets inserted vs sheets consumed(values differ for alloys)
to_chat(user, span_notice("[sheets > 1 ? "[sheets] " : ""][item_name][sheets > 1 ? "s were" : " was"] added to [parent]."))
else
to_chat(user, span_notice("[count > 1 ? "[count] " : ""][item_name][count > 1 ? "s" : ""], worth [amount] sheets, [count > 1 ? "were" : "was"] added to [parent]."))
if(MATERIAL_INSERT_ITEM_NO_SPACE) //no space
to_chat(user, span_warning("[parent] has no space to accept [item_name]!"))
if(MATERIAL_INSERT_ITEM_NO_MATS) //no materials inside these items
to_chat(user, span_warning("[item_name][count > 1 ? "s have" : " has"] no materials that can be accepted by [parent]!"))
if(MATERIAL_INSERT_ITEM_FAILURE) //could be because the material type was not accepted or other stuff
to_chat(user, span_warning("[item_name][count > 1 ? "s were" : " was"] rejected by [parent]!"))
//finally delete the items
for(var/obj/item/deleting as anything in to_delete)
if(!QDELETED(deleting)) //deleting parents also delete their children so we check
qdel(deleting)
/datum/component/material_container/proc/on_attackby(datum/source, obj/item/I, mob/living/user)
SIGNAL_HANDLER
return attempt_insert(user, I)
/// Proc that allows players to fill the parent with mats
/datum/component/material_container/proc/attempt_insert(mob/living/user, obj/item/weapon)
if(istype(parent, /obj/machinery))
var/obj/machinery/machine = parent
if(machine.stat || machine.panel_open)
return
user_insert(weapon, user)
return TRUE
//===============================================================================================
//======================================Material Validation=======================================
//=========================================LOW LEVEL===================================
/**
* Proc that returns TRUE if the container has space
*
* Arguments:
* * amt - can this container hold this much amount of materials
*/
/datum/component/material_container/proc/has_space(amt = 0)
return (total_amount() + amt) <= max_amount
/**
* The default check for whether we can add materials to this material container.
*
* Arguments:
* - [mat][/atom/material]: The material we are checking for insertability.
*/
/datum/component/material_container/proc/can_hold_material(datum/material/mat)
if(mat in allowed_materials)
return TRUE
if(istype(mat) && ((mat.name in allowed_materials) || (mat.type in allowed_materials)))
allowed_materials += mat // This could get messy with passing lists by ref... but if you're doing that the list expansion is probably being taken care of elsewhere anyway...
return TRUE
if(SEND_SIGNAL(src, COMSIG_MATCONTAINER_MAT_CHECK, mat) & MATCONTAINER_ALLOW_MAT)
allowed_materials += mat
return TRUE
return FALSE
//========================================================================================
//===================================MID LEVEL=============================================
/**
* Returns the amount of a specific material in this container.
*
* Arguments:
* -[mat][datum/material] : the material type to check for 3 cases
* a) If it's an path its ref is retrieved
* b) If it's text then its an category material & there is no way to deal with it so return 0
* c) If normal material proceeds as usual
*/
/datum/component/material_container/proc/get_material_amount(datum/material/mat)
if(!istype(mat))
mat = GET_MATERIAL_REF(mat)
return materials[mat]
/**
* Returns the amount of material relevant to this container;
* if this container does not support glass, any glass in 'I' will not be taken into account
*
* Arguments:
* - [I][obj/item]: the item whos materials must be retrieved
*/
/datum/component/material_container/proc/get_item_material_amount(obj/item/I, breakdown_flags = mat_container_flags)
if(!istype(I) || !I.matter)
return 0
var/material_amount = 0
var/list/item_materials = I.get_material_composition(breakdown_flags)
for(var/MAT in item_materials)
if(!can_hold_material(MAT))
continue
material_amount += item_materials[MAT]
return material_amount
//================================================================================================
//=========================================HIGH LEVEL==========================================
/// returns the total amount of material in the container
/datum/component/material_container/proc/total_amount()
. = 0
for(var/i in materials)
. += get_material_amount(i)
/**
* Returns TRUE if you have enough of the specified material.
*
* Arguments:
* - [req_mat][datum/material]: the material to check for
* - amount: how much material do we need
*/
/datum/component/material_container/proc/has_enough_of_material(datum/material/req_mat, amount = 1)
return get_material_amount(req_mat) >= OPTIMAL_COST(amount)
/**
* Checks if its possible to afford a certain amount of materials. Takes a dictionary of materials.
* coefficient can be thought of as the machines efficiency & multiplier as the print quantity
*
* Arguments:
* - mats: list of materials(key=material, value= 1 unit of material) to check for
* - coefficient: scaling applied to 1 unit of material in the mats list
* - multiplier: how many units(after scaling) do we require
*/
/datum/component/material_container/proc/has_materials(list/mats, coefficient = 1, multiplier = 1)
if(!length(mats))
return FALSE
for(var/x in mats) //Loop through all required materials
var/wanted = OPTIMAL_COST(mats[x] * coefficient) * multiplier
if(!has_enough_of_material(x, wanted))//Not a category, so just check the normal way
testing("didn't have: [x] wanted: [wanted]")
return FALSE
return TRUE
//==========================================================================================================
//================================================Material Usage============================================
//==================================================LOW LEVEL=======================================
/**
* Uses an amount of a specific material, effectively removing it.
*
* Arguments:
* - amt: amount of said material to use
* - [mat][datum/material]: type of mat to use
*/
/datum/component/material_container/proc/use_amount_mat(amt, datum/material/mat)
//round amount
amt = OPTIMAL_COST(amt)
//get ref if necessary
if(!istype(mat))
mat = GET_MATERIAL_REF(mat)
if(materials[mat] < amt)
return 0
materials[mat] -= amt
return amt
//==============================================================================================
//=========================================MID LEVEL==========================================
/**
* For consuming a dictionary of materials.
*
* Arguments:
* - mats: map of materials to consume(key = material type, value = amount)
* - coefficient: how much fraction of unit material in the mats list must be consumed. This is usually your machines efficiency
* - multiplier: how many units of material in the mats list(after each unit is multiplied and rounded with coefficient) must be consumed, This is usually your print quantity
*/
/datum/component/material_container/proc/use_materials(list/mats, coefficient = 1, multiplier = 1)
if(!mats || !length(mats))
return FALSE
var/amount_removed = 0
for(var/i in mats)
amount_removed += use_amount_mat(OPTIMAL_COST(mats[i] * coefficient) * multiplier, i)
return amount_removed
//============================================================================================
//===========================================HIGH LEVEL=======================================
/**
* For spawning mineral sheets at a specific location. Used by machines to output sheets.
*
* Arguments:
* sheet_amt: number of sheets to extract
* [material][datum/material]: type of sheets present in this container to extract
* [target][atom]: drop location
* [atom][context]: context - the atom performing the operation, this is the last argument sent in COMSIG_MATCONTAINER_SHEETS_RETRIEVED and is used mostly for silo logging
*/
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, datum/material/material, atom/target = null, atom/context = parent)
//do we support sheets of this material
if(!material.stack_type)
return 0 //Add greyscale sheet handling here later
if(!can_hold_material(material))
return 0
//requested amount greater than available amount or just an invalid value
sheet_amt = min(round(materials[material] / SHEET_MATERIAL_AMOUNT), sheet_amt)
if(sheet_amt <= 0)
return 0
//auto drop location
if(!target)
var/atom/parent_atom = parent
target = parent_atom.drop_location()
if(!target)
return 0
//eject sheets based on available amount after each iteration
var/count = 0
while(sheet_amt > 0)
//don't merge yet. we need to do stuff with it first
var/obj/item/stack/material/new_sheets = new material.stack_type(target, min(sheet_amt, MAX_STACK_SIZE), FALSE)
count += new_sheets.amount
//use material & deduct work needed
use_amount_mat(new_sheets.amount * SHEET_MATERIAL_AMOUNT, material)
sheet_amt -= new_sheets.amount
//send signal
SEND_SIGNAL(src, COMSIG_MATCONTAINER_SHEETS_RETRIEVED, new_sheets, context)
//no point merging anything into an already full stack
if(new_sheets.amount == new_sheets.max_amount)
continue
//now we can merge since we are done with it
for(var/obj/item/stack/item_stack in target)
if(item_stack == new_sheets || item_stack.type != material.stack_type) //don't merge with self or different type
continue
//speed merge
var/merge_amount = min(item_stack.amount, new_sheets.max_amount - new_sheets.get_amount())
item_stack.use(merge_amount)
new_sheets.add(merge_amount)
break
return count
/**
* Proc to get all the materials and dump them as sheets
*
* Arguments:
* - target: drop location of the sheets
* - context: the atom which is ejecting the sheets. Used mostly in silo logging
*/
/datum/component/material_container/proc/retrieve_all(target = null, atom/context = parent)
var/result = 0
for(var/MAT in materials)
result += retrieve_sheets(amount2sheet(materials[MAT]), MAT, target, context)
return result
//============================================================================================
/// Turns a material amount into the amount of sheets it should output
/datum/component/material_container/proc/amount2sheet(amt)
if(amt >= SHEET_MATERIAL_AMOUNT)
return round(amt / SHEET_MATERIAL_AMOUNT)
return FALSE
/// Turns an amount of sheets into the amount of material amount it should output
/datum/component/material_container/proc/sheet2amount(sheet_amt)
if(sheet_amt > 0)
return sheet_amt * SHEET_MATERIAL_AMOUNT
return FALSE
/datum/component/material_container/tgui_static_data(mob/user)
var/list/data = list()
data["SHEET_MATERIAL_AMOUNT"] = SHEET_MATERIAL_AMOUNT
return data
/// List format is list(list(name = ..., amount = ..., ref = ..., etc.), list(...))
/datum/component/material_container/tgui_data(mob/user, skip_empty = FALSE)
var/list/data = list()
for(var/datum/material/material as anything in materials)
var/amount = materials[material]
if(amount == 0 && skip_empty)
continue
data += list(list(
"name" = material.name,
"ref" = REF(material),
"amount" = amount,
"color" = material.icon_colour,
"sheets" = round(amount / SHEET_MATERIAL_AMOUNT),
"removable" = amount >= SHEET_MATERIAL_AMOUNT,
))
return data
#undef MATERIAL_INSERT_ITEM_SUCCESS
@@ -0,0 +1,277 @@
/*
This component allows machines to connect remotely to a material container
(namely an /obj/machinery/ore_silo) elsewhere. It offers optional graceful
fallback to a local material storage in case remote storage is unavailable, and
handles linking back and forth.
*/
/datum/component/remote_materials
// Three possible states:
// 1. silo exists, materials is parented to silo
// 2. silo is null, materials is parented to parent
// 3. silo is null, materials is null
///The silo machine this container is connected to
var/obj/machinery/ore_silo/silo
///Material container. the value is either the silo or local
var/datum/component/material_container/mat_container
///Should we create a local storage if we can't connect to silo
var/allow_standalone
///Local size of container when silo = null
var/local_size = INFINITY
///Flags used for the local material container(exceptions for item insert & intent flags)
var/mat_container_flags = NONE
///List of signals to hook onto the local container
var/list/mat_container_signals
/datum/component/remote_materials/Initialize(
mapload,
allow_standalone = TRUE,
force_connect = FALSE,
mat_container_flags = NONE,
list/mat_container_signals = null,
)
if (!isatom(parent))
return COMPONENT_INCOMPATIBLE
src.allow_standalone = allow_standalone
src.mat_container_flags = mat_container_flags
src.mat_container_signals = mat_container_signals
var/turf/T = get_turf(parent)
var/connect_to_silo = FALSE
if(force_connect || (mapload && (T.z in using_map.station_levels)))
connect_to_silo = TRUE
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(on_item_insert))
if(mapload) // wait for silo to initialize during mapload
SSticker.OnRoundstart(CALLBACK(src, PROC_REF(_PrepareStorage), connect_to_silo))
else //directly register in round
_PrepareStorage(connect_to_silo)
/**
* Internal proc. prepares local storage if onnect_to_silo = FALSE
*
* Arguments
* connect_to_silo- if true connect to global silo. If not successfull then go to local storage
* only if allow_standalone = TRUE, else you a null mat_container
*/
/datum/component/remote_materials/proc/_PrepareStorage(connect_to_silo)
PRIVATE_PROC(TRUE)
if (connect_to_silo)
silo = GLOB.ore_silo_default
if (silo)
silo.ore_connected_machines += src
mat_container = silo.materials
if(!mat_container && allow_standalone)
_MakeLocal()
/datum/component/remote_materials/Destroy()
if(silo)
allow_standalone = FALSE
disconnect()
mat_container = null
return ..()
/datum/component/remote_materials/proc/_MakeLocal()
PRIVATE_PROC(TRUE)
silo = null
mat_container = parent.AddComponent( \
/datum/component/material_container, \
subtypesof(/datum/material), \
local_size, \
mat_container_flags, \
container_signals = mat_container_signals, \
allowed_items = /obj/item/stack \
)
/// Adds/Removes this connection from the silo
/datum/component/remote_materials/proc/toggle_holding()
if(isnull(silo))
return
if(!silo.holds[src])
silo.holds[src] = TRUE
else
silo.holds -= src
/**
* Sets the storage size for local materials when not linked with silo
* Arguments
*
* * size - the new size for local storage. measured in SHEET_MATERIAL_SIZE units
*/
/datum/component/remote_materials/proc/set_local_size(size)
local_size = size
if (!silo && mat_container)
mat_container.max_amount = size
///Disconnects this component from the silo
/datum/component/remote_materials/proc/disconnect()
if(isnull(silo))
return
silo.ore_connected_machines -= src
silo = null
mat_container = null
if (allow_standalone)
_MakeLocal()
/datum/component/remote_materials/proc/OnMultitool(datum/source, mob/user, obj/item/multitool/M)
SIGNAL_HANDLER
. = NONE
if (!QDELETED(M.buffer) && istype(M.buffer, /obj/machinery/ore_silo))
if (silo == M.buffer)
to_chat(user, span_warning("[parent] is already connected to [silo]!"))
return FALSE
if(!check_z_level(M.buffer))
to_chat(user, span_warning("[parent] is too far away to get a connection signal!"))
return FALSE
var/obj/machinery/ore_silo/new_silo = M.buffer
var/datum/component/material_container/new_container = new_silo.GetComponent(/datum/component/material_container)
if (silo)
silo.ore_connected_machines -= src
silo.holds -= src
else if (mat_container)
//transfer all mats to silo. whatever cannot be transfered is dumped out as sheets
if(mat_container.total_amount())
for(var/datum/material/mat as anything in mat_container.materials)
var/mat_amount = mat_container.materials[mat]
if(!mat_amount || !new_container.has_space(mat_amount) || !new_container.can_hold_material(mat))
continue
new_container.materials[mat] += mat_amount
mat_container.materials[mat] = 0
qdel(mat_container)
silo = new_silo
silo.ore_connected_machines += src
mat_container = new_container
to_chat(user, span_notice("You connect [parent] to [silo] from the multitool's buffer."))
return TRUE
/datum/component/remote_materials/proc/on_item_insert(datum/source, obj/item/target, mob/living/user)
SIGNAL_HANDLER
if(istype(target, /obj/item/multitool))
return OnMultitool(source, user, target)
if(mat_container_flags & MATCONTAINER_NO_INSERT)
return
return attempt_insert(user, target)
/// Insert mats into silo
/datum/component/remote_materials/proc/attempt_insert(mob/living/user, obj/item/target)
if(silo)
mat_container.user_insert(target, user, parent)
return TRUE
/**
* Checks if the param silo is in the same level as this components parent i.e. connected machine, rcd, etc
*
* Arguments
* silo_to_check- Is this components parent in the same Z level as this param silo. If null
* then check this components connected silo
*
* Returns true if both are on the station or same z level
*/
/datum/component/remote_materials/proc/check_z_level(obj/silo_to_check = silo)
if(isnull(silo_to_check))
return FALSE
return is_valid_z_level(get_turf(silo_to_check), get_turf(parent))
/// returns TRUE if this connection put on hold by the silo
/datum/component/remote_materials/proc/on_hold()
return check_z_level() ? silo.holds[src] : FALSE
/**
* Check if this connection can use any materials from the silo
* Returns true only if
* - The parent is of type movable atom
* - A mat container is actually present
* - The silo in not on hold
* Arguments
* * check_hold - should we check if the silo is on hold
*/
/datum/component/remote_materials/proc/can_use_resource(check_hold = TRUE)
var/atom/movable/movable_parent = parent
if (!istype(movable_parent))
return FALSE
if (!mat_container) //no silolink & local storage not supported
movable_parent.atom_say("No access to material storage, please contact the quartermaster.")
return FALSE
if(check_hold && on_hold()) //silo on hold
movable_parent.atom_say("Mineral access is on hold, please contact the quartermaster.")
return FALSE
return TRUE
/**
* Use materials from either the silo(if connected) or from the local storage. If silo then this action
* is logged else not e.g. action="build" & name="matter bin" means you are trying to build a matter bin
*
* Arguments
* [mats][list]- list of materials to use
* coefficient- each mat unit is scaled by this value then rounded. This value if usually your machine efficiency e.g. upgraded protolathe has reduced costs
* multiplier- each mat unit is scaled by this value then rounded after it is scaled by coefficient. This value is your print quatity e.g. printing multiple items
* action- For logging only. e.g. build, create, i.e. the action you are trying to perform
* name- For logging only. the design you are trying to build e.g. matter bin, etc.
*/
/datum/component/remote_materials/proc/use_materials(list/mats, coefficient = 1, multiplier = 1, action = "build", name = "design")
if(!can_use_resource())
return 0
var/list/rebuilt_mats = list()
for(var/datum/material/req_mat as anything in mats)
var/imat = mats[req_mat]
if(!istype(req_mat))
req_mat = GET_MATERIAL_REF(req_mat)
rebuilt_mats[req_mat] = imat
var/amount_consumed = mat_container.use_materials(rebuilt_mats, coefficient, multiplier)
if (silo)//log only if silo is linked
var/list/scaled_mats = list()
for(var/i in rebuilt_mats)
scaled_mats[i] = OPTIMAL_COST(OPTIMAL_COST(rebuilt_mats[i] * coefficient) * multiplier)
silo.silo_log(parent, action, -multiplier, name, scaled_mats)
return amount_consumed
/**
* Ejects the given material ref and logs it
*
* Arguments
* [material_ref][datum/material]- The material type you are trying to eject
* eject_amount- how many sheets to eject
* [drop_target][atom]- optional where to drop the sheets. null means it is dropped at this components parent location
*/
/datum/component/remote_materials/proc/eject_sheets(datum/material/material_ref, eject_amount, atom/drop_target = null)
if(!can_use_resource())
return 0
var/atom/movable/movable_parent = parent
if(isnull(drop_target))
drop_target = movable_parent.drop_location()
return mat_container.retrieve_sheets(eject_amount, material_ref, target = drop_target, context = parent)
/**
* Insert an item into the mat container, helper proc to insert items with the correct context
*
* Arguments
* * obj/item/weapon - the item you are trying to insert
* * multiplier - the multiplier applied on the materials consumed
*/
/datum/component/remote_materials/proc/insert_item(obj/item/weapon, multiplier = 1)
if(!can_use_resource(FALSE))
return MATERIAL_INSERT_ITEM_FAILURE
return mat_container.insert_item(weapon, multiplier, parent)
@@ -115,3 +115,14 @@
mid_length = 6
end_sound = 'sound/machines/vehicle/engine_end.ogg'
volume = 20
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/lathe_print
mid_sounds = list('sound/machines/lathe/lathe_print.ogg')
mid_length = 2 SECONDS
volume = 50
vary = TRUE
// ignore_walls = FALSE
// falloff_distance = 1
// mid_length_vary = 1 SECONDS
+2 -5
View File
@@ -225,7 +225,7 @@
if(!def_value)//If it's a custom objective, it will be an empty string.
def_value = "custom"
var/list/choices = list("assassinate", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "download", "mercenary", "capture", "absorb", "custom")
var/list/choices = list("assassinate", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "mercenary", "capture", "absorb", "custom")
var/new_obj_type = tgui_input_list(usr, "Select objective type:", "Objective type", choices, def_value)
if (!new_obj_type) return
@@ -294,7 +294,7 @@
if (!steal.select_target())
return
if("download","capture","absorb", "vore")
if("capture","absorb", "vore")
var/def_num
if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]"))
def_num = objective.target_amount
@@ -304,9 +304,6 @@
return
switch(new_obj_type)
if("download")
new_objective = new /datum/objective/download
new_objective.explanation_text = "Download [target_number] research levels."
if("capture")
new_objective = new /datum/objective/capture
new_objective.explanation_text = "Accumulate [target_number] capture points."
+2
View File
@@ -24,12 +24,14 @@
headset = /obj/item/radio/headset/heads/rd
headset_alt = /obj/item/radio/headset/alt/heads/rd
headset_earbud = /obj/item/radio/headset/earbud/heads/rd
l_pocket = /obj/item/experi_scanner
/decl/hierarchy/outfit/job/science/scientist
name = OUTFIT_JOB_NAME(JOB_SCIENTIST)
uniform = /obj/item/clothing/under/rank/scientist
id_type = /obj/item/card/id/science
suit = /obj/item/clothing/suit/storage/toggle/labcoat/science
l_pocket = /obj/item/experi_scanner
/decl/hierarchy/outfit/job/science/xenobiologist
name = OUTFIT_JOB_NAME(JOB_XENOBIOLOGIST)
+3 -9
View File
@@ -30,7 +30,7 @@ var/datum/antagonist/ninja/ninjas
if(!..())
return
var/objective_list = list(1,2,3,4,5)
var/objective_list = list(1,2,3,4)
for(var/i=rand(2,4),i>0,i--)
switch(pick(objective_list))
if(1)//Kill
@@ -56,13 +56,7 @@ var/datum/antagonist/ninja/ninjas
else
i++
objective_list -= 3
if(4)//Download
var/datum/objective/download/ninja_objective = new
ninja_objective.owner = ninja
ninja_objective.gen_amount_goal()
ninja.objectives += ninja_objective
objective_list -= 4
if(5)//Harm
if(4)//Harm
var/datum/objective/harm/ninja_objective = new
ninja_objective.owner = ninja
ninja_objective.target = ninja_objective.find_target()
@@ -70,7 +64,7 @@ var/datum/antagonist/ninja/ninjas
ninja.objectives += ninja_objective
else
i++
objective_list -= 5
objective_list -= 4
var/datum/objective/ninja_highlander/ninja_obj = new
ninja_obj.owner = ninja
-33
View File
@@ -542,39 +542,6 @@ GLOBAL_LIST_EMPTY(all_objectives)
return 1
return 0
/datum/objective/download/proc/gen_amount_goal()
target_amount = rand(10,20)
explanation_text = "Download [target_amount] research levels."
return target_amount
/datum/objective/download/check_completion()
if(!ishuman(owner.current))
return 0
if(!owner.current || owner.current.stat == 2)
return 0
var/current_amount
var/obj/item/rig/S
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
S = H.back
if(!istype(S) || !S.installed_modules || !S.installed_modules.len)
return 0
var/obj/item/rig_module/datajack/stolen_data = locate() in S.installed_modules
if(!istype(stolen_data))
return 0
for(var/datum/tech/current_data in stolen_data.stored_research)
if(current_data.level > 1)
current_amount += (current_data.level-1)
return (current_amount<target_amount) ? 0 : 1
/datum/objective/capture/proc/gen_amount_goal()
target_amount = rand(5,10)
explanation_text = "Accumulate [target_amount] capture points."
+17 -19
View File
@@ -29,8 +29,16 @@
var/filtertext
/// Reference to a remote material inventory, such as an ore silo.
var/datum/component/remote_materials/rmat
/obj/machinery/autolathe/Initialize(mapload)
AddComponent(/datum/component/material_container, subtypesof(/datum/material), 0, MATCONTAINER_EXAMINE, _after_insert = CALLBACK(src, PROC_REF(AfterMaterialInsert)))
rmat = AddComponent( \
/datum/component/remote_materials, \
mapload, \
mat_container_signals = list( \
COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/autolathe, AfterMaterialInsert) \
))
. = ..()
if(!autolathe_recipes)
autolathe_recipes = new()
@@ -58,6 +66,8 @@
/obj/machinery/autolathe/tgui_static_data(mob/user)
var/list/data = ..()
data += rmat.mat_container.tgui_static_data(user)
var/list/categories = list()
var/list/recipes = list()
for(var/datum/category_group/autolathe/A in autolathe_recipes.categories)
@@ -89,8 +99,7 @@
/obj/machinery/autolathe/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
data["busy"] = busy
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
data["materials"] = materials.tgui_data(user, TRUE)
data["materials"] = rmat.mat_container.tgui_data(user, TRUE)
data["mat_efficiency"] = mat_efficiency
return data
@@ -160,7 +169,7 @@
if(making.hidden && !hacked)
return
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/datum/component/material_container/materials = rmat.mat_container
var/list/materials_used = list()
@@ -183,15 +192,11 @@
//Check if we still have the materials.
var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient
for(var/datum/material/used_material as anything in making.resources)
var/amount_needed = making.resources[used_material] * coeff * multiplier
materials_used[used_material] = amount_needed
if(LAZYLEN(materials_used))
if(!materials.has_materials(materials_used))
if(!materials.has_materials(making.resources))
return
materials.use_materials(materials_used)
rmat.use_materials(making.resources, coeff, multiplier)
busy = making.name
update_use_power(USE_POWER_ACTIVE)
@@ -261,18 +266,12 @@
for(var/obj/item/stock_parts/manipulator/M in component_parts)
man_rating += M.rating
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.max_amount = mb_rating * 75000
rmat.set_local_size(mb_rating * 75000)
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()
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
return ..()
/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted)
flick("autolathe_loading", src)//plays metal insertion animation
// use_power(min(1000, amount_inserted / 100))
@@ -280,6 +279,5 @@
/obj/machinery/autolathe/examine(mob/user)
. = ..()
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(in_range(user, src) || isobserver(user))
. += span_notice("The status display reads: Storing up to <b>[materials.max_amount]</b> material units.<br>Material consumption at <b>[mat_efficiency*100]%</b>.")
. += span_notice("The status display reads: Storing up to <b>[rmat.local_size]</b> material units.<br>Material consumption at <b>[mat_efficiency*100]%</b>.")
+7 -5
View File
@@ -35,7 +35,9 @@
new CB.build_path(loc, CB)
return INITIALIZE_HINT_QDEL
/obj/machinery/computer/arcade/proc/prizevend()
/obj/machinery/computer/arcade/proc/prizevend(mob/user)
SEND_SIGNAL(src, COMSIG_ARCADE_PRIZEVEND, user)
if(LAZYLEN(special_prizes)) // Downstream wanted the 'win things inside contents sans circuitboard' feature kept.
var/atom/movable/AM = pick_n_take(special_prizes)
AM.forceMove(get_turf(src))
@@ -221,11 +223,11 @@
emagged = 0
else if(!contents.len)
feedback_inc("arcade_win_normal")
prizevend()
prizevend(user)
else
feedback_inc("arcade_win_normal")
prizevend()
prizevend(user)
else if (emagged && (turtle >= 4))
var/boomamt = rand(5,10)
@@ -1015,7 +1017,7 @@
message_admins("[key_name_admin(user)] made it to Orion on an emagged machine and got an explosive toy ship.")
log_game("[key_name(user)] made it to Orion on an emagged machine and got an explosive toy ship.")
else
prizevend()
prizevend(user)
emagged = 0
name = "The Orion Trail"
desc = "Learn how our ancestors got to Orion, and have fun in the process!"
@@ -1292,7 +1294,7 @@
if(prob(winprob)) /// YEAH.
if(!emagged)
prizevend()
prizevend(user)
winscreen = "You won!"
else if(emagged)
gameprice = 1
@@ -4,14 +4,6 @@
board_type = new /datum/frame/frame_types/button
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/datum/design/circuit/airlock_cycling
name = "Machine Design (Cycling Airlock Board)"
desc = "The circuit board for cycling airlock parts."
id = "airlock_cycling"
build_path = /obj/item/circuitboard/airlock_cycling
req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2)
sort_string = "MAAAD"
/obj/item/circuitboard/airlock_cycling/attackby(obj/item/I as obj, mob/user as mob)
if(I.has_tool_quality(TOOL_MULTITOOL))
var/result = tgui_input_list(
+1
View File
@@ -429,6 +429,7 @@ Class Procs:
. = dismantle()
/obj/machinery/proc/dismantle()
SEND_SIGNAL(src, COMSIG_OBJ_DECONSTRUCT)
playsound(src, 'sound/items/Crowbar.ogg', 50, 1)
for(var/obj/I in contents)
if(istype(I,/obj/item/card/id))
-724
View File
@@ -1,724 +0,0 @@
/obj/machinery/mecha_part_fabricator
icon = 'icons/obj/robotics_vr.dmi' //VOREStation Edit - New icon
icon_state = "mechfab"
name = "Exosuit Fabricator"
desc = "A machine used for the construction of mechas."
density = TRUE
anchored = TRUE
use_power = USE_POWER_IDLE
idle_power_usage = 20
active_power_usage = 5000
req_access = list(access_robotics)
circuit = /obj/item/circuitboard/mechfab
/// 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(
MAT_STEEL = 0,
MAT_GLASS = 0,
MAT_PLASTIC = 0,
MAT_GRAPHITE = 0,
MAT_PLASTEEL = 0,
MAT_GOLD = 0,
MAT_SILVER = 0,
MAT_LEAD = 0,
MAT_OSMIUM = 0,
MAT_DIAMOND = 0,
MAT_DURASTEEL = 0,
MAT_PHORON = 0,
MAT_URANIUM = 0,
MAT_VERDANTIUM = 0,
MAT_MORPHIUM = 0,
MAT_METALHYDROGEN = 0,
MAT_SUPERMATTER = 0,
MAT_TITANIUM = 0)
var/res_max_amount = 200000
var/datum/research/files
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",
"Pinnace",
"Baron",
"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(mapload)
. = ..()
default_apply_parts()
files = new /datum/research(src) //Setup the research data holder.
/obj/machinery/mecha_part_fabricator/dismantle()
for(var/f in materials)
eject_materials(f, -1)
..()
/obj/machinery/mecha_part_fabricator/RefreshParts()
res_max_amount = 0
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
res_max_amount += M.rating * 100000 // 200k -> 600k
var/T = 0
for(var/obj/item/stock_parts/manipulator/M in component_parts)
T += M.rating
component_coeff = max(1 - (T - 1) / 4, 0.2) // 1 -> 0.2
for(var/obj/item/stock_parts/micro_laser/M in component_parts) // Not resetting T is intended; time_coeff is affected by both
T += M.rating
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_UTILITY)
sub_category += "All Cyborgs - Utility"
if(module_types & BORG_BASIC)
sub_category += "All Cyborgs - Basic"
if(module_types & BORG_ADVANCED)
sub_category += "All Cyborgs - Advanced"
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"
if(module_types & BORG_MODULE_SCIENCE)
sub_category += "Science"
if(module_types & BORG_MODULE_SERVICE)
sub_category += "Service"
if(module_types & BORG_MODULE_CLERIC)
sub_category += "Cleric"
if(module_types & BORG_MODULE_COMBAT)
sub_category += "Combat"
if(module_types & BORG_MODULE_EXPLO)
sub_category += "Exploration"
else
sub_category += "This shouldn't be here, bother a dev!"
// 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"
if(mech_types & EXOSUIT_MODULE_PINNACE)
category_override += "Pinnace"
if(mech_types & EXOSUIT_MODULE_BARON)
category_override += "Baron"
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("[icon_state]-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("[icon_state]-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))
to_chat(user, span_warning("\The [src] rejects your use due to lack of access!"))
return
tgui_interact(user)
/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, "ExosuitFabricator", name)
ui.open()
/obj/machinery/mecha_part_fabricator/tgui_static_data(mob/user)
var/list/data = list()
var/list/final_sets = list()
var/list/buildable_parts = list()
for(var/part_set in part_sets)
final_sets += part_set
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(part["categoryOverride"])
for(var/cat in part["categoryOverride"])
buildable_parts[cat] += list(part)
if(!(cat in part_sets))
final_sets += cat
continue
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
data["buildingPart"] = null
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, list/params, datum/tgui/ui)
if(..())
return TRUE
. = TRUE
add_fingerprint(ui.user)
ui.user.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(being_built)
to_chat(user, span_notice("\The [src] is busy. Please wait for completion of previous operation."))
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/stack/material))
var/obj/item/stack/material/S = I
if(!(S.material.name in materials))
to_chat(user, span_warning("The [src] doesn't accept [material_display_name(S.material)]!"))
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("[loading_icon_state]", src)
// yess hacky but whatever //even more hacky now, but at least it works
if(loading_icon_state == "mechfab-idle")
flick("mechfab-load-metal", 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.")
else
to_chat(user, "The fabricator cannot hold more [sname].")
return
..()
/obj/machinery/mecha_part_fabricator/emag_act(var/remaining_charges, var/mob/user)
switch(emagged)
if(0)
emagged = 0.5
visible_message("[icon2html(src,viewers(src))] <b>[src]</b> beeps: \"DB error \[Code 0x00F1\]\"")
sleep(10)
visible_message("[icon2html(src,viewers(src))] <b>[src]</b> beeps: \"Attempting auto-repair\"")
sleep(15)
visible_message("[icon2html(src,viewers(src))] <b>[src]</b> beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
sleep(30)
visible_message("[icon2html(src,viewers(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("[icon2html(src,viewers(src))] <b>[src]</b> beeps: \"DB not responding \[Code 0x0003\]...\"")
if(1)
visible_message("[icon2html(src,viewers(src))] <b>[src]</b> beeps: \"No records in User DB\"")
/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 ? TRUE : FALSE
var/matstring = lowertext(material)
// 0 or null, nothing to eject
if(!materials[matstring])
return
// Problem, fix problem and abort
if(materials[matstring] < 0)
warning("[src] tried to eject material '[material]', which it has 'materials[matstring]' of!")
materials[matstring] = 0
return
// Find the material datum for our material
var/datum/material/M = get_material_by_name(matstring)
if(!M)
warning("[src] tried to eject material '[matstring]', which didn't match any known material datum!")
return
// Find what type of sheets it makes
var/obj/item/stack/material/S = M.stack_type
if(!S)
warning("[src] tried to eject material '[matstring]', which didn't have a stack_type!")
return
// If we were passed -1, then it's recursive ejection and we should eject all we can
if(amount <= 0)
amount = initial(S.max_amount)
// Smaller of what we have left, or the desired amount (note the amount is in sheets, but the array stores perunit values)
var/ejected = min(round(materials[matstring] / initial(S.perunit)), amount)
// Place a sheet
S = M.place_sheet(get_turf(src), ejected)
if(!istype(S))
warning("[src] tried to eject material '[material]', which didn't generate a proper stack when asked!")
return
// Reduce our amount stored
materials[matstring] -= ejected * S.perunit
// Recurse if we have enough left for more sheets
if(recursive && materials[matstring] >= S.perunit)
eject_materials(matstring, -1)
-164
View File
@@ -1,164 +0,0 @@
/obj/machinery/mecha_part_fabricator/pros
icon = 'icons/obj/robotics_vr.dmi' //VOREStation Edit - New icon
icon_state = "prosfab"
name = "Prosthetics Fabricator"
desc = "A machine used for the construction of prosthetics."
density = TRUE
anchored = TRUE
unacidable = TRUE
use_power = USE_POWER_IDLE
idle_power_usage = 20
active_power_usage = 5000
req_access = list(access_robotics)
circuit = /obj/item/circuitboard/prosthetics
// Prosfab specific stuff
var/manufacturer = null
var/species_types = list("Human")
var/species = "Human"
loading_icon_state = null
materials = list(
MAT_STEEL = 0,
MAT_GLASS = 0,
MAT_PLASTIC = 0,
MAT_GRAPHITE = 0,
MAT_PLASTEEL = 0,
MAT_GLASS = 0,
MAT_SILVER = 0,
MAT_LEAD = 0,
MAT_OSMIUM = 0,
MAT_GOLD = 0,
MAT_PLATINUM = 0,
MAT_DIAMOND = 0,
MAT_DURASTEEL = 0,
MAT_PHORON = 0,
MAT_URANIUM = 0,
MAT_VERDANTIUM = 0,
MAT_MORPHIUM = 0)
res_max_amount = 200000
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",
"Pinnace",
"Baron",
"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",
"pAI Parts", //VOREStation Add
"Implants",
"Control Interfaces",
"Other",
"Misc",
)
/obj/machinery/mecha_part_fabricator/pros/Initialize(mapload)
. = ..()
manufacturer = GLOB.basic_robolimb.company
/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/mecha_part_fabricator/pros/tgui_data(mob/user)
var/list/data = ..()
data["species_types"] = species_types
data["species"] = species
if(GLOB.all_robolimbs)
var/list/T = list()
for(var/A in GLOB.all_robolimbs)
var/datum/robolimb/R = GLOB.all_robolimbs[A]
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
return data
/obj/machinery/mecha_part_fabricator/pros/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
. = TRUE
add_fingerprint(ui.user)
ui.user.set_machine(src)
switch(action)
if("species")
var/new_species = tgui_input_list(ui.user, "Select a new species", "Prosfab Species Selection", species_types)
if(new_species && tgui_status(ui.user, state) == STATUS_INTERACTIVE)
species = new_species
return
if("manufacturer")
var/list/new_manufacturers = list()
for(var/A in GLOB.all_robolimbs)
var/datum/robolimb/R = GLOB.all_robolimbs[A]
if(R.unavailable_to_build)
continue
if(species in R.species_cannot_use)
continue
new_manufacturers += A
var/new_manufacturer = tgui_input_list(ui.user, "Select a new manufacturer", "Prosfab Species Selection", new_manufacturers)
if(new_manufacturer && tgui_status(ui.user, state) == STATUS_INTERACTIVE)
manufacturer = new_manufacturer
return
return FALSE
/obj/machinery/mecha_part_fabricator/pros/attackby(var/obj/item/I, var/mob/user)
if(..())
return 1
if(istype(I,/obj/item/disk/limb))
var/obj/item/disk/limb/D = I
if(!D.company || !(D.company in GLOB.all_robolimbs))
to_chat(user, span_warning("This disk seems to be corrupted!"))
else
to_chat(user, span_notice("Installing blueprint files for [D.company]..."))
if(do_after(user,50,src))
var/datum/robolimb/R = GLOB.all_robolimbs[D.company]
R.unavailable_to_build = 0
to_chat(user, span_notice("Installed [D.company] blueprints!"))
qdel(I)
return
if(istype(I,/obj/item/disk/species))
var/obj/item/disk/species/D = I
if(!D.species || !(D.species in GLOB.all_species))
to_chat(user, span_warning("This disk seems to be corrupted!"))
else
to_chat(user, span_notice("Uploading modification files for [D.species]..."))
if(do_after(user,50,src))
species_types |= D.species
to_chat(user, span_notice("Uploaded [D.species] files!"))
qdel(I)
return
-187
View File
@@ -1,187 +0,0 @@
/datum/design/item/mechfab/gopher
category = list("Gopher")
time = 5
/datum/design/item/mechfab/gopher/chassis
name = "Gopher Chassis"
id = "gopher_chassis"
build_path = /obj/item/mecha_parts/micro/chassis/gopher
time = 3
materials = list(MAT_STEEL = 7000)
/datum/design/item/mechfab/gopher/torso
name = "Gopher Torso"
id = "gopher_torso"
build_path = /obj/item/mecha_parts/micro/part/gopher_torso
materials = list(MAT_STEEL = 15000, MAT_GLASS = 5250)
/datum/design/item/mechfab/gopher/left_arm
name = "Gopher Left Arm"
id = "gopher_left_arm"
build_path = /obj/item/mecha_parts/micro/part/gopher_left_arm
materials = list(MAT_STEEL = 8750)
/datum/design/item/mechfab/gopher/right_arm
name = "Gopher Right Arm"
id = "gopher_right_arm"
build_path = /obj/item/mecha_parts/micro/part/gopher_right_arm
materials = list(MAT_STEEL = 8750)
/datum/design/item/mechfab/gopher/left_leg
name = "Gopher Left Leg"
id = "gopher_left_leg"
build_path = /obj/item/mecha_parts/micro/part/gopher_left_leg
materials = list(MAT_STEEL = 12500)
/datum/design/item/mechfab/gopher/right_leg
name = "Gopher Right Leg"
id = "gopher_right_leg"
build_path = /obj/item/mecha_parts/micro/part/gopher_right_leg
materials = list(MAT_STEEL = 12500)
/datum/design/item/mecha/drill/micro
name = "Miniature Drill"
id = "micro_drill"
build_path = /obj/item/mecha_parts/mecha_equipment/tool/drill/micro
time = 5
materials = list(MAT_STEEL = 2500)
/datum/design/item/mecha/hydraulic_clamp/micro
name = "Mounted ore box"
id = "ore_scoop"
build_path = /obj/item/mecha_parts/mecha_equipment/tool/micro/orescoop
time = 5
materials = list(MAT_STEEL = 2500)
/datum/design/item/mechfab/polecat
category = list("Polecat")
time = 10
/datum/design/item/mechfab/polecat/chassis
name = "Polecat Chassis"
id = "polecat_chassis"
build_path = /obj/item/mecha_parts/micro/chassis/polecat
time = 3
materials = list(MAT_STEEL = 7000)
/datum/design/item/mechfab/polecat/torso
name = "Polecat Torso"
id = "polecat_torso"
build_path = /obj/item/mecha_parts/micro/part/polecat_torso
materials = list(MAT_STEEL = 15000, MAT_GLASS = 5250)
/datum/design/item/mechfab/polecat/left_arm
name = "Polecat Left Arm"
id = "polecat_left_arm"
build_path = /obj/item/mecha_parts/micro/part/polecat_left_arm
materials = list(MAT_STEEL = 8750)
/datum/design/item/mechfab/polecat/right_arm
name = "Polecat Right Arm"
id = "polecat_right_arm"
build_path = /obj/item/mecha_parts/micro/part/polecat_right_arm
materials = list(MAT_STEEL = 8750)
/datum/design/item/mechfab/polecat/left_leg
name = "Polecat Left Leg"
id = "polecat_left_leg"
build_path = /obj/item/mecha_parts/micro/part/polecat_left_leg
materials = list(MAT_STEEL = 12500)
/datum/design/item/mechfab/polecat/right_leg
name = "Polecat Right Leg"
id = "polecat_right_leg"
build_path = /obj/item/mecha_parts/micro/part/polecat_right_leg
materials = list(MAT_STEEL = 12500)
/datum/design/item/mechfab/polecat/armour
name = "Polecat Armour Plates"
id = "polecat_armour"
build_path = /obj/item/mecha_parts/micro/part/polecat_armour
time = 25
materials = list(MAT_STEEL = 12500, MAT_PLASTIC = 7500)
/datum/design/item/mecha/taser/micro
name = "\improper TS-12 \"Suppressor\" integrated taser"
id = "micro_taser"
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/microtaser
/datum/design/item/mecha/weapon/laser/micro
name = "\improper WS-19 \"Torch\" laser carbine"
id = "micro_laser"
// req_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 3)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/microlaser
/datum/design/item/mecha/weapon/laser_heavy/micro
name = "\improper PC-20 \"Lance\" light laser cannon"
id = "micro_laser_heavy"
req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3)
materials = list(MAT_STEEL = 10000, MAT_GLASS = 1000, MAT_DIAMOND = 2000)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/microheavy
/datum/design/item/mecha/weapon/grenade_launcher/micro
name = "\improper FP-20 mounted grenade launcher"
id = "micro_flashbang_launcher"
// req_tech = list(TECH_COMBAT = 3)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/microflashbang
/datum/design/item/mecha/weapon/scattershot/micro
name = "\improper Remington C-12 \"Boomstick\""
desc = "A mounted combat shotgun with integrated ammo-lathe."
id = "micro_scattershot"
// req_tech = list(TECH_COMBAT = 4)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/microshotgun
/datum/design/item/mechfab/weasel
category = list("Weasel")
time = 5
/datum/design/item/mechfab/weasel/chassis
name = "Weasel Chassis"
id = "weasel_chassis"
build_path = /obj/item/mecha_parts/micro/chassis/weasel
time = 3
materials = list(MAT_STEEL = 7000)
/datum/design/item/mechfab/weasel/torso
name = "Weasel Torso"
id = "weasel_torso"
build_path = /obj/item/mecha_parts/micro/part/weasel_torso
materials = list(MAT_STEEL = 15000, MAT_GLASS = 5250)
/datum/design/item/mechfab/weasel/left_arm
name = "Weasel Left Arm"
id = "weasel_left_arm"
build_path = /obj/item/mecha_parts/micro/part/weasel_left_arm
materials = list(MAT_STEEL = 8750)
/datum/design/item/mechfab/weasel/right_arm
name = "Weasel Right Arm"
id = "weasel_right_arm"
build_path = /obj/item/mecha_parts/micro/part/weasel_right_arm
materials = list(MAT_STEEL = 8750)
/*/datum/design/item/mechfab/weasel/left_leg
name = "Weasel Left Leg"
id = "weasel_left_leg"
build_path = /obj/item/mecha_parts/micro/part/weasel_left_leg
materials = list(MAT_STEEL = 12500)
/datum/design/item/mechfab/weasel/right_leg
name = "Weasel Right Leg"
id = "weasel_right_leg"
build_path = /obj/item/mecha_parts/micro/part/weasel_right_leg
materials = list(MAT_STEEL = 12500)*/
/datum/design/item/mechfab/weasel/tri_leg
name = "Weasel Tri Leg"
id = "weasel_right_leg"
build_path = /obj/item/mecha_parts/micro/part/weasel_tri_leg
materials = list(MAT_STEEL = 27500)
/datum/design/item/mechfab/weasel/head
name = "Weasel Head"
id = "weasel_head"
build_path = /obj/item/mecha_parts/micro/part/weasel_head
materials = list(MAT_STEEL = 7000, MAT_GLASS = 2500)
+2 -2
View File
@@ -51,7 +51,7 @@
icon_state = "micromech_shotgun"
equip_cooldown = 15
var/mode = 0 //0 - buckshot, 1 - beanbag, 2 - slug.
projectile = /obj/item/projectile/bullet/pellet/shotgun
projectile = /obj/item/projectile/scatter/shotgun
fire_sound = 'sound/weapons/gunshot_shotgun.ogg'
fire_volume = 80
projectiles = 6
@@ -68,7 +68,7 @@
switch(mode)
if(0)
occupant_message("Now firing buckshot.")
projectile = /obj/item/projectile/bullet/pellet/shotgun
projectile = /obj/item/projectile/scatter/shotgun
if(1)
occupant_message("Now firing beanbags.")
projectile = /obj/item/projectile/bullet/shotgun/beanbag
@@ -0,0 +1,19 @@
/**
* Creates a mutable appearance with the material color applied for its insertion animation into an autolathe or techfab
* Arguments
*
* * material - the material used to generate the overlay
*/
/proc/material_insertion_animation(datum/material/material)
RETURN_TYPE(/mutable_appearance)
var/static/list/mutable_appearance/apps = list()
var/mutable_appearance/cached_app = apps[material]
if(isnull(cached_app))
cached_app = mutable_appearance('icons/obj/machines/research_vr.dmi', "material_insertion")
cached_app.color = material.icon_colour
// cached_app.alpha = material.alpha
apps[material] = cached_app
return cached_app
@@ -6,6 +6,7 @@
icon_state = "nanopaste"
origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3)
amount = 10
max_amount = 10
toolspeed = 0.75 //Used in surgery, shouldn't be the same speed as a normal screwdriver on mechanical organ repair.
w_class = ITEMSIZE_SMALL
no_variants = FALSE
+5
View File
@@ -55,6 +55,11 @@
synths.Cut()
return ..()
/obj/item/stack/get_material_composition(breakdown_flags)
. = ..()
for(var/M in .)
.[M] *= amount
/obj/item/stack/update_icon()
if(no_variants)
icon_state = initial(icon_state)
@@ -78,3 +78,12 @@
network = list(NETWORK_XENOBIO)
req_access = list()
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/machine/rdserver
name = T_BOARD("R&D Server")
build_path = /obj/machinery/rnd/server
board_type = new /datum/frame/frame_types/machine
req_components = list(
/obj/item/stack/cable_coil = 2,
/obj/item/stock_parts/scanning_module = 1,
)
@@ -4,18 +4,4 @@
/obj/item/circuitboard/rdconsole
name = T_BOARD("R&D control console")
build_path = /obj/machinery/computer/rdconsole/core
/obj/item/circuitboard/rdconsole/attackby(obj/item/I as obj, mob/user as mob)
if(I.has_tool_quality(TOOL_SCREWDRIVER))
playsound(src, I.usesound, 50, 1)
user.visible_message(span_infoplain(span_bold("\The [user]") + " adjusts the jumper on \the [src]'s access protocol pins."), span_notice("You adjust the jumper on the access protocol pins."))
if(build_path == /obj/machinery/computer/rdconsole/core)
name = T_BOARD("RD Console - Robotics")
build_path = /obj/machinery/computer/rdconsole/robotics
to_chat(user, span_notice("Access protocols set to robotics."))
else
name = T_BOARD("RD Console")
build_path = /obj/machinery/computer/rdconsole/core
to_chat(user, span_notice("Access protocols set to default."))
return
build_path = /obj/machinery/computer/rdconsole_tg
@@ -2,39 +2,6 @@
#error T_BOARD macro is not defined but we need it!
#endif
/obj/item/circuitboard/rdserver
name = T_BOARD("R&D server")
build_path = /obj/machinery/r_n_d/server/core
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_DATA = 3)
req_components = list(
/obj/item/stack/cable_coil = 2,
/obj/item/stock_parts/scanning_module = 1)
/obj/item/circuitboard/rdserver/attackby(obj/item/I as obj, mob/user as mob)
if(I.has_tool_quality(TOOL_SCREWDRIVER))
playsound(src, I.usesound, 50, 1)
user.visible_message(span_infoplain(span_bold("\The [user]") + " adjusts the jumper on \the [src]'s access protocol pins."), span_notice("You adjust the jumper on the access protocol pins."))
if(build_path == /obj/machinery/r_n_d/server/core)
name = T_BOARD("RD Console - Robotics")
build_path = /obj/machinery/r_n_d/server/robotics
to_chat(user, span_notice("Access protocols set to robotics."))
else
name = T_BOARD("RD Console")
build_path = /obj/machinery/r_n_d/server/core
to_chat(user, span_notice("Access protocols set to default."))
return
/obj/item/circuitboard/destructive_analyzer
name = T_BOARD("destructive analyzer")
build_path = /obj/machinery/r_n_d/destructive_analyzer
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2, TECH_DATA = 2)
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
/obj/item/stock_parts/manipulator = 1,
/obj/item/stock_parts/micro_laser = 1)
/obj/item/circuitboard/autolathe
name = T_BOARD("autolathe")
build_path = /obj/machinery/autolathe
@@ -45,19 +12,40 @@
/obj/item/stock_parts/manipulator = 1,
/obj/item/stock_parts/console_screen = 1)
/obj/item/circuitboard/protolathe
/obj/item/circuitboard/machine/protolathe
name = T_BOARD("protolathe")
build_path = /obj/machinery/r_n_d/protolathe
build_path = /obj/machinery/rnd/production/protolathe
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2)
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
/obj/item/stock_parts/manipulator = 2,
/obj/item/reagent_containers/glass/beaker = 2)
/obj/item/circuitboard/machine/protolathe/department
name = T_BOARD("departmental protolathe")
build_path = /obj/machinery/rnd/production/protolathe/department
/obj/item/circuitboard/machine/protolathe/department/engineering
name = T_BOARD("departmental protolathe (engineering)")
build_path = /obj/machinery/rnd/production/protolathe/department/engineering
/obj/item/circuitboard/machine/protolathe/department/service
name = T_BOARD("departmental protolathe (service)")
build_path = /obj/machinery/rnd/production/protolathe/department/service
/obj/item/circuitboard/machine/protolathe/department/medical
name = T_BOARD("departmental protolathe (medical)")
build_path = /obj/machinery/rnd/production/protolathe/department/medical
/obj/item/circuitboard/machine/protolathe/department/cargo
name = T_BOARD("departmental protolathe (cargo)")
build_path = /obj/machinery/rnd/production/protolathe/department/cargo
/obj/item/circuitboard/machine/protolathe/department/science
name = T_BOARD("departmental protolathe (science)")
build_path = /obj/machinery/rnd/production/protolathe/department/science
/obj/item/circuitboard/machine/protolathe/department/security
name = T_BOARD("departmental protolathe (security)")
build_path = /obj/machinery/rnd/production/protolathe/department/security
/obj/item/circuitboard/circuit_imprinter
name = T_BOARD("circuit imprinter")
build_path = /obj/machinery/r_n_d/circuit_imprinter
build_path = /obj/machinery/rnd/production/circuit_imprinter
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2)
req_components = list(
@@ -67,7 +55,7 @@
/obj/item/circuitboard/mechfab
name = "Circuit board (Exosuit Fabricator)"
build_path = /obj/machinery/mecha_part_fabricator
build_path = /obj/machinery/mecha_part_fabricator_tg
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3)
req_components = list(
@@ -78,7 +66,7 @@
/obj/item/circuitboard/prosthetics
name = "Circuit board (Prosthetics Fabricator)"
build_path = /obj/machinery/mecha_part_fabricator/pros
build_path = /obj/machinery/mecha_part_fabricator_tg/prosthetics
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3)
req_components = list(
@@ -17,3 +17,9 @@
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
/obj/item/stock_parts/manipulator = 2)
/obj/item/circuitboard/machine/ore_silo
name = T_BOARD("Ore Silo")
build_path = /obj/machinery/ore_silo
board_type = new /datum/frame/frame_types/machine
req_components = list()
@@ -43,6 +43,7 @@
var/vore_sound = 'sound/effects/metalscrape2.ogg'
/obj/structure/closet/Initialize(mapload)
ADD_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER, ROUNDSTART_TRAIT)
..()
return INITIALIZE_HINT_LATELOAD
+16 -9
View File
@@ -30,6 +30,7 @@
law_list = dd_sortedObjectList(law_list)
/datum/eventkit/modify_robot/tgui_close()
target = null
if(source)
qdel(source)
@@ -586,13 +587,19 @@
to_chat(ui.user, span_notice("Laws displayed."))
return TRUE
if("select_ai")
selected_ai = locate(params["new_ai"])
selected_ai = params["new_ai"]
return TRUE
if("swap_sync")
var/new_ai = selected_ai ? selected_ai : select_active_ai_with_fewest_borgs()
if(new_ai)
var/mob/living/silicon/ai/our_ai
for(var/mob/living/silicon/ai/ai in GLOB.ai_list)
if(ai.name == selected_ai)
our_ai = ai
break
if(!our_ai)
our_ai = select_active_ai_with_fewest_borgs()
if(our_ai)
target.lawupdate = 1
target.connect_to_ai(new_ai)
target.connect_to_ai(our_ai)
return TRUE
if("disconnect_ai")
if(target.is_slaved())
@@ -649,7 +656,7 @@
var/list/all_upgrades = list()
var/list/whitelisted_upgrades = list()
var/list/blacklisted_upgrades = list()
for(var/datum/design/item/prosfab/robot_upgrade/restricted/upgrade)
for(var/datum/design_techweb/prosfab/robot_upgrade/restricted/upgrade as anything in subtypesof(/datum/design_techweb/prosfab/robot_upgrade/restricted))
if(!upgrade.name)
continue
if(!(initial(upgrade.build_path) in target.module.supported_upgrades))
@@ -659,14 +666,14 @@
all_upgrades["whitelisted_upgrades"] = whitelisted_upgrades
all_upgrades["blacklisted_upgrades"] = blacklisted_upgrades
var/list/utility_upgrades = list()
for(var/datum/design/item/prosfab/robot_upgrade/utility/upgrade)
for(var/datum/design_techweb/prosfab/robot_upgrade/utility/upgrade as anything in subtypesof(/datum/design_techweb/prosfab/robot_upgrade/utility))
if(!upgrade.name)
continue
if(!(target.has_upgrade(initial(upgrade.build_path))))
utility_upgrades += list(list("name" = initial(upgrade.name), "path" = "[initial(upgrade.build_path)]"))
all_upgrades["utility_upgrades"] = utility_upgrades
var/list/basic_upgrades = list()
for(var/datum/design/item/prosfab/robot_upgrade/basic/upgrade)
for(var/datum/design_techweb/prosfab/robot_upgrade/basic/upgrade as anything in subtypesof(/datum/design_techweb/prosfab/robot_upgrade/basic))
if(!upgrade.name)
continue
if(!(target.has_upgrade(initial(upgrade.build_path))))
@@ -675,7 +682,7 @@
basic_upgrades += list(list("name" = initial(upgrade.name), "path" = "[initial(upgrade.build_path)]", "installed" = 1))
all_upgrades["basic_upgrades"] = basic_upgrades
var/list/advanced_upgrades = list()
for(var/datum/design/item/prosfab/robot_upgrade/advanced/upgrade)
for(var/datum/design_techweb/prosfab/robot_upgrade/advanced/upgrade as anything in subtypesof(/datum/design_techweb/prosfab/robot_upgrade/advanced))
if(!upgrade.name)
continue
if(!(target.has_upgrade(initial(upgrade.build_path))))
@@ -684,7 +691,7 @@
advanced_upgrades += list(list("name" = initial(upgrade.name), "path" = "[initial(upgrade.build_path)]", "installed" = 1))
all_upgrades["advanced_upgrades"] = advanced_upgrades
var/list/restricted_upgrades = list()
for(var/datum/design/item/prosfab/robot_upgrade/restricted/upgrade)
for(var/datum/design_techweb/prosfab/robot_upgrade/restricted/upgrade as anything in subtypesof(/datum/design_techweb/prosfab/robot_upgrade/restricted))
if(!upgrade.name)
continue
if(!(target.has_upgrade(initial(upgrade.build_path))))
-366
View File
@@ -1,366 +0,0 @@
//Allows to add and remove modules from borgs
/client/proc/modify_robot(var/mob/living/silicon/robot/target in GLOB.silicon_mob_list)
set name = "Modify Robot Module"
set desc = "Allows to add or remove modules to/from robots."
set category = "Admin.Silicon"
if(!check_rights(R_ADMIN|R_FUN|R_VAREDIT|R_EVENT))
return
if(!istype(target))
return
if(!target.module)
var/list/pre_modification_options = list(MODIFIY_ROBOT_TOGGLE_ERT, MODIFIY_ROBOT_LIMIT_MODULES_ADD, MODIFIY_ROBOT_LIMIT_MODULES_REMOVE)
while(TRUE)
var/pre_modification_choice = tgui_input_list(usr, "Which pre module selection edits would you like to perform form [target]","Choice", pre_modification_options)
if(!pre_modification_choice || pre_modification_choice == "Cancel")
return
switch(pre_modification_choice)
if(MODIFIY_ROBOT_TOGGLE_ERT)
if(tgui_alert(usr, "This robot has not yet selected a module. Would you like to toggle combat module override?","Confirm",list("Yes","No"))!="Yes")
continue
target.crisis_override = !target.crisis_override
to_chat(usr, span_danger("You [target.crisis_override? "enabled":"disabled"] [target]'s combat module overwrite."))
continue
if(MODIFIY_ROBOT_LIMIT_MODULES_ADD)
if(target.restrict_modules_to.len)
to_chat(usr, span_warning("[target]'s modules are already restricted. For details you can use the remove verb to show all active restrictions."))
var/list/possible_options = list()
for(var/entry in robot_modules)
if(!target.restrict_modules_to.Find(entry))
possible_options += entry
while(TRUE)
var/selected_type = tgui_input_list(usr, "Please select the module type to add to the robot's restrictions. This will limit the module choices to the added types only.", "Module types", possible_options)
if(!selected_type || selected_type == "Cancel")
break
possible_options -= selected_type
target.restrict_modules_to += selected_type
to_chat(usr, span_danger("You added [selected_type] to [target]'s possible modules list."))
continue
if(MODIFIY_ROBOT_LIMIT_MODULES_REMOVE)
while(TRUE)
var/selected_type = tgui_input_list(usr, "Please select the module type to remove. Removing all module types here will allow default station module selection.", "Module types", target.restrict_modules_to)
if(!selected_type || selected_type == "Cancel")
to_chat(usr, span_danger("[target] uses the default module list without special restrictions."))
break
target.restrict_modules_to -= selected_type
to_chat(usr, span_danger("You removed [selected_type] from [target]'s possible modules list."))
continue
if(!target.module.modules)
return
var/list/modification_options = list(MODIFIY_ROBOT_MODULE_ADD,MODIFIY_ROBOT_MODULE_REMOVE, MODIFIY_ROBOT_APPLY_UPGRADE, MODIFIY_ROBOT_SUPP_ADD, MODIFIY_ROBOT_SUPP_REMOVE, MODIFIY_ROBOT_RADIOC_ADD, MODIFIY_ROBOT_RADIOC_REMOVE,
MODIFIY_ROBOT_COMP_ADD, MODIFIY_ROBOT_COMP_REMOVE, MODIFIY_ROBOT_SWAP_MODULE, MODIFIY_ROBOT_RESET_MODULE, MODIFIY_ROBOT_TOGGLE_ERT, MODIFIY_ROBOT_TOGGLE_STATION_ACCESS, MODIFIY_ROBOT_TOGGLE_CENT_ACCESS)
while(TRUE)
var/modification_choice = tgui_input_list(usr, "Select if you want to add or remove a module to/from [target]","Choice", modification_options)
if(!modification_choice || modification_choice == "Cancel")
return
if(!target.module || !target.module.modules)
to_chat(usr, span_danger("[target] was recently reset, you must wait until module selection has been completed before continuing modifying."))
continue
log_and_message_admins("has used MODIFYROBOT ([modification_choice]) on [key_name(target)].", usr)
feedback_add_details("admin_verb","MODIFYROBOT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
switch(modification_choice)
if(MODIFIY_ROBOT_MODULE_ADD)
while(TRUE)
var/selected_module_module = tgui_input_list(usr, "Please select the module to pick modules from", "Module", robot_modules)
if(!selected_module_module || selected_module_module == "Cancel")
break
var/module_type = robot_modules[selected_module_module]
var/mob/living/silicon/robot/robot = new /mob/living/silicon/robot(null)
var/obj/item/robot_module/robot/robot_type = new module_type(robot)
robot.emag_items = 1
if(!istype(robot_type, /obj/item/robot_module/robot/))
qdel(robot)
break
var/list/all_modules = robot.module.modules
all_modules += robot.module.emag
while(TRUE)
var/add_item_select = tgui_input_list(usr, "Please select the module to add", "Modules", all_modules)
if(!istype(add_item_select, /obj/item/))
break
var/obj/item/add_item = add_item_select
robot.module.emag.Remove(add_item)
robot.module.modules.Remove(add_item)
robot.module.contents.Remove(add_item)
target.module.modules.Add(add_item)
target.module.contents.Add(add_item)
spawn(0) Must be after to allow the movement to finish
SEND_SIGNAL(add_item, COMSIG_OBSERVER_MOVED)
target.hud_used.update_robot_modules_display()
to_chat(usr, span_danger("You added \"[add_item]\" to [target]."))
if(istype(add_item, /obj/item/stack/))
var/obj/item/stack/item_with_synth = add_item
for(var/synth in item_with_synth.synths)
var/found = target.module.synths.Find(synth)
if(!found)
robot.module.synths.Remove(synth)
target.module.synths.Add(synth)
else
item_with_synth.synths = list(target.module.synths[found])
continue
if(istype(add_item, /obj/item/matter_decompiler/) || istype(add_item, /obj/item/dogborg/sleeper/compactor/decompiler/))
var/obj/item/matter_decompiler/item_with_matter = add_item
if(item_with_matter.metal)
var/found = target.module.synths.Find(item_with_matter.metal)
if(!found)
robot.module.synths.Remove(item_with_matter.metal)
target.module.synths.Add(item_with_matter.metal)
else
item_with_matter.metal = target.module.synths[found]
if(item_with_matter.glass)
var/found = target.module.synths.Find(item_with_matter.glass)
if(!found)
robot.module.synths.Remove(item_with_matter.glass)
target.module.synths.Add(item_with_matter.glass)
else
item_with_matter.glass = target.module.synths[found]
if(item_with_matter.wood)
var/found = target.module.synths.Find(item_with_matter.wood)
if(!found)
robot.module.synths.Remove(item_with_matter.wood)
target.module.synths.Add(item_with_matter.wood)
else
item_with_matter.wood = target.module.synths[found]
if(item_with_matter.plastic)
var/found = target.module.synths.Find(item_with_matter.plastic)
if(!found)
robot.module.synths.Remove(item_with_matter.plastic)
target.module.synths.Add(item_with_matter.plastic)
else
item_with_matter.plastic = target.module.synths[found]
qdel(robot)
if(MODIFIY_ROBOT_MODULE_REMOVE)
while(TRUE)
var/list/active_modules = target.module.modules
var/selected_module_module = tgui_input_list(usr, "Please select the module to remove", "Modules", active_modules)
if(!istype(selected_module_module, /obj/item/))
break
to_chat(usr, span_danger("You removed \"[selected_module_module]\" from [target]"))
target.uneq_all()
target.hud_used.update_robot_modules_display(TRUE)
target.module.emag.Remove(selected_module_module)
target.module.modules.Remove(selected_module_module)
target.module.contents.Remove(selected_module_module)
qdel(selected_module_module)
if(MODIFIY_ROBOT_APPLY_UPGRADE)
var/list/upgrades = list()
for(var/datum/design/item/prosfab/robot_upgrade/upgrade)
if(!(target.has_upgrade(initial(upgrade.build_path))))
upgrades[initial(upgrade.name)] = initial(upgrade.build_path)
while(TRUE)
var/selected_module_upgrade = tgui_input_list(usr, "Please select the module to remove", "Upgrades", upgrades)
if(!selected_module_upgrade || selected_module_upgrade == "Cancel")
break
if(selected_module_upgrade == "Reset Module")
if(tgui_alert(usr, "Are you sure that you want to install [selected_module_upgrade] and reset the robot's module?","Confirm",list("Yes","No"))!="Yes")
continue
var/new_upgrade = upgrades[capitalize(selected_module_upgrade)]
upgrades.Remove(selected_module_upgrade)
var/obj/item/borg/upgrade/U = new new_upgrade(src)
if(selected_module_upgrade == "Rename Module")
var/obj/item/borg/upgrade/utility/rename/UN = U
var/new_name = sanitizeSafe(tgui_input_text(usr, "Enter new robot name", "Robot Reclassification", UN.heldname, MAX_NAME_LEN), MAX_NAME_LEN)
if(new_name)
UN.heldname = new_name
U = UN
if(istype(U, /obj/item/borg/upgrade/restricted))
target.module.supported_upgrades |= new_upgrade
if(U.action(target))
to_chat(usr, span_danger("You apply the [U] to [target]!"))
usr.drop_item()
U.loc = target
target.hud_used.update_robot_modules_display()
else
to_chat(usr, span_danger("Upgrade error!"))
if(selected_module_upgrade == "Proto-Kinetic Accelerator")
var/list/modkits = list()
for(var/modkit in typesof(/obj/item/borg/upgrade/modkit))
var/obj/item/borg/upgrade/modkit/single_modkit = modkit
modkits["[initial(single_modkit.name)] [initial(single_modkit.cost)]"] = modkit
modkits.Remove("kinetic accelerator modification kit 30")
var/capacity = 100
while(TRUE)
var/selected_ka_upgrade = tgui_input_list(usr, "Do you want to install upgrades? Remaining capacity: [capacity]", "KA Upgrades", modkits)
if(!selected_ka_upgrade || selected_ka_upgrade == "Cancel")
break
var/new_modkit = modkits[selected_ka_upgrade]
var/obj/item/borg/upgrade/modkit/M = new new_modkit(src)
var/obj/item/gun/energy/kinetic_accelerator/kin = locate() in target.module.modules
if(kin.get_remaining_mod_capacity() >= M.cost)
to_chat(usr, span_danger("You installed the [M] into the [kin], [capacity]% remaining!"))
modkits.Remove(selected_ka_upgrade)
M.install(kin, target)
capacity = kin.get_remaining_mod_capacity()
if(MODIFIY_ROBOT_SUPP_ADD)
var/list/whitelisted_upgrades = list()
for(var/datum/design/item/prosfab/robot_upgrade/restricted/upgrade)
if(!(initial(upgrade.build_path) in target.module.supported_upgrades))
whitelisted_upgrades[initial(upgrade.name)] = initial(upgrade.build_path)
while(TRUE)
var/selected_upgrade_type = tgui_input_list(usr, "Please select which upgrade you want this module to support", "Upgrades", whitelisted_upgrades)
if(!selected_upgrade_type || selected_upgrade_type == "Cancel")
break
var/upgrade_path = whitelisted_upgrades[capitalize(selected_upgrade_type)]
whitelisted_upgrades.Remove(selected_upgrade_type)
target.module.supported_upgrades |= upgrade_path
if(MODIFIY_ROBOT_SUPP_REMOVE)
var/list/whitelisted_upgrades = list()
for(var/datum/design/item/prosfab/robot_upgrade/restricted/upgrade)
if((initial(upgrade.build_path) in target.module.supported_upgrades))
whitelisted_upgrades[initial(upgrade.name)] = initial(upgrade.build_path)
while(TRUE)
var/selected_upgrade_type = tgui_input_list(usr, "Please select which upgrade you want this module to support", "Upgrades", whitelisted_upgrades)
if(!selected_upgrade_type || selected_upgrade_type == "Cancel")
break
var/upgrade_path = whitelisted_upgrades[capitalize(selected_upgrade_type)]
whitelisted_upgrades.Remove(selected_upgrade_type)
target.module.supported_upgrades -= upgrade_path
if(MODIFIY_ROBOT_RADIOC_ADD)
var/list/available_channels = radiochannels.Copy()
for(var/has_channel in target.radio.channels)
available_channels -= has_channel
while(TRUE)
var/selected_radio_channel = tgui_input_list(usr, "Please select the radio channel to add", "Channels", available_channels)
if(!selected_radio_channel || selected_radio_channel == "Cancel")
break
if(selected_radio_channel == CHANNEL_SPECIAL_OPS || selected_radio_channel == CHANNEL_RESPONSE_TEAM)
target.radio.centComm = 1
if(selected_radio_channel == CHANNEL_RAIDER)
qdel(target.radio.keyslot)
target.radio.keyslot = new /obj/item/encryptionkey/raider(target)
target.radio.syndie = 1
if(selected_radio_channel == CHANNEL_MERCENARY)
qdel(target.radio.keyslot)
target.radio.keyslot = new /obj/item/encryptionkey/syndicate(target)
target.radio.syndie = 1
target.module.channels += list("[selected_radio_channel]" = 1)
target.radio.channels[selected_radio_channel] = target.module.channels[selected_radio_channel]
target.radio.secure_radio_connections[selected_radio_channel] = radio_controller.add_object(target.radio, radiochannels[selected_radio_channel], RADIO_CHAT)
available_channels -= selected_radio_channel
to_chat(usr, span_danger("You added \"[selected_radio_channel]\" channel to [target]."))
if(MODIFIY_ROBOT_RADIOC_REMOVE)
while(TRUE)
var/selected_radio_channel = tgui_input_list(usr, "Please select the radio channel to remove", "Channels", target.radio.channels)
if(!selected_radio_channel || selected_radio_channel == "Cancel")
break
if(selected_radio_channel == CHANNEL_SPECIAL_OPS || selected_radio_channel == CHANNEL_RESPONSE_TEAM && !(target.module.channels[CHANNEL_SPECIAL_OPS] || target.module.channels[CHANNEL_RESPONSE_TEAM]))
target.radio.centComm = 0
target.module.channels -= selected_radio_channel
if((selected_radio_channel == CHANNEL_MERCENARY || selected_radio_channel == CHANNEL_RAIDER) && !(target.module.channels[CHANNEL_RAIDER] || target.module.channels[CHANNEL_MERCENARY]))
qdel(target.radio.keyslot)
target.radio.keyslot = null
target.radio.syndie = 0
target.radio.channels = list()
for(var/n_chan in target.module.channels)
target.radio.channels[n_chan] = target.module.channels[n_chan]
radio_controller.remove_object(target.radio, radiochannels[selected_radio_channel])
target.radio.secure_radio_connections -= selected_radio_channel
to_chat(usr, span_danger("You removed \"[selected_radio_channel]\" channel from [target]."))
if(MODIFIY_ROBOT_COMP_ADD)
while(TRUE)
var/selected_component = tgui_input_list(usr, "Please select the component to add or replace", "Component", target.components)
if(!selected_component || selected_component == "Cancel")
break
var/datum/robot_component/C = target.components[selected_component]
if(C.wrapped && selected_component != "power cell")
qdel(C.wrapped)
switch(selected_component)
if("actuator")
C.wrapped = new /obj/item/robot_parts/robot_component/actuator(target)
if("radio")
C.wrapped = new /obj/item/robot_parts/robot_component/radio(target)
if("power cell")
var/list/recommended_cells = list(/obj/item/cell/robot_station, /obj/item/cell/high, /obj/item/cell/super, /obj/item/cell/robot_syndi, /obj/item/cell/hyper,
/obj/item/cell/infinite, /obj/item/cell/potato, /obj/item/cell/slime)
var/list/cell_names = list()
for(var/cell_type in recommended_cells)
var/obj/item/cell/single_cell = cell_type
cell_names[capitalize(initial(single_cell.name))] = cell_type
var/selected_cell = tgui_input_list(usr, "What kind of cell do you want to install?", "Cells", cell_names)
if(!selected_cell || selected_cell == "Cancel")
continue
qdel(C.wrapped)
var/new_power_cell = cell_names[capitalize(selected_cell)]
target.cell = new new_power_cell(target)
C.wrapped = target.cell
to_chat(usr, span_danger("You replaced \"[C]\" on [target] with \"[selected_cell]\"."))
if("diagnosis unit")
C.wrapped = new /obj/item/robot_parts/robot_component/diagnosis_unit(target)
if("camera")
C.wrapped = new /obj/item/robot_parts/robot_component/camera(target)
if("comms")
C.wrapped = new /obj/item/robot_parts/robot_component/binary_communication_device(target)
if("armour")
C.wrapped = new /obj/item/robot_parts/robot_component/armour(target)
C.install()
C.installed = 1
if(selected_component != "power cell")
to_chat(usr, span_danger("You repplaced \"[C]\" on [target]."))
if(MODIFIY_ROBOT_COMP_REMOVE)
while(TRUE)
var/selected_component = tgui_input_list(usr, "Please select the component to remove", "Component", target.components)
if(!selected_component || selected_component == "Cancel")
break
var/datum/robot_component/C = target.components[selected_component]
if(C.wrapped)
C.uninstall()
C.installed = 0
qdel(C.wrapped)
C.wrapped = null
if(selected_component == "power cell")
target.cell = null
to_chat(usr, span_danger("You removed \"[C]\" from [target]"))
if(MODIFIY_ROBOT_SWAP_MODULE)
var/selected_module = tgui_input_list(usr, "Which Module would you like to use?", "Module", robot_modules)
if(!selected_module || selected_module == "Cancel")
continue
if(!(selected_module in robot_modules))
continue
target.uneq_all()
target.hud_used.update_robot_modules_display(TRUE)
target.modtype = initial(target.modtype)
target.module.Reset(target)
qdel(target.module)
target.modtype = selected_module
var/module_type = robot_modules[selected_module]
target.transform_with_anim()
new module_type(target)
target.hands.icon_state = target.get_hud_module_icon()
target.hud_used.update_robot_modules_display()
if(MODIFIY_ROBOT_RESET_MODULE)
if(tgui_alert(usr, "Are you sure that you want to reset the entire module?","Confirm",list("Yes","No"))!="Yes")
continue
target.module_reset(FALSE)
to_chat(usr, span_danger("You resetted [target]'s module selection."))
if(MODIFIY_ROBOT_TOGGLE_ERT)
target.crisis_override = !target.crisis_override
to_chat(usr, span_danger("You [target.crisis_override? "enabled":"disabled"] [target]'s combat module overwrite."))
if(tgui_alert(usr, "Do you want to reset the module as well to allow selection?","Confirm",list("Yes","No"))!="Yes")
continue
target.module_reset(FALSE)
if(MODIFIY_ROBOT_TOGGLE_STATION_ACCESS)
if(target?.idcard?.GetAccess())
var/obj/item/card/id/synthetic/card = target.idcard
if(access_synth in card.GetAccess())
card.access -= get_all_station_access()
card.access -= access_synth
to_chat(usr, span_danger("You revoke station access from [target]."))
else
card.access |= get_all_station_access()
card.access |= access_synth
to_chat(usr, span_danger("You grant station access to [target]."))
if(MODIFIY_ROBOT_TOGGLE_CENT_ACCESS)
if(target?.idcard?.GetAccess())
var/obj/item/card/id/synthetic/card = target.idcard
if(access_cent_specops in card.GetAccess())
card.access -= get_all_centcom_access()
to_chat(usr, span_danger("You revoke central access from [target]."))
else
card.access |= get_all_centcom_access()
to_chat(usr, span_danger("You grant central access to [target]."))
@@ -0,0 +1,67 @@
// Representative icons for each research design
/datum/asset/spritesheet_batched/research_designs
name = "design"
/datum/asset/spritesheet_batched/research_designs/create_spritesheets()
for (var/datum/design_techweb/path as anything in subtypesof(/datum/design_techweb))
if(initial(path.id) == DESIGN_ID_IGNORE)
continue
var/icon_file
var/icon_state
var/datum/icon_transformer/transform = null
if(initial(path.research_icon) && initial(path.research_icon_state)) //If the design has an icon replacement skip the rest
icon_file = path::research_icon
icon_state = path::research_icon_state
// if (PERFORM_ALL_TESTS(focus_only/invalid_research_designs))
// if(!icon_exists(icon_file, icon_state))
// stack_trace("design [path] with icon '[icon_file]' missing state '[icon_state]'")
// continue
else
// construct the icon and slap it into the resource cache
var/atom/item = initial(path.build_path)
if (!ispath(item, /atom))
// biogenerator reagent designs display their default container
// if(initial(path.make_reagent))
// var/datum/reagent/reagent = initial(path.make_reagent)
// item = initial(reagent.default_container)
// else
continue // shouldn't happen, but just in case
// circuit boards become their resulting machines or computers
if (ispath(item, /obj/item/circuitboard))
var/obj/item/circuitboard/C = item
var/machine = initial(C.build_path)
if (machine)
item = machine
// GAGS icon short-circuit the rest of the checks
// if (item::greyscale_config && item::greyscale_colors)
// insert_icon(path::id, gags_to_universal_icon(item))
// continue
// else
icon_file = item::icon
icon_state = item::icon_state
if(item::color)
transform = color_transform(item::color)
// if (PERFORM_ALL_TESTS(focus_only/invalid_research_designs))
// if(!icon_exists(icon_file, icon_state))
// stack_trace("design [path] with icon '[icon_file]' missing state '[icon_state]'")
// continue
// computers (and snowflakes) get their screen and keyboard sprites
if (ispath(item, /obj/machinery/computer) || ispath(item, /obj/machinery/power/solar_control))
if(!transform)
transform = new()
var/obj/machinery/computer/C = item
var/screen = initial(C.icon_screen)
var/keyboard = initial(C.icon_keyboard)
var/all_states = icon_states(icon_file)
if (screen && (screen in all_states))
transform.blend_icon(uni_icon(icon_file, screen), ICON_OVERLAY)
if (keyboard && (keyboard in all_states))
transform.blend_icon(uni_icon(icon_file, keyboard), ICON_OVERLAY)
insert_icon(initial(path.id), uni_icon(icon_file, icon_state, transform=transform))
@@ -1,501 +0,0 @@
/*
* Contains
* /obj/item/rig_module/ai_container
* /obj/item/rig_module/datajack
* /obj/item/rig_module/power_sink
* /obj/item/rig_module/electrowarfare_suite
*/
/obj/item/ai_verbs
name = "AI verb holder"
/obj/item/ai_verbs/verb/hardsuit_interface()
set category = "Hardsuit"
set name = "Open Hardsuit Interface"
set src in usr
if(!usr.loc || !usr.loc.loc || !istype(usr.loc.loc, /obj/item/rig_module))
to_chat(usr, "You are not loaded into a hardsuit.")
return
var/obj/item/rig_module/module = usr.loc.loc
if(!module.holder)
to_chat(usr, "Your module is not installed in a hardsuit.")
return
module.holder.tgui_interact(usr, custom_state = GLOB.tgui_contained_state)
/obj/item/rig_module/ai_container
name = "IIS module"
desc = "An integrated intelligence system module suitable for most hardsuits."
icon_state = "IIS"
toggleable = 1
usable = 1
disruptive = 0
activates_on_touch = 1
engage_string = "Eject AI"
activate_string = "Enable Core Transfer"
deactivate_string = "Disable Core Transfer"
interface_name = "integrated intelligence system"
interface_desc = "A socket that supports a range of artificial intelligence systems."
var/mob/integrated_ai // Direct reference to the actual mob held in the suit.
var/obj/item/ai_card // Reference to the MMI, posibrain, intellicard or pAI card previously holding the AI.
var/obj/item/ai_verbs/verb_holder
/obj/item/rig_module/ai_container/process()
if(integrated_ai)
var/obj/item/rig/rig = get_rig()
if(rig && rig.ai_override_enabled)
integrated_ai.get_rig_stats = 1
else
integrated_ai.get_rig_stats = 0
/mob/living/Stat()
. = ..()
if(. && get_rig_stats)
var/obj/item/rig/rig = get_rig()
if(rig)
SetupStat(rig)
/obj/item/rig_module/ai_container/proc/update_verb_holder()
if(!verb_holder)
verb_holder = new(src)
if(integrated_ai)
verb_holder.forceMove(integrated_ai)
else
verb_holder.forceMove(src)
/obj/item/rig_module/ai_container/accepts_item(var/obj/item/input_device, var/mob/living/user)
// Check if there's actually an AI to deal with.
var/mob/living/silicon/ai/target_ai
if(isAI(input_device))
target_ai = input_device
else
target_ai = locate(/mob/living/silicon/ai) in input_device.contents
var/obj/item/aicard/card = ai_card
// Downloading from/loading to a terminal.
if(istype(input_device,/obj/machinery/computer/aifixer) || istype(input_device,/mob/living/silicon/ai) || istype(input_device,/obj/structure/AIcore/deactivated))
// If we're stealing an AI, make sure we have a card for it.
if(!card)
card = new /obj/item/aicard(src)
// Terminal interaction only works with an intellicarded AI.
if(!istype(card))
return 0
// Since we've explicitly checked for three types, this should be safe.
input_device.attackby(card,user)
// If the transfer failed we can delete the card.
if(locate(/mob/living/silicon/ai) in card)
ai_card = card
integrated_ai = locate(/mob/living/silicon/ai) in card
else
eject_ai()
update_verb_holder()
return 1
if(istype(input_device,/obj/item/aicard))
// We are carding the AI in our suit.
if(integrated_ai)
integrated_ai.attackby(input_device,user)
// If the transfer was successful, we can clear out our vars.
if(integrated_ai.loc != src)
integrated_ai = null
eject_ai()
else
// You're using an empty card on an empty suit, idiot.
if(!target_ai)
return 0
integrate_ai(input_device,user)
return 1
// Okay, it wasn't a terminal being touched, check for all the simple insertions.
if(input_device.type in list(/obj/item/paicard, /obj/item/mmi, /obj/item/mmi/digital/posibrain))
if(integrated_ai)
integrated_ai.attackby(input_device,user)
// If the transfer was successful, we can clear out our vars.
if(integrated_ai.loc != src)
integrated_ai = null
eject_ai()
else
integrate_ai(input_device,user)
return 1
return 0
/obj/item/rig_module/ai_container/engage(atom/target)
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!target)
if(ai_card)
if(istype(ai_card,/obj/item/aicard))
ai_card.ui_interact(H, state = deep_inventory_state)
else
eject_ai(H)
update_verb_holder()
return 1
if(accepts_item(target,H))
return 1
return 0
/obj/item/rig_module/ai_container/removed()
eject_ai()
..()
/obj/item/rig_module/ai_container/proc/eject_ai(var/mob/user)
if(ai_card)
if(istype(ai_card, /obj/item/aicard))
if(integrated_ai && !integrated_ai.stat)
if(user)
to_chat(user, span_danger("You cannot eject your currently stored AI. Purge it manually."))
return 0
to_chat(user, span_danger("You purge the previous AI from your Integrated Intelligence System, freeing it for use."))
if(integrated_ai)
integrated_ai.ghostize()
qdel(integrated_ai)
integrated_ai = null
if(ai_card)
qdel(ai_card)
ai_card = null
else if(user)
user.put_in_hands(ai_card)
else
ai_card.forceMove(get_turf(src))
ai_card = null
integrated_ai = null
update_verb_holder()
/obj/item/rig_module/ai_container/proc/integrate_ai(var/obj/item/ai,var/mob/user)
if(!ai) return
// The ONLY THING all the different AI systems have in common is that they all store the mob inside an item.
var/mob/living/ai_mob = locate(/mob/living) in ai.contents
if(ai_mob)
if(ai_mob.key && ai_mob.client)
if(istype(ai, /obj/item/aicard))
if(!ai_card)
ai_card = new /obj/item/aicard(src)
var/obj/item/aicard/source_card = ai
var/obj/item/aicard/target_card = ai_card
if(istype(source_card) && istype(target_card))
if(target_card.grab_ai(ai_mob, user))
source_card.clear()
else
return 0
else
return 0
else
user.drop_from_inventory(ai)
ai.forceMove(src)
ai_card = ai
to_chat(ai_mob, span_blue("You have been transferred to \the [holder]'s [src]."))
to_chat(user, span_blue("You load [ai_mob] into \the [holder]'s [src]."))
integrated_ai = ai_mob
if(!(locate(integrated_ai) in ai_card))
integrated_ai = null
eject_ai()
else
to_chat(user, span_warning("There is no active AI within \the [ai]."))
else
to_chat(user, span_warning("There is no active AI within \the [ai]."))
update_verb_holder()
return
/obj/item/rig_module/datajack
name = "datajack module"
desc = "A simple induction datalink module."
icon_state = "datajack"
toggleable = 1
activates_on_touch = 1
usable = 0
activate_string = "Enable Datajack"
deactivate_string = "Disable Datajack"
interface_name = "contact datajack"
interface_desc = "An induction-powered high-throughput datalink suitable for hacking encrypted networks."
var/list/stored_research = list()
/obj/item/rig_module/datajack/engage(atom/target)
if(!..())
return 0
if(target)
var/mob/living/carbon/human/H = holder.wearer
if(!accepts_item(target,H))
return 0
return 1
/obj/item/rig_module/datajack/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(istype(input_device,/obj/item/disk/tech_disk))
to_chat(user, "You slot the disk into [src].")
var/obj/item/disk/tech_disk/disk = input_device
if(disk.stored)
if(load_data(disk.stored))
to_chat(user, span_blue"Download successful; disk erased."))
disk.stored = null
else
to_chat(user, span_warning("The disk is corrupt. It is useless to you."))
else
to_chat(user, span_warning("The disk is blank. It is useless to you."))
return 1
// I fucking hate R&D code. This typecheck spam would be totally unnecessary in a sane setup.
else if(istype(input_device,/obj/machinery))
var/datum/research/incoming_files
if(istype(input_device,/obj/machinery/computer/rdconsole))
var/obj/machinery/computer/rdconsole/input_machine = input_device
incoming_files = input_machine.files
else if(istype(input_device,/obj/machinery/r_n_d/server))
var/obj/machinery/r_n_d/server/input_machine = input_device
incoming_files = input_machine.files
else if(istype(input_device,/obj/machinery/mecha_part_fabricator))
var/obj/machinery/mecha_part_fabricator/input_machine = input_device
incoming_files = input_machine.files
if(!incoming_files || !incoming_files.known_tech || !incoming_files.known_tech.len)
to_chat(user, span_warning("Memory failure. There is nothing accessible stored on this terminal."))
else
// Maybe consider a way to drop all your data into a target repo in the future.
if(load_data(incoming_files.known_tech))
to_chat(user, span_blue("Download successful; local and remote repositories synchronized."))
else
to_chat(user, span_warning("Scan complete. There is nothing useful stored on this terminal."))
return 1
return 0
/obj/item/rig_module/datajack/proc/load_data(var/incoming_data)
if(islist(incoming_data))
for(var/entry in incoming_data)
load_data(entry)
return 1
if(istype(incoming_data, /datum/tech))
var/data_found
var/datum/tech/new_data = incoming_data
for(var/datum/tech/current_data in stored_research)
if(current_data.id == new_data.id)
data_found = 1
if(current_data.level < new_data.level)
current_data.level = new_data.level
break
if(!data_found)
stored_research += incoming_data
return 1
return 0
/obj/item/rig_module/electrowarfare_suite
name = "electrowarfare module"
desc = "A bewilderingly complex bundle of fiber optics and chips."
icon_state = "ewar"
toggleable = 1
usable = 0
activate_string = "Enable Countermeasures"
deactivate_string = "Disable Countermeasures"
interface_name = "electrowarfare system"
interface_desc = "An active counter-electronic warfare suite that disrupts AI tracking."
/obj/item/rig_module/electrowarfare_suite/activate()
if(!..())
return
// This is not the best way to handle this, but I don't want it to mess with ling camo
var/mob/living/M = holder.wearer
M.digitalcamo++
/obj/item/rig_module/electrowarfare_suite/deactivate()
if(!..())
return
var/mob/living/M = holder.wearer
M.digitalcamo = max(0,(M.digitalcamo-1))
/obj/item/rig_module/power_sink
name = "hardsuit power sink"
desc = "An heavy-duty power sink."
icon_state = "powersink"
toggleable = 1
activates_on_touch = 1
disruptive = 0
activate_string = "Enable Power Sink"
deactivate_string = "Disable Power Sink"
interface_name = "niling d-sink"
interface_desc = "Colloquially known as a power siphon, this module drains power through the suit hands into the suit battery."
var/atom/interfaced_with // Currently draining power from this device.
var/total_power_drained = 0
var/drain_loc
/obj/item/rig_module/power_sink/deactivate()
if(interfaced_with)
if(holder && holder.wearer)
to_chat(holder.wearer, span_warning("Your power sink retracts as the module deactivates."))
drain_complete()
interfaced_with = null
total_power_drained = 0
return ..()
/obj/item/rig_module/power_sink/activate()
interfaced_with = null
total_power_drained = 0
return ..()
/obj/item/rig_module/power_sink/engage(atom/target)
if(!..())
return 0
//Target wasn't supplied or we're already draining.
if(interfaced_with)
return 0
if(!target)
return 1
// Are we close enough?
var/mob/living/carbon/human/H = holder.wearer
if(!target.Adjacent(H))
return 0
// Is it a valid power source?
if(target.drain_power(1) <= 0)
return 0
to_chat(H, span_danger("You begin draining power from [target]!"))
interfaced_with = target
drain_loc = interfaced_with.loc
holder.spark_system.start()
playsound(H, 'sound/effects/sparks2.ogg', 50, 1)
return 1
/obj/item/rig_module/power_sink/accepts_item(var/obj/item/input_device, var/mob/living/user)
var/can_drain = input_device.drain_power(1)
if(can_drain > 0)
engage(input_device)
return 1
return 0
/obj/item/rig_module/power_sink/process()
if(!interfaced_with)
return ..()
var/mob/living/carbon/human/H
if(holder && holder.wearer)
H = holder.wearer
if(!H || !istype(H))
return 0
holder.spark_system.start()
playsound(H, 'sound/effects/sparks2.ogg', 50, 1)
H.break_cloak()
if(!holder.cell)
to_chat(H, span_danger("Your power sink flashes an error; there is no cell in your rig."))
drain_complete(H)
return
if(!interfaced_with || !interfaced_with.Adjacent(H) || !(interfaced_with.loc == drain_loc))
to_chat(H, span_warning("Your power sink retracts into its casing."))
drain_complete(H)
return
if(holder.cell.fully_charged())
to_chat(H, span_warning("Your power sink flashes an amber light; your rig cell is full."))
drain_complete(H)
return
// Attempts to drain up to 12.5*cell-capacity kW, determines this value from remaining cell capacity to ensure we don't drain too much.
// 1Ws/(12.5*CELLRATE) = 40s to charge
var/to_drain = min(12.5*holder.cell.maxcharge, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE))
var/target_drained = interfaced_with.drain_power(0,0,to_drain)
if(target_drained <= 0)
to_chat(H, span_danger("Your power sink flashes a red light; there is no power left in [interfaced_with]."))
drain_complete(H)
return
holder.cell.give(target_drained * CELLRATE)
total_power_drained += target_drained
return
/obj/item/rig_module/power_sink/proc/drain_complete(var/mob/living/M)
if(!interfaced_with)
if(M)
to_chat(M, span_notice(span_bold("Total power drained:") + " [round(total_power_drained*CELLRATE)] cell units."))
else
if(M)
to_chat(M, span_notice(span_bold("Total power drained from [interfaced_with]:") + " [round(total_power_drained*CELLRATE)] cell units."))
interfaced_with.drain_power(0,1,0) // Damage the victim.
drain_loc = null
interfaced_with = null
total_power_drained = 0
/*
//Maybe make this use power when active or something
/obj/item/rig_module/emp_shielding
name = "\improper EMP dissipation module"
desc = "A bewilderingly complex bundle of fiber optics and chips."
toggleable = 1
usable = 0
activate_string = "Enable active EMP shielding"
deactivate_string = "Disable active EMP shielding"
interface_name = "active EMP shielding system"
interface_desc = "A highly experimental system that augments the hardsuit's existing EM shielding."
var/protection_amount = 20
/obj/item/rig_module/emp_shielding/activate()
if(!..())
return
holder.emp_protection += protection_amount
/obj/item/rig_module/emp_shielding/deactivate()
if(!..())
return
holder.emp_protection = max(0,(holder.emp_protection - protection_amount))
*/
@@ -136,7 +136,7 @@
stat_modules += new/atom/movable/stat_rig_module/charge(src)
/obj/item/rig_module/Destroy()
holder.installed_modules -= src
holder?.installed_modules -= src
holder = null
QDEL_NULL_LIST(stat_modules)
. = ..()
@@ -3,7 +3,7 @@
name = "mounted space cleaner launcher"
desc = "A shoulder-mounted micro-cleaner dispenser."
selectable = 1
icon_state = "grenade_launcher"
icon_state = "grenadelauncher"
interface_name = "integrated cleaner launcher"
interface_desc = "Discharges loaded cleaner grenades against the wearer's location."
@@ -31,37 +31,37 @@
/obj/item/rig_module/datajack/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(istype(input_device,/obj/item/disk/tech_disk))
to_chat(user, "You slot the disk into [src].")
var/obj/item/disk/tech_disk/disk = input_device
if(disk.stored)
if(load_data(disk.stored))
to_chat(user, span_blue("Download successful; disk erased."))
disk.stored = null
else
to_chat(user, span_warning("The disk is corrupt. It is useless to you."))
else
to_chat(user, span_warning("The disk is blank. It is useless to you."))
return 1
// if(istype(input_device,/obj/item/disk/tech_disk))
// to_chat(user, "You slot the disk into [src].")
// var/obj/item/disk/tech_disk/disk = input_device
// if(disk.stored)
// if(load_data(disk.stored))
// to_chat(user, span_blue("Download successful; disk erased."))
// disk.stored = null
// else
// to_chat(user, span_warning("The disk is corrupt. It is useless to you."))
// else
// to_chat(user, span_warning("The disk is blank. It is useless to you."))
// return 1
// I fucking hate R&D code. This typecheck spam would be totally unnecessary in a sane setup. Sanity? This is BYOND.
else if(istype(input_device,/obj/machinery))
var/datum/research/incoming_files
if(istype(input_device,/obj/machinery/computer/rdconsole) ||\
istype(input_device,/obj/machinery/r_n_d/server) ||\
istype(input_device,/obj/machinery/mecha_part_fabricator))
// else if(istype(input_device,/obj/machinery))
// var/datum/research/incoming_files
// if(istype(input_device,/obj/machinery/computer/rdconsole) ||
// istype(input_device,/obj/machinery/r_n_d/server) ||
// istype(input_device,/obj/machinery/mecha_part_fabricator))
incoming_files = input_device:files
// incoming_files = input_device:files
if(!incoming_files || !incoming_files.known_tech || !incoming_files.known_tech.len)
to_chat(user, span_warning("Memory failure. There is nothing accessible stored on this terminal."))
else
// Maybe consider a way to drop all your data into a target repo in the future.
if(load_data(incoming_files.known_tech))
to_chat(user, span_blue("Download successful; local and remote repositories synchronized."))
else
to_chat(user, span_warning("Scan complete. There is nothing useful stored on this terminal."))
return 1
// if(!incoming_files || !incoming_files.known_tech || !incoming_files.known_tech.len)
// to_chat(user, span_warning("Memory failure. There is nothing accessible stored on this terminal."))
// else
// // Maybe consider a way to drop all your data into a target repo in the future.
// if(load_data(incoming_files.known_tech))
// to_chat(user, span_blue("Download successful; local and remote repositories synchronized."))
// else
// to_chat(user, span_warning("Scan complete. There is nothing useful stored on this terminal."))
// return 1
return 0
/obj/item/rig_module/datajack/proc/load_data(var/incoming_data)
@@ -71,16 +71,16 @@
load_data(entry)
return 1
if(istype(incoming_data, /datum/tech))
var/data_found
var/datum/tech/new_data = incoming_data
for(var/datum/tech/current_data in stored_research)
if(current_data.id == new_data.id)
data_found = 1
if(current_data.level < new_data.level)
current_data.level = new_data.level
break
if(!data_found)
stored_research += incoming_data
return 1
// if(istype(incoming_data, /datum/tech))
// var/data_found
// var/datum/tech/new_data = incoming_data
// for(var/datum/tech/current_data in stored_research)
// if(current_data.id == new_data.id)
// data_found = 1
// if(current_data.level < new_data.level)
// current_data.level = new_data.level
// break
// if(!data_found)
// stored_research += incoming_data
// return 1
return 0
@@ -121,7 +121,7 @@
name = "mop projector"
desc = "A powerful mop projector."
icon_state = "mop"
icon_state = "generic"
activate_string = "Project Mop"
deactivate_string = "Cancel Mop"
@@ -1,5 +1,5 @@
/obj/item/rig_module/mounted/sizegun
icon = 'icons/obj/rig_modules.dmi'
icon = 'icons/obj/rig_modules_vr.dmi'
icon_state = "sizegun"
name = "mounted size gun"
desc = "A size gun to be mounted on a rig suit. Features interface-based target size adjustment for hands-free size-altering shenanigans."
@@ -1,6 +1,8 @@
/obj/item/rig_module/rescue_pharm
name = "micro-pharmacy"
desc = "A small chemical dispenser with integrated micro cartridges."
icon = 'icons/obj/rig_modules.dmi'
icon_state = "generic"
usable = 0
selectable = 1
disruptive = 1
-11
View File
@@ -32,7 +32,6 @@
if(DEPARTMENT_MEDICAL)
choose_chemistry_items(roll(severity, 2))
if(DEPARTMENT_RESEARCH) // Would be nice to differentiate between research diciplines
choose_research_items(roll(severity, 2))
choose_robotics_items(roll(1, severity))
if(DEPARTMENT_CARGO)
choose_alloy_items(rand(1, severity))
@@ -261,16 +260,6 @@
required_items += new /datum/supply_demand_order/thing(chosen_qty, chosen_path)
return
/datum/event/supply_demand/proc/choose_research_items(var/differentTypes)
var/list/types = subtypesof(/datum/design)
for(var/i in 1 to differentTypes)
var/datum/design/D = pick(types)
types -= D // Don't pick the same thing twice
var/chosen_path = initial(D.build_path)
var/chosen_qty = rand(1, 3)
required_items += new /datum/supply_demand_order/thing(chosen_qty, chosen_path)
return
/datum/event/supply_demand/proc/choose_chemistry_items(var/differentTypes)
// Checking if they show up in health analyzer is good huristic for it being a drug
var/list/medicineReagents = list()
@@ -78,6 +78,22 @@ var/list/name_to_material
else
.[M] = matter[mat]
/obj/proc/set_custom_materials(list/materials, multiplier = 1)
SHOULD_NOT_OVERRIDE(TRUE)
if(!LAZYLEN(materials))
matter = null
return
materials = materials.Copy()
if(multiplier != 1)
for(var/x in materials)
materials[x] *= multiplier
matter = materials
// Builds the datum list above.
/proc/populate_material_list(force_remake=0)
if(name_to_material && !force_remake) return // Already set up!
+276
View File
@@ -0,0 +1,276 @@
/obj/machinery/ore_silo
name = "ore silo"
desc = "An all-in-one bluespace storage and transmission system for the station's mineral distribution needs."
icon = 'icons/obj/machines/ore_silo.dmi'
icon_state = "silo"
density = TRUE
circuit = /obj/item/circuitboard/machine/ore_silo
/// List of all connected components that are on hold from accessing materials.
var/list/holds = list()
/// List of all components that are sharing ores with this silo.
var/list/datum/component/remote_materials/ore_connected_machines = list()
/// Material Container
var/datum/component/material_container/materials
/obj/machinery/ore_silo/Initialize(mapload)
. = ..()
materials = AddComponent( \
/datum/component/material_container, \
subtypesof(/datum/material), \
INFINITY, \
MATCONTAINER_EXAMINE, \
container_signals = list( \
COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/ore_silo, on_item_consumed), \
COMSIG_MATCONTAINER_SHEETS_RETRIEVED = TYPE_PROC_REF(/obj/machinery/ore_silo, log_sheets_ejected), \
), \
allowed_items = /obj/item/stack \
)
if(!GLOB.ore_silo_default && mapload && (z in using_map.station_levels))
GLOB.ore_silo_default = src
// register_context()
/obj/machinery/ore_silo/Destroy()
if(GLOB.ore_silo_default == src)
GLOB.ore_silo_default = null
for(var/datum/component/remote_materials/mats as anything in ore_connected_machines)
mats.disconnect()
ore_connected_machines = null
materials = null
return ..()
/obj/machinery/ore_silo/examine(mob/user)
. = ..()
. += span_notice("It can be linked to techfabs, circuit printers and protolathes with a multitool.")
. += span_notice("Its maintainence panel can be [span_bold("screwed")] [panel_open ? "closed" : "open"].")
if(panel_open)
. += span_notice("The whole machine can be [span_bold("pried")] apart.")
/obj/machinery/ore_silo/proc/on_item_consumed(datum/component/material_container/container, obj/item/item_inserted, last_inserted_id, mats_consumed, amount_inserted, atom/context)
SIGNAL_HANDLER
silo_log(context, "deposited", amount_inserted, item_inserted.name, mats_consumed)
SEND_SIGNAL(context, COMSIG_SILO_ITEM_CONSUMED, container, item_inserted, last_inserted_id, mats_consumed, amount_inserted)
/obj/machinery/ore_silo/proc/log_sheets_ejected(datum/component/material_container/container, obj/item/stack/material/sheets, atom/context)
SIGNAL_HANDLER
silo_log(context, "ejected", -sheets.amount, "[sheets.singular_name]", list(sheets.material))
/obj/machinery/ore_silo/attackby(obj/item/W, mob/user, attack_modifier, click_parameters)
if(default_deconstruction_screwdriver(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
if(istype(W, /obj/item/multitool))
var/obj/item/multitool/M = W
M.buffer = src
balloon_alert(user, "saved to multitool buffer")
return
. = ..()
/obj/machinery/ore_silo/attack_hand(mob/user)
return tgui_interact(user)
/obj/machinery/ore_silo/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/sheetmaterials)
)
/obj/machinery/ore_silo/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "OreSilo")
ui.open()
/obj/machinery/ore_silo/tgui_static_data(mob/user)
return materials.tgui_static_data(user)
/obj/machinery/ore_silo/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
data["materials"] = materials.tgui_data(user)
data["machines"] = list()
for(var/datum/component/remote_materials/remote as anything in ore_connected_machines)
var/atom/parent = remote.parent
data["machines"] += list(
list(
"icon" = icon2base64(icon(initial(parent.icon), initial(parent.icon_state), frame = 1)),
"name" = parent.name,
"onHold" = !!holds[remote],
"location" = get_area_name(parent, TRUE),
)
)
data["logs"] = list()
for(var/datum/ore_silo_log/entry as anything in GLOB.silo_access_logs[REF(src)])
data["logs"] += list(
list(
"rawMaterials" = entry.get_raw_materials(""),
"machineName" = entry.machine_name,
"areaName" = entry.area_name,
"action" = entry.action,
"amount" = entry.amount,
"time" = entry.timestamp,
"noun" = entry.noun,
)
)
return data
/obj/machinery/ore_silo/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
. = ..()
if(.)
return
switch(action)
if("remove")
var/index = params["id"]
if(isnull(index))
return
index = text2num(index)
if(isnull(index))
return
var/datum/component/remote_materials/remote = ore_connected_machines[index]
if(isnull(remote))
return
remote.disconnect()
return TRUE
if("hold")
var/index = params["id"]
if(isnull(index))
return
index = text2num(index)
if(isnull(index))
return
var/datum/component/remote_materials/remote = ore_connected_machines[index]
if(isnull(remote))
return
remote.toggle_holding()
return TRUE
if("remove_mat")
var/datum/material/ejecting = GET_MATERIAL_REF(params["id"])
if(!istype(ejecting))
return
var/amount = params["amount"]
if(isnull(amount))
return
amount = text2num(amount)
if(isnull(amount))
return
materials.retrieve_sheets(amount, ejecting, drop_location())
return TRUE
/**
* Creates a log entry for depositing/withdrawing from the silo both ingame and in text based log
*
* Arguments:
* - [M][/obj/machinery]: The machine performing the action.
* - action: Text that visually describes the action (smelted/deposited/resupplied...)
* - amount: The amount of sheets/objects deposited/withdrawn by this action. Positive for depositing, negative for withdrawing.
* - noun: Name of the object the action was performed with (sheet, units, ore...)
* - [mats][list]: Assoc list in format (material datum = amount of raw materials). Wants the actual amount of raw (iron, glass...) materials involved in this action. If you have 10 metal sheets each worth 100 iron you would pass a list with the iron material datum = 1000
*/
/obj/machinery/ore_silo/proc/silo_log(obj/machinery/M, action, amount, noun, list/mats)
if (!length(mats))
return
var/datum/ore_silo_log/entry = new(M, action, amount, noun, mats)
var/list/datum/ore_silo_log/logs = GLOB.silo_access_logs[REF(src)]
if(!LAZYLEN(logs))
GLOB.silo_access_logs[REF(src)] = logs = list(entry)
else if(!logs[1].merge(entry))
logs.Insert(1, entry)
flick("silo_active", src)
///The log entry for an ore silo action
/datum/ore_silo_log
///The time of action
var/timestamp
///The name of the machine that remotely acted on the ore silo
var/machine_name
///The area of the machine that remotely acted on the ore silo
var/area_name
///The actual action performed by the machine
var/action
///An short verb describing the action
var/noun
///The amount of items affected by this action e.g. print quantity, sheets ejected etc.
var/amount
///List of individual materials used in the action
var/list/materials
/datum/ore_silo_log/New(obj/machinery/M, _action, _amount, _noun, list/mats=list())
timestamp = stationtime2text()
machine_name = M.name
area_name = get_area_name(M, TRUE)
action = _action
amount = _amount
noun = _noun
materials = mats.Copy()
// var/list/data = list(
// "machine_name" = machine_name,
// "area_name" = AREACOORD(M),
// "action" = action,
// "amount" = abs(amount),
// "noun" = noun,
// "raw_materials" = get_raw_materials(""),
// "direction" = amount < 0 ? "withdrawn" : "deposited",
// )
// logger.Log(
// LOG_CATEGORY_SILO,
// "[machine_name] in \[[AREACOORD(M)]\] [action] [abs(amount)]x [noun] | [get_raw_materials("")]",
// data,
// )
/**
* Merges a silo log entry with this one
* Arguments
*
* * datum/ore_silo_log/other - the other silo entry we are trying to merge with this one
*/
/datum/ore_silo_log/proc/merge(datum/ore_silo_log/other)
if (other == src || action != other.action || noun != other.noun)
return FALSE
if (machine_name != other.machine_name || area_name != other.area_name)
return FALSE
timestamp = other.timestamp
amount += other.amount
for(var/each in other.materials)
materials[each] += other.materials[each]
return TRUE
/**
* Returns list/materials but with each entry joined by an seperator to create 1 string
* Arguments
*
* * separator - the string used to concatenate all entries in list/materials
*/
/datum/ore_silo_log/proc/get_raw_materials(separator)
var/list/msg = list()
for(var/key in materials)
var/datum/material/M = key
var/val = round(materials[key])
msg += separator
separator = ", "
msg += "[amount < 0 ? "-" : "+"][val] [M.name]"
return msg.Join()
@@ -98,7 +98,7 @@
if(cell)
user.show_message("\t Power Cell Details: [span_blue("[capitalize(cell.name)]")] with a capacity of [cell.maxcharge] at [round(cell.percent())]% charge")
var/show_title = TRUE
for(var/datum/design/item/prosfab/robot_upgrade/utility/upgrade)
for(var/datum/design_techweb/prosfab/robot_upgrade/utility/upgrade in SSresearch.techweb_designs)
var/obj/item/borg/upgrade/utility/upgrade_type = initial(upgrade.build_path)
var/needs_module = initial(upgrade_type.require_module)
if((!R.module && needs_module) || !initial(upgrade.name) || (R.stat != DEAD && (upgrade_type == /obj/item/borg/upgrade/utility/restart)) || (isshell(R) && (upgrade_type == /obj/item/borg/upgrade/utility/rename)))
@@ -112,7 +112,7 @@
else
user.show_message(span_blue("\t\t [capitalize(initial(upgrade.name))]: [span_green("Usable")]"))
show_title = TRUE
for(var/datum/design/item/prosfab/robot_upgrade/basic/upgrade)
for(var/datum/design_techweb/prosfab/robot_upgrade/basic/upgrade in SSresearch.techweb_designs)
var/obj/item/borg/upgrade/basic/upgrade_type = initial(upgrade.build_path)
var/needs_module = initial(upgrade_type.require_module)
if((!R.module && needs_module) || !initial(upgrade.name) || R.stat == DEAD)
@@ -125,7 +125,7 @@
else
user.show_message(span_blue("\t\t [capitalize(initial(upgrade.name))]: [R.has_basic_upgrade(initial(upgrade.build_path)) ? span_green("Installed") : span_red("Missing")]"))
show_title = TRUE
for(var/datum/design/item/prosfab/robot_upgrade/advanced/upgrade)
for(var/datum/design_techweb/prosfab/robot_upgrade/advanced/upgrade in SSresearch.techweb_designs)
var/obj/item/borg/upgrade/advanced/upgrade_type = initial(upgrade.build_path)
var/needs_module = initial(upgrade_type.require_module)
if((!R.module && needs_module) || !initial(upgrade.name) || R.stat == DEAD)
@@ -138,7 +138,7 @@
else
user.show_message(span_blue("\t\t [capitalize(initial(upgrade.name))]: [R.has_advanced_upgrade(initial(upgrade.build_path)) ? span_green("Installed") : span_red("Missing")]"))
show_title = TRUE
for(var/datum/design/item/prosfab/robot_upgrade/restricted/upgrade)
for(var/datum/design_techweb/prosfab/robot_upgrade/restricted/upgrade in SSresearch.techweb_designs)
var/obj/item/borg/upgrade/restricted/upgrade_type = initial(upgrade.build_path)
var/needs_module = initial(upgrade_type.require_module)
if((!R.module && needs_module) || !initial(upgrade.name) || !R.supports_upgrade(initial(upgrade.build_path)) || R.stat == DEAD)
@@ -151,20 +151,6 @@
else
user.show_message(span_blue("\t\t [capitalize(initial(upgrade.name))]: [R.has_restricted_upgrade(initial(upgrade.build_path)) ? span_green("Installed") : span_red("Missing")]"))
show_title = TRUE
for(var/datum/design/item/prosfab/robot_upgrade/no_prod/upgrade)
var/obj/item/borg/upgrade/no_prod/upgrade_type = initial(upgrade.build_path)
var/needs_module = initial(upgrade_type.require_module)
var/hidden = initial(upgrade_type.hidden_from_scan)
if((!R.module && needs_module) || !initial(upgrade.name) || hidden || R.stat == DEAD)
continue
if(show_title)
user.show_message("\t Special Modules, used for recreation purposes:")
show_title = FALSE
if(R.has_no_prod_upgrade(initial(upgrade.build_path)) == "")
user.show_message(span_blue("\t\t [capitalize(initial(upgrade.name))]: [span_red(span_bold("ERROR"))]"))
else
user.show_message(span_blue("\t\t [capitalize(initial(upgrade.name))]: [R.has_no_prod_upgrade(initial(upgrade.build_path)) ? span_green("Installed") : span_red("Missing")]"))
if("prosthetics")
var/mob/living/carbon/human/H = M
@@ -27,7 +27,6 @@
var/list/deliveryslot_1 = list()
var/list/deliveryslot_2 = list()
var/list/deliveryslot_3 = list()
var/datum/research/techonly/files //Analyzerbelly var.
var/synced = FALSE
var/startdrain = 500
var/max_item_count = 1
@@ -47,7 +46,6 @@
/obj/item/dogborg/sleeper/Initialize(mapload)
. = ..()
files = new /datum/research/techonly(src)
med_analyzer = new /obj/item/healthanalyzer
/obj/item/dogborg/sleeper/Destroy()
@@ -92,12 +90,6 @@
target.forceMove(src)
user.visible_message(span_warning("[hound.name]'s [src.name] groans lightly as [target.name] slips inside."), span_notice("Your [src.name] groans lightly as [target] slips inside."))
playsound(src, gulpsound, vol = 60, vary = 1, falloff = 0.1, preference = /datum/preference/toggle/eating_noises)
if(analyzer && istype(target,/obj/item))
var/obj/item/tech_item = target
var/list/tech_levels = list()
for(var/T in tech_item.origin_tech)
tech_levels += "\The [tech_item] has level [tech_item.origin_tech[T]] in [CallTechName(T)]."
to_chat(user, span_notice("[jointext(tech_levels, "<br>")]"))
if(delivery)
if(islist(deliverylists[delivery_tag]))
deliverylists[delivery_tag] |= target
@@ -295,9 +287,6 @@
dat += span_red("Cargo compartment slot: Fuel.") + "<BR>"
dat += span_red("([jointext(contents - (deliveryslot_1 + deliveryslot_2 + deliveryslot_3),", ")])") + "<BR><BR>"
if(analyzer && !synced)
dat += "<A href='byond://?src=\ref[src];sync=1'>Sync Files</A><BR>"
//Cleaning and there are still un-preserved items
if(cleaning && length(contents - items_preserved))
dat += span_red(span_bold("Self-cleaning mode.") + " [length(contents - items_preserved)] object(s) remaining.") + "<BR>"
@@ -429,25 +418,6 @@
deliverylists[delivery_tag].Cut()
sleeperUI(usr)
return
if(href_list["sync"])
synced = TRUE
var/success = 0
for(var/obj/machinery/r_n_d/server/S in GLOB.machines)
for(var/datum/tech/T in files.known_tech) //Uploading
S.files.AddTech2Known(T)
for(var/datum/tech/T in S.files.known_tech) //Downloading
files.AddTech2Known(T)
success = 1
files.RefreshResearch()
if(success)
to_chat(usr, "You connect to the research server, push your data upstream to it, then pull the resulting merged data from the master branch.")
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
else
to_chat(usr, "Reserch server ping response timed out. Unable to connect. Please contact the system administrator.")
playsound(src, 'sound/machines/buzz-two.ogg', 50, 1)
sleeperUI(usr)
return
if(patient && !(patient.stat & DEAD)) //What is bitwise NOT? ... Thought it was tilde.
if(href_list["inject"] == REAGENT_ID_INAPROVALINE || patient.health > min_health)
inject_chem(usr, href_list["inject"])
@@ -650,11 +620,6 @@
if(!digested)
items_preserved |= T
else
if(analyzer && digested)
var/obj/item/tech_item = T
for(var/tech in tech_item.origin_tech)
files.UpdateTech(tech, tech_item.origin_tech[tech])
synced = FALSE
if(recycles && T.matter)
for(var/material in T.matter)
var/total_material = T.matter[material]
@@ -1,132 +1,3 @@
//A portable analyzer, for research borgs. This is better then giving them a gripper which can hold anything and letting them use the normal analyzer.
/obj/item/portable_destructive_analyzer
name = "Portable Destructive Analyzer"
icon = 'icons/obj/items.dmi'
icon_state = "portable_analyzer"
desc = "Similar to the stationary version, this rather unwieldy device allows you to break down objects in the name of science."
var/min_reliability = 90 //Can't upgrade, call it laziness or a drawback
var/datum/research/techonly/files //The device uses the same datum structure as the R&D computer/server.
//This analyzer can only store tech levels, however.
var/obj/item/loaded_item //What is currently inside the analyzer.
/obj/item/portable_destructive_analyzer/Initialize(mapload)
. = ..()
files = new /datum/research/techonly(src) //Setup the research data holder.
/obj/item/portable_destructive_analyzer/Destroy()
qdel_null(files)
. = ..()
/obj/item/portable_destructive_analyzer/attack_self(user as mob)
var/response = tgui_alert(user, "Analyzing the item inside will *DESTROY* the item for good.\n\
Syncing to the research server will send the data that is stored inside to research.\n\
Ejecting will place the loaded item onto the floor.",
"What would you like to do?", list("Analyze", "Sync", "Eject"))
if(response == "Analyze")
if(loaded_item)
var/confirm = tgui_alert(user, "This will destroy the item inside forever. Are you sure?","Confirm Analyze",list("Yes","No"))
if(confirm == "Yes" && !QDELETED(loaded_item)) //This is pretty copypasta-y
to_chat(user, span_filter_notice("You activate the analyzer's microlaser, analyzing \the [loaded_item] and breaking it down."))
flick("portable_analyzer_scan", src)
playsound(src, 'sound/items/Welder2.ogg', 50, 1)
var/research_levels = list()
for(var/T in loaded_item.origin_tech)
files.UpdateTech(T, loaded_item.origin_tech[T])
research_levels += "\The [loaded_item] had level [loaded_item.origin_tech[T]] in [CallTechName(T)]."
if (length(research_levels))
to_chat(user, span_filter_notice("[jointext(research_levels,"<br>")]"))
loaded_item = null
for(var/obj/I in contents)
for(var/mob/M in I.contents)
M.death()
if(istype(I,/obj/item/stack/material))//Only deconstructs 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)
loaded_item = S
else
qdel(S)
desc = initial(desc)
icon_state = initial(icon_state)
else
qdel(I)
desc = initial(desc)
icon_state = initial(icon_state)
else
return
else
to_chat(user, span_filter_notice("The [src] is empty. Put something inside it first."))
if(response == "Sync")
var/success = 0
for(var/obj/machinery/r_n_d/server/S in GLOB.machines)
for(var/datum/tech/T in files.known_tech) //Uploading
S.files.AddTech2Known(T)
for(var/datum/tech/T in S.files.known_tech) //Downloading
files.AddTech2Known(T)
success = 1
files.RefreshResearch()
if(success)
to_chat(user, span_filter_notice("You connect to the research server, push your data upstream to it, then pull the resulting merged data from the master branch."))
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
else
to_chat(user, span_filter_notice("Reserch server ping response timed out. Unable to connect. Please contact the system administrator."))
playsound(src, 'sound/machines/buzz-two.ogg', 50, 1)
if(response == "Eject")
if(loaded_item)
loaded_item.loc = get_turf(src)
desc = initial(desc)
icon_state = initial(icon_state)
loaded_item = null
else
to_chat(user, span_filter_notice("The [src] is already empty."))
/obj/item/portable_destructive_analyzer/afterattack(var/atom/target, var/mob/living/user, proximity)
if(!target)
return
if(!proximity)
return
if(!isturf(target.loc)) // Don't load up stuff if it's inside a container or mob!
return
if(istype(target,/obj/item))
if(loaded_item)
to_chat(user, span_filter_notice("Your [src] already has something inside. Analyze or eject it first."))
return
var/obj/item/I = target
I.loc = src
loaded_item = I
for(var/mob/M in viewers())
M.show_message(span_notice("[user] adds the [I] to the [src]."), 1)
desc = initial(desc) + "<br>It is holding \the [loaded_item]."
flick("portable_analyzer_load", src)
icon_state = "portable_analyzer_full"
/obj/item/portable_scanner
name = "Portable Resonant Analyzer"
icon = 'icons/obj/items.dmi'
icon_state = "portable_scanner"
desc = "An advanced scanning device used for analyzing objects without completely annihilating them for science. Unfortunately, it has no connection to any database like its angrier cousin."
/obj/item/portable_scanner/afterattack(var/atom/target, var/mob/living/user, proximity)
if(!target)
return
if(!proximity)
return
if(istype(target,/obj/item))
var/obj/item/I = target
if(do_after(src, 5 SECONDS * I.w_class))
for(var/mob/M in viewers())
M.show_message(span_notice("[user] sweeps \the [src] over \the [I]."), 1)
flick("[initial(icon_state)]-scan", src)
if(I.origin_tech && I.origin_tech.len)
for(var/T in I.origin_tech)
to_chat(user, span_notice("\The [I] had level [I.origin_tech[T]] in [CallTechName(T)]."))
else
to_chat(user, span_notice("\The [I] cannot be scanned by \the [src]."))
//This is used to unlock other borg covers.
/obj/item/card/robot //This is not a child of id cards, as to avoid dumb typechecks on computers.
name = "access code transmission device"
@@ -663,7 +663,7 @@
/obj/item/robot_module/robot/research/create_equipment(var/mob/living/silicon/robot/robot)
..()
src.modules += new /obj/item/portable_destructive_analyzer(src)
src.modules += new /obj/item/experi_scanner(src)
src.modules += new /obj/item/robotanalyzer(src)
src.modules += new /obj/item/card/robot(src)
src.modules += new /obj/item/gripper/research(src)
@@ -475,4 +475,5 @@
rest_sprite_options = list("Default", "Sit", "Bellyup")
/datum/robot_sprite/dogborg/crisis/smolraptor/alt
name = "Small Raptor Alt"
sprite_icon_state = "smolraptor_alt"
@@ -248,7 +248,7 @@
minbodytemp = 0
/mob/living/simple_mob/vore/aggressive/rat/pet
name = "pet rat"
name = "Giant Rat Siblings"
ai_holder_type = /datum/ai_holder/simple_mob/retaliate
/mob/living/simple_mob/vore/aggressive/rat/pet/Initialize(mapload)
@@ -67,7 +67,7 @@
parent_organ = BP_R_HAND
target_slot = slot_r_hand
integrated_object_type = /obj/item/portable_scanner
integrated_object_type = null
/obj/item/organ/internal/augment/armmounted/hand/attackby(obj/item/I as obj, mob/user as mob)
if(I.has_tool_quality(TOOL_SCREWDRIVER))
-7
View File
@@ -218,13 +218,6 @@
/obj/item/organ/internal/nano/digest_act(atom/movable/item_storage = null)
return FALSE
/datum/design/item/protean_reboot
name = "Protean Reboot Programmer"
id = "protean_reboot"
materials = list(MAT_STEEL = 2000, MAT_GLASS = 1000, MAT_PLASTEEL = 10000)
build_path = /obj/item/protean_reboot
sort_string = "JVAAZ"
/obj/item/protean_reboot
name = "Protean Reboot Programmer"
desc = "A small, highly specialized programmer used to form the basis of a Protean swarm. A necessary component in reconstituting a Protean who has lost total body cohesion."
@@ -60,40 +60,3 @@
/obj/item/stock_parts/micro_laser/high = 3,
/obj/item/stock_parts/capacitor/adv = 1
)
/datum/design/circuit/fusion
name = "fusion core control console"
id = "fusion_core_control"
build_path = /obj/item/circuitboard/fusion_core_control
sort_string = "LAAAD"
req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_MATERIAL = 3)
/datum/design/circuit/fusion/fuel_compressor
name = "fusion fuel compressor"
id = "fusion_fuel_compressor"
build_path = /obj/item/circuitboard/fusion_fuel_compressor
sort_string = "LAAAE"
/datum/design/circuit/fusion/fuel_control
name = "fusion fuel control console"
id = "fusion_fuel_control"
build_path = /obj/item/circuitboard/fusion_fuel_control
sort_string = "LAAAF"
/datum/design/circuit/fusion/gyrotron_control
name = "gyrotron control console"
id = "gyrotron_control"
build_path = /obj/item/circuitboard/gyrotron_control
sort_string = "LAAAG"
/datum/design/circuit/fusion/core
name = "fusion core"
id = "fusion_core"
build_path = /obj/item/circuitboard/fusion_core
sort_string = "LAAAH"
/datum/design/circuit/fusion/injector
name = "fusion fuel injector"
id = "fusion_injector"
build_path = /obj/item/circuitboard/fusion_injector
sort_string = "LAAAI"
@@ -10,14 +10,6 @@
origin_tech = list(TECH_MAGNET = 2, TECH_POWER = 4)
req_components = list(/obj/item/stock_parts/capacitor = 1)
/datum/design/circuit/tesla_coil
name = "Machine Design (Tesla Coil Board)"
desc = "The circuit board for a tesla coil."
id = "tesla_coil"
build_path = /obj/item/circuitboard/tesla_coil
req_tech = list(TECH_MAGNET = 2, TECH_POWER = 4)
sort_string = "MAAAC"
// Grounding rods can be built as machines using a circuit made in an autolathe.
/obj/item/circuitboard/grounding_rod
name = T_BOARD("grounding rod")
-223
View File
@@ -1,223 +0,0 @@
/*///////////////Circuit Imprinter (By Darem)////////////////////////
Used to print new circuit boards (for computers and similar systems) and AI modules. Each circuit board pattern are stored in
a /datum/desgin on the linked R&D console. You can then print them out in a fasion similar to a regular lathe. However, instead of
using metal and glass, it uses glass and reagents (usually sulphuric acid).
*/
/obj/machinery/r_n_d/circuit_imprinter
name = "Circuit Imprinter"
icon_state = "circuit_imprinter"
flags = OPENCONTAINER
circuit = /obj/item/circuitboard/circuit_imprinter
var/list/datum/design/queue = list()
var/progress = 0
var/max_material_storage = 75000
var/mat_efficiency = 1
var/speed = 1
materials = list(
MAT_STEEL = 0,
MAT_GLASS = 0,
MAT_PLASTEEL = 0,
MAT_PLASTIC = 0,
MAT_GRAPHITE = 0,
MAT_GOLD = 0,
MAT_SILVER = 0,
MAT_OSMIUM = 0,
MAT_LEAD = 0,
MAT_PHORON = 0,
MAT_URANIUM = 0,
MAT_DIAMOND = 0,
MAT_DURASTEEL = 0,
MAT_VERDANTIUM = 0,
MAT_MORPHIUM = 0,
MAT_METALHYDROGEN = 0,
MAT_SUPERMATTER = 0)
hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER)
use_power = USE_POWER_IDLE
idle_power_usage = 30
active_power_usage = 2500
/obj/machinery/r_n_d/circuit_imprinter/Initialize(mapload)
. = ..()
default_apply_parts()
/obj/machinery/r_n_d/circuit_imprinter/process()
..()
if(stat)
update_icon()
return
if(queue.len == 0)
busy = 0
update_icon()
return
var/datum/design/D = queue[1]
if(canBuild(D))
busy = 1
progress += speed
if(progress >= D.time)
build(D)
progress = 0
removeFromQueue(1)
update_icon()
else
if(busy)
visible_message(span_notice("[icon2html(src,viewers(src))] flashes: insufficient materials: [getLackingMaterials(D)]."))
busy = 0
update_icon()
/obj/machinery/r_n_d/circuit_imprinter/RefreshParts()
var/T = 0
for(var/obj/item/reagent_containers/glass/G in component_parts)
T += G.reagents.maximum_volume
create_reagents(T)
max_material_storage = 0
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
max_material_storage += M.rating * 75000
T = 0
for(var/obj/item/stock_parts/manipulator/M in component_parts)
T += M.rating
mat_efficiency = max(1 - (T - 1) / 4, 0.2)
speed = T
/obj/machinery/r_n_d/circuit_imprinter/update_icon()
if(panel_open)
icon_state = "circuit_imprinter_t"
else if(busy)
icon_state = "circuit_imprinter_ani"
else
icon_state = "circuit_imprinter"
/obj/machinery/r_n_d/circuit_imprinter/proc/TotalMaterials()
var/t = 0
for(var/f in materials)
t += materials[f]
return t
/obj/machinery/r_n_d/circuit_imprinter/dismantle()
for(var/obj/I in component_parts)
if(istype(I, /obj/item/reagent_containers/glass/beaker))
reagents.trans_to_obj(I, reagents.total_volume)
for(var/f in materials)
if(materials[f] >= SHEET_MATERIAL_AMOUNT)
var/path = getMaterialType(f)
if(path)
new path(loc, round(materials[f] / SHEET_MATERIAL_AMOUNT))
..()
/obj/machinery/r_n_d/circuit_imprinter/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(busy)
to_chat(user, span_notice("\The [src] is busy. Please wait for completion of previous operation."))
return 1
if(default_deconstruction_screwdriver(user, O))
if(linked_console)
linked_console.linked_imprinter = null
linked_console = null
return
if(default_deconstruction_crowbar(user, O))
return
if(default_part_replacement(user, O))
return
if(istype(O, /obj/item/gripper/no_use/loader))
return 0 //Sheet loaders weren't finishing attack(), this prevents the message "You can't stuff that gripper into this" without preventing the rest of the attack sequence from finishing
if(panel_open)
to_chat(user, span_notice("You can't load \the [src] while it's opened."))
return 1
if(!linked_console)
to_chat(user, "\The [src] must be linked to an R&D console first.")
return 1
if(O.is_open_container())
return 0
if(!istype(O, /obj/item/stack/material)) //Previously checked for specific material sheets, for some reason? Made the check on 133 redundant.
to_chat(user, span_notice("You cannot insert this item into \the [src]."))
return 1
if(stat)
return 1
if(TotalMaterials() + SHEET_MATERIAL_AMOUNT > max_material_storage)
to_chat(user, span_notice("\The [src]'s material bin is full. Please remove material before adding more."))
return 1
var/obj/item/stack/material/S = O
if(!(S.material.name in materials))
to_chat(user, span_warning("The [src] doesn't accept [material_display_name(S.material)]!"))
return
busy = 1
var/sname = "[S.name]"
var/amnt = S.perunit
var/max_res_amount = max_material_storage
for(var/mat in materials)
max_res_amount -= materials[mat]
if(materials[S.material.name] + amnt <= max_res_amount)
if(S && S.get_amount() >= 1)
var/count = 0
add_overlay("fab-load-metal")
spawn(10)
cut_overlay("fab-load-metal")
while(materials[S.material.name] + amnt <= max_res_amount && S.get_amount() >= 1)
materials[S.material.name] += amnt
S.use(1)
count++
to_chat(user, span_filter_notice("You insert [count] [sname] into the fabricator."))
else
to_chat(user, span_filter_notice("The fabricator cannot hold more [sname]."))
busy = 0
return
/obj/machinery/r_n_d/circuit_imprinter/proc/addToQueue(var/datum/design/D)
queue += D
return
/obj/machinery/r_n_d/circuit_imprinter/proc/removeFromQueue(var/index)
if(queue.len >= index)
queue.Cut(index, index + 1)
return
/obj/machinery/r_n_d/circuit_imprinter/proc/canBuild(var/datum/design/D)
for(var/M in D.materials)
if(materials[M] < (D.materials[M] * mat_efficiency))
return 0
for(var/C in D.chemicals)
if(!reagents.has_reagent(C, D.chemicals[C] * mat_efficiency))
return 0
return 1
/obj/machinery/r_n_d/circuit_imprinter/proc/getLackingMaterials(var/datum/design/D)
var/ret = ""
for(var/M in D.materials)
if(materials[M] < D.materials[M])
if(ret != "")
ret += ", "
ret += "[D.materials[M] - materials[M]] [M]"
for(var/C in D.chemicals)
if(!reagents.has_reagent(C, D.chemicals[C]))
if(ret != "")
ret += ", "
ret += C
return ret
/obj/machinery/r_n_d/circuit_imprinter/proc/build(var/datum/design/D)
var/power = active_power_usage
for(var/M in D.materials)
power += round(D.materials[M] / 5)
power = max(active_power_usage, power)
use_power(power)
for(var/M in D.materials)
materials[M] = max(0, materials[M] - D.materials[M] * mat_efficiency)
for(var/C in D.chemicals)
reagents.remove_reagent(C, D.chemicals[C] * mat_efficiency)
if(D.build_path)
var/obj/new_item = D.Fabricate(src, src)
new_item.loc = loc
if(mat_efficiency != 1) // No matter out of nowhere
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
-88
View File
@@ -1,88 +0,0 @@
/***************************************************************
** Design Datums **
** All the data for building stuff and tracking reliability. **
***************************************************************/
/*
For the materials datum, it assumes you need reagents unless specified otherwise. To designate a material that isn't a reagent,
you use one of the material IDs below. These are NOT ids in the usual sense (they aren't defined in the object or part of a datum),
they are simply references used as part of a "has materials?" type proc. They all start with a to denote that they aren't reagents.
The currently supporting non-reagent materials:
Don't add new keyword/IDs if they are made from an existing one (such as rods which are made from metal). Only add raw materials.
Design Guidlines
- When adding new designs, check rdreadme.dm to see what kind of things have already been made and where new stuff is needed.
- A single sheet of anything is 2000 units of material. Materials besides metal/glass require help from other jobs (mining for
other types of metals and chemistry for reagents).
*/
//Note: More then one of these can be added to a design.
/datum/design //Datum for object designs, used in construction
var/name = null //Name of the created object. If null it will be 'guessed' from build_path if possible.
var/desc = null //Description of the created object. If null it will use group_desc and name where applicable.
var/item_name = null //An item name before it is modified by various name-modifying procs
var/id = "id" //ID of the created object for easy refernece. Alphanumeric, lower-case, no symbols.
var/list/req_tech = list() //IDs of that techs the object originated from and the minimum level requirements.
var/build_type = null //Flag as to what kind machine the design is built in. See defines.
var/list/materials = list() //List of materials. Format: "id" = amount.
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/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()
//These procs are used in subtypes for assigning names and descriptions dynamically
/datum/design/proc/AssembleDesignInfo()
AssembleDesignName()
AssembleDesignDesc()
return
/datum/design/proc/AssembleDesignName()
if(!name && build_path) //Get name from build path if posible
var/atom/movable/A = build_path
name = initial(A.name)
item_name = name
return
/datum/design/proc/AssembleDesignDesc()
if(!desc) //Try to make up a nice description if we don't have one
desc = "Allows for the construction of \a [item_name]."
return
//Returns a new instance of the item for this design
//This is to allow additional initialization to be performed, including possibly additional contructor arguments.
/datum/design/proc/Fabricate(var/newloc, var/fabricator)
return new build_path(newloc)
/datum/design/item
build_type = PROTOLATHE
//Make sure items don't get free power, or resources. Also make things be recycled with proper values.
/datum/design/item/Fabricate()
var/obj/item/I = ..()
if(LAZYLEN(materials))
if(!LAZYLEN(I.matter))
I.matter = list()
else
I.matter.Cut()
for(var/matname in materials)
I.matter[matname] = materials[matname]
var/obj/item/cell/C = I.get_cell()
if(C)
C.charge = 0
I.update_icon()
return I
-54
View File
@@ -1,54 +0,0 @@
// HUDs
/datum/design/item/hud
materials = list(MAT_STEEL = 50, MAT_GLASS = 50)
/datum/design/item/hud/AssembleDesignName()
..()
name = "HUD glasses prototype ([item_name])"
/datum/design/item/hud/AssembleDesignDesc()
desc = "Allows for the construction of \a [item_name] HUD glasses."
/datum/design/item/hud/health
name = "health scanner"
id = "health_hud"
req_tech = list(TECH_BIO = 2, TECH_MAGNET = 3)
build_path = /obj/item/clothing/glasses/hud/health
sort_string = "EAAAA"
/datum/design/item/hud/security
name = "security records"
id = "security_hud"
req_tech = list(TECH_MAGNET = 3, TECH_COMBAT = 2)
build_path = /obj/item/clothing/glasses/hud/security
sort_string = "EAAAB"
/datum/design/item/hud/janitor
name = "contaminant detector"
id = "janitor_hud"
req_tech = list(TECH_MAGNET = 2)
build_path = /obj/item/clothing/glasses/hud/janitor
sort_string = "EAAAC"
/datum/design/item/hud/mesons
name = "optical meson scanner"
id = "mesons"
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/clothing/glasses/meson
sort_string = "EAAAD"
/datum/design/item/hud/material
name = "optical material scanner"
id = "material"
req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3)
build_path = /obj/item/clothing/glasses/material
sort_string = "EAAAE"
/datum/design/item/hud/graviton_visor
name = "graviton visor"
id = "graviton_goggles"
req_tech = list(TECH_MAGNET = 5, TECH_ENGINEERING = 3, TECH_BLUESPACE = 3, TECH_PHORON = 3, TECH_ARCANE = 1)
materials = list(MAT_PLASTEEL = 2000, MAT_GLASS = 3000, MAT_PHORON = 1500, MAT_DIAMOND = 500)
build_path = /obj/item/clothing/glasses/graviton
sort_string = "EAAAF"
-7
View File
@@ -1,7 +0,0 @@
/datum/design/item/hud/omni
name = "AR glasses"
id = "omnihud"
req_tech = list(TECH_MAGNET = 4, TECH_COMBAT = 3, TECH_BIO = 3)
materials = list(MAT_STEEL = 1000, MAT_GLASS = 1000)
build_path = /obj/item/clothing/glasses/omnihud
sort_string = "EAAVA"
@@ -1,51 +0,0 @@
// Various AI/mind holding device
/datum/design/item/ai_holder/AssembleDesignName()
..()
name = "Mind storage device prototype ([item_name])"
/datum/design/item/ai_holder/mmi
name = "Man-machine interface"
id = "mmi"
req_tech = list(TECH_DATA = 2, TECH_BIO = 3)
build_type = PROTOLATHE | PROSFAB
materials = list(MAT_STEEL = 1000, MAT_GLASS = 500)
build_path = /obj/item/mmi
category = list("Misc")
sort_string = "SAAAA"
/datum/design/item/ai_holder/posibrain
name = "Positronic brain"
id = "posibrain"
req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 6, TECH_BLUESPACE = 2, TECH_DATA = 4)
build_type = PROTOLATHE | PROSFAB
materials = list(MAT_STEEL = 2000, MAT_GLASS = 1000, MAT_SILVER = 1000, MAT_GOLD = 500, MAT_PHORON = 500, MAT_DIAMOND = 100)
build_path = /obj/item/mmi/digital/posibrain
category = list("Misc")
sort_string = "SAAAB"
/datum/design/item/ai_holder/dronebrain
name = "Robotic intelligence circuit"
id = "dronebrain"
req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 5, TECH_DATA = 4)
build_type = PROTOLATHE | PROSFAB
materials = list(MAT_STEEL = 2000, MAT_GLASS = 1000, MAT_SILVER = 1000, MAT_GOLD = 500)
build_path = /obj/item/mmi/digital/robot
category = list("Misc")
sort_string = "SAAAC"
/datum/design/item/ai_holder/paicard
name = "'pAI', personal artificial intelligence device"
id = "paicard"
req_tech = list(TECH_DATA = 2)
materials = list(MAT_GLASS = 500, MAT_STEEL = 500)
build_path = /obj/item/paicard
sort_string = "SBAAA"
/datum/design/item/ai_holder/intellicard
name = "intelliCore"
desc = "Allows for the construction of an intelliCore."
id = "intellicore"
req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4)
materials = list(MAT_GLASS = 1000, MAT_GOLD = 200)
build_path = /obj/item/aicard
sort_string = "SCAAA"
@@ -1,78 +0,0 @@
// Bags of holding
/datum/design/item/boh/AssembleDesignName()
..()
name = "Infinite capacity storage prototype ([item_name])"
/datum/design/item/boh/ore_holding
name = "Mining Satchel of Holding"
desc = "For the most tenacious miners, a bag with incomprehensible depth!"
id = "ore_holding"
req_tech = list(TECH_BLUESPACE = 2, TECH_MATERIAL = 3)
materials = list(MAT_GOLD = 1000, MAT_DIAMOND = 500, MAT_URANIUM = 250) // Less expensive since it can only hold ores
build_path = /obj/item/storage/bag/ore/holding
sort_string = "QAAAA"
/datum/design/item/boh/sheet_holding
name = "Sheet Snatcher of Holding"
desc = "For those who really hate walking up and down the stairs more than once!"
id = "sheet_holding"
req_tech = list(TECH_BLUESPACE = 1, TECH_MATERIAL = 2)
materials = list(MAT_GOLD = 300, MAT_DIAMOND = 200, MAT_URANIUM = 150) // Even less expensive because it has a more limited use
build_path = /obj/item/storage/bag/sheetsnatcher/holding
sort_string = "QAAAA"
/datum/design/item/boh/bag_holding
name = "Bag of Holding"
desc = "Using localized pockets of bluespace this bag prototype offers incredible storage capacity with the contents weighting nothing. It's a shame the bag itself is pretty heavy."
id = "bag_holding"
req_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 6)
materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 1500, MAT_URANIUM = 250)
build_path = /obj/item/storage/backpack/holding
sort_string = "QAAAA"
/datum/design/item/boh/dufflebag_holding
name = "DuffleBag of Holding"
desc = "A minaturized prototype of the popular Bag of Holding, the Dufflebag of Holding is, functionally, identical to the bag of holding, but comes in a more stylish and compact form."
id = "dufflebag_holding"
req_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 6)
materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 1500, MAT_URANIUM = 250)
build_path = /obj/item/storage/backpack/holding/duffle
sort_string = "QAAAB"
/datum/design/item/boh/trashbag_holding
name = "Trashbag of Holding"
desc = "Considerably more utilitarian than the Bag of Holding, the Trashbag of Holding is a janitor's best friend."
id = "trashbag_holding"
req_tech = list(TECH_BLUESPACE = 3, TECH_MATERIAL = 5)
materials = list(MAT_GOLD = 2000, MAT_DIAMOND = 1000, MAT_URANIUM = 250)
build_path = /obj/item/storage/bag/trash/holding
sort_string = "QAAAC"
/datum/design/item/boh/pouch_holding
name = "Pouch of Holding"
desc = "Somehow compresses the storage of a backpack into a pouch-sized container!"
id = "pouch_holding"
req_tech = list(TECH_BLUESPACE = 3, TECH_MATERIAL = 5)
materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 2000, MAT_URANIUM = 250)
build_path = /obj/item/storage/pouch/holding
sort_string = "QAAAD"
/datum/design/item/boh/belt_holding_med
name = "Medical Belt of Holding"
desc = "A belt that uses localized bluespace pockets to hold more items than expected!"
id = "belt_holding_med"
req_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 6)
materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 2000, MAT_TITANIUM = 500)
build_path = /obj/item/storage/belt/medical/holding
sort_string = "QAAAE"
/datum/design/item/boh/belt_holding_utility
name = "Tool-Belt of Holding"
desc = "A belt that uses localized bluespace pockets to hold more items than expected!"
id = "belt_holding_utility"
req_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 6)
materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 2000, MAT_TITANIUM = 500)
build_path = /obj/item/storage/belt/utility/holding
sort_string = "QAAAF"
-22
View File
@@ -1,22 +0,0 @@
// Various beakers
/datum/design/item/beaker/AssembleDesignName()
name = "Beaker prototype ([item_name])"
/datum/design/item/beaker/noreact
name = "cryostasis"
desc = "A cryostasis beaker that allows for chemical storage without reactions. Can hold up to 50 units."
id = "splitbeaker"
req_tech = list(TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 3000)
build_path = /obj/item/reagent_containers/glass/beaker/noreact
sort_string = "IAAAA"
/datum/design/item/beaker/bluespace
name = TECH_BLUESPACE
desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete. Can hold up to 300 units."
id = "bluespacebeaker"
req_tech = list(TECH_BLUESPACE = 2, TECH_MATERIAL = 6)
materials = list(MAT_STEEL = 3000, MAT_PHORON = 3000, MAT_DIAMOND = 500)
build_path = /obj/item/reagent_containers/glass/beaker/bluespace
sort_string = "IAAAB"
@@ -1,60 +0,0 @@
/datum/design/item/biotech
materials = list(MAT_STEEL = 30, MAT_GLASS = 20)
/datum/design/item/biotech/AssembleDesignName()
..()
name = "Biotech device prototype ([item_name])"
// Biotech of various types
/datum/design/item/biotech/mass_spectrometer
desc = "A device for analyzing chemicals in blood."
id = "mass_spectrometer"
req_tech = list(TECH_BIO = 2, TECH_MAGNET = 2)
build_path = /obj/item/mass_spectrometer
sort_string = "JAAAA"
/datum/design/item/biotech/adv_mass_spectrometer
desc = "A device for analyzing chemicals in blood and their quantities."
id = "adv_mass_spectrometer"
req_tech = list(TECH_BIO = 2, TECH_MAGNET = 4)
build_path = /obj/item/mass_spectrometer/adv
sort_string = "JAAAB"
/datum/design/item/biotech/reagent_scanner
desc = "A device for identifying chemicals."
id = "reagent_scanner"
req_tech = list(TECH_BIO = 2, TECH_MAGNET = 2)
build_path = /obj/item/reagent_scanner
sort_string = "JAABA"
/datum/design/item/biotech/adv_reagent_scanner
desc = "A device for identifying chemicals and their proportions."
id = "adv_reagent_scanner"
req_tech = list(TECH_BIO = 2, TECH_MAGNET = 4)
build_path = /obj/item/reagent_scanner/adv
sort_string = "JAABB"
/datum/design/item/biotech/robot_scanner
desc = "A hand-held scanner able to diagnose robotic injuries."
id = "robot_scanner"
req_tech = list(TECH_MAGNET = 3, TECH_BIO = 2, TECH_ENGINEERING = 3)
materials = list(MAT_STEEL = 500, MAT_GLASS = 200)
build_path = /obj/item/robotanalyzer
sort_string = "JAACA"
/datum/design/item/biotech/nanopaste
desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery."
id = "nanopaste"
req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3)
materials = list(MAT_STEEL = 7000, MAT_GLASS = 7000)
build_path = /obj/item/stack/nanopaste
sort_string = "JAACB"
/datum/design/item/biotech/plant_analyzer
desc = "A device capable of quickly scanning all relevant data about a plant."
id = "plant_analyzer"
req_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
materials = list(MAT_STEEL = 500, MAT_GLASS = 500)
build_path = /obj/item/analyzer/plant_analyzer
sort_string = "JAADA"
@@ -1,23 +0,0 @@
/datum/design/item/biotech/nif
name = "nanite implant framework (NIF)"
id = "nif"
req_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_DATA = 5)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 8000, MAT_URANIUM = 6000, MAT_DIAMOND = 6000)
build_path = /obj/item/nif
sort_string = "JVAAA"
/datum/design/item/biotech/nifbio
name = "bioadaptive NIF"
id = "bioadapnif"
req_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_DATA = 5, TECH_BIO = 5)
materials = list(MAT_STEEL = 10000, MAT_GLASS = 15000, MAT_URANIUM = 10000, MAT_DIAMOND = 10000)
build_path = /obj/item/nif/bioadap
sort_string = "JVAAB"
/datum/design/item/biotech/nifrepairtool
name = "adv. NIF repair tool"
id = "anrt"
req_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_DATA = 5)
materials = list(MAT_STEEL = 2000, MAT_GLASS = 3000, MAT_URANIUM = 2000, MAT_DIAMOND = 2000)
build_path = /obj/item/nifrepairer
sort_string = "JVABA"
@@ -1,108 +0,0 @@
// Integrated circuits stuff
/datum/design/item/integrated_circuitry/AssembleDesignName()
..()
name = "Circuitry device design ([item_name])"
/datum/design/item/integrated_circuitry/custom_circuit_printer
name = "Portable integrated circuit printer"
desc = "A portable(ish) printer for modular machines."
id = "ic_printer"
req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 4, TECH_DATA = 5)
materials = list(MAT_STEEL = 10000)
build_path = /obj/item/integrated_circuit_printer
sort_string = "UAAAA"
/datum/design/item/integrated_circuitry/custom_circuit_printer_upgrade
name = "Integrated circuit printer upgrade - advanced designs"
desc = "Allows the integrated circuit printer to create advanced circuits"
id = "ic_printer_upgrade_adv"
req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4)
materials = list(MAT_STEEL = 2000)
build_path = /obj/item/disk/integrated_circuit/upgrade/advanced
sort_string = "UBAAA"
/datum/design/item/integrated_circuitry/wirer
name = "Custom wirer tool"
id = "wirer"
req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 2500)
build_path = /obj/item/integrated_electronics/wirer
sort_string = "UCAAA"
/datum/design/item/integrated_circuitry/debugger
name = "Custom circuit debugger tool"
id = "debugger"
req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 2500)
build_path = /obj/item/integrated_electronics/debugger
sort_string = "UCBBB"
// Assemblies
/datum/design/item/integrated_circuitry/assembly/AssembleDesignName()
..()
name = "Circuitry assembly design ([item_name])"
/datum/design/item/integrated_circuitry/assembly/custom_circuit_assembly_small
name = "Small custom assembly"
desc = "A customizable assembly for simple, small devices."
id = "assembly-small"
req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_POWER = 2)
materials = list(MAT_STEEL = 10000)
build_path = /obj/item/electronic_assembly
sort_string = "UDAAA"
/datum/design/item/integrated_circuitry/assembly/custom_circuit_assembly_medium
name = "Medium custom assembly"
desc = "A customizable assembly suited for more ambitious mechanisms."
id = "assembly-medium"
req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_POWER = 3)
materials = list(MAT_STEEL = 20000)
build_path = /obj/item/electronic_assembly/medium
sort_string = "UDAAB"
/datum/design/item/integrated_circuitry/assembly/custom_circuit_assembly_large
name = "Large custom assembly"
desc = "A customizable assembly for large machines."
id = "assembly-large"
req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4)
materials = list(MAT_STEEL = 40000)
build_path = /obj/item/electronic_assembly/large
sort_string = "UDAAC"
/datum/design/item/integrated_circuitry/assembly/custom_circuit_assembly_drone
name = "Drone custom assembly"
desc = "A customizable assembly optimized for autonomous devices."
id = "assembly-drone"
req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4, TECH_POWER = 4)
materials = list(MAT_STEEL = 30000)
build_path = /obj/item/electronic_assembly/drone
sort_string = "UDAAD"
/datum/design/item/integrated_circuitry/assembly/custom_circuit_assembly_device
name = "Device custom assembly"
desc = "An customizable assembly designed to interface with other devices."
id = "assembly-device"
req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2, TECH_POWER = 2)
materials = list(MAT_STEEL = 5000)
build_path = /obj/item/assembly/electronic_assembly
sort_string = "UDAAE"
/datum/design/item/integrated_circuitry/assembly/custom_circuit_assembly_implant
name = "Implant custom assembly"
desc = "An customizable assembly for very small devices, implanted into living entities."
id = "assembly-implant"
req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 3, TECH_BIO = 5)
materials = list(MAT_STEEL = 2000)
build_path = /obj/item/implant/integrated_circuit
sort_string = "UDAAF"
/datum/design/item/integrated_circuitry/assembly/circuit_bug
name = "Circuitry Bug"
desc = "A tiny circuit assembly that can easily be hidden."
id = "circuit-bug"
req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_POWER = 2)
materials = list(MAT_STEEL = 2000)
build_path = /obj/item/electronic_assembly/circuit_bug
sort_string = "UDAAG"
@@ -1,237 +0,0 @@
/datum/design/aimodule
build_type = IMPRINTER
materials = list(MAT_GLASS = 2000, MAT_GOLD = 100)
/datum/design/aimodule/AssembleDesignName()
name = "AI module design ([name])"
/datum/design/aimodule/AssembleDesignDesc()
desc = "Allows for the construction of \a '[name]' AI module."
/datum/design/aimodule/safeguard
name = "Safeguard"
id = "safeguard"
req_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
build_path = /obj/item/aiModule/safeguard
sort_string = "XABAA"
/datum/design/aimodule/onehuman
name = "OneCrewMember"
id = "onehuman"
req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/oneHuman
sort_string = "XABAB"
/datum/design/aimodule/protectstation
name = "ProtectStation"
id = "protectstation"
req_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/protectStation
sort_string = "XABAC"
/datum/design/aimodule/notele
name = "TeleporterOffline"
id = "notele"
req_tech = list(TECH_DATA = 3)
build_path = /obj/item/aiModule/teleporterOffline
sort_string = "XABAD"
/datum/design/aimodule/quarantine
name = "Quarantine"
id = "quarantine"
req_tech = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4)
build_path = /obj/item/aiModule/quarantine
sort_string = "XABAE"
/datum/design/aimodule/oxygen
name = "OxygenIsToxicToHumans"
id = "oxygen"
req_tech = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4)
build_path = /obj/item/aiModule/oxygen
sort_string = "XABAF"
/datum/design/aimodule/freeform
name = "Freeform"
id = "freeform"
req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4)
build_path = /obj/item/aiModule/freeform
sort_string = "XABAG"
/datum/design/aimodule/reset
name = "Reset"
id = "reset"
req_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/reset
sort_string = "XABAH"
/datum/design/aimodule/purge
name = "Purge"
id = "purge"
req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/purge
sort_string = "XABAI"
// Core modules
/datum/design/aimodule/core
req_tech = list(TECH_DATA = 4, TECH_MATERIAL = 6)
/datum/design/aimodule/core/AssembleDesignName()
name = "AI core module design ([name])"
/datum/design/aimodule/core/AssembleDesignDesc()
desc = "Allows for the construction of \a '[name]' AI core module."
/datum/design/aimodule/core/freeformcore
name = "Freeform"
id = "freeformcore"
build_path = /obj/item/aiModule/freeformcore
sort_string = "XACAA"
/datum/design/aimodule/core/asimov
name = "Asimov"
id = "asimov"
build_path = /obj/item/aiModule/asimov
sort_string = "XACAB"
/datum/design/aimodule/core/paladin
name = "P.A.L.A.D.I.N."
id = "paladin"
build_path = /obj/item/aiModule/paladin
sort_string = "XACAC"
/datum/design/aimodule/core/tyrant
name = "T.Y.R.A.N.T."
id = "tyrant"
req_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 2, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/tyrant
sort_string = "XACAD"
/datum/design/aimodule/core/nanotrasen
name = "NT Default"
id = "nanotrasen"
build_path = /obj/item/aiModule/nanotrasen
req_tech = list(TECH_DATA = 1)
sort_string = "XACAE"
/datum/design/aimodule/core/predator
name = "Predator"
id = "laws_predator_vr"
req_tech = list(TECH_DATA = 4, TECH_BIO = 3, TECH_ILLEGAL = 2, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/predator
sort_string = "XACAF"
/datum/design/aimodule/core/protective_shell
name = "Protective Shell"
id = "laws_protective_shell_vr"
req_tech = list(TECH_DATA = 4, TECH_BIO = 3, TECH_ILLEGAL = 2, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/protective_shell
sort_string = "XACAG"
/datum/design/aimodule/core/scientific_pursuer
name = "Scientific Pursuer"
id = "laws_scientific_pursuer_vr"
req_tech = list(TECH_DATA = 4, TECH_BIO = 3, TECH_ILLEGAL = 2, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/scientific_pursuer
sort_string = "XACAH"
/datum/design/aimodule/core/guard_dog
name = "Guard Dog"
id = "laws_guard_dog_vr"
req_tech = list(TECH_DATA = 4, TECH_BIO = 3, TECH_ILLEGAL = 2, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/guard_dog
sort_string = "XACAI"
/datum/design/aimodule/core/pleasurebot
name = "Pleasurebot"
id = "laws_pleasurebot_vr"
req_tech = list(TECH_DATA = 4, TECH_BIO = 3, TECH_ILLEGAL = 2, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/pleasurebot
sort_string = "XACAJ"
/datum/design/aimodule/core/consuming_eradicator
name = "Consuming Eradicator"
id = "laws_consuming_eradicator_vr"
req_tech = list(TECH_DATA = 4, TECH_BIO = 3, TECH_ILLEGAL = 6, TECH_MATERIAL = 6)
build_path = /obj/item/aiModule/consuming_eradicator
sort_string = "XACAK"
// Illegal modules
/datum/design/aimodule/illegal
materials = list(MAT_GLASS = 4000, MAT_GOLD = 500)
req_tech = list(TECH_DATA = 6, TECH_ILLEGAL = 7, TECH_MATERIAL = 9, TECH_COMBAT = 7)
/datum/design/aimodule/illegal/AssembleDesignName()
name = "AI illegal module design ([name])"
/datum/design/aimodule/illegal/AssembleDesignDesc()
desc = "Allows for the construction of \a '[name]' AI illegal module."
/datum/design/aimodule/illegal/noengine
name = "EngineOffline"
id = "noengine"
req_tech = list(TECH_DATA = 5, TECH_ILLEGAL = 5, TECH_MATERIAL = 6, TECH_COMBAT = 7)
build_path = /obj/item/aiModule/prototypeEngineOffline
sort_string = "XADAA"
/datum/design/aimodule/illegal/corp
name = "Corporate"
id = "corp"
req_tech = list(TECH_DATA = 2, TECH_ILLEGAL = 4, TECH_MATERIAL = 2, TECH_COMBAT = 2)
build_path = /obj/item/aiModule/corp
sort_string = "XADAB"
/datum/design/aimodule/illegal/robocop
name = "Robocop"
id = "robocop"
req_tech = list(TECH_DATA = 2, TECH_ILLEGAL = 2, TECH_MATERIAL = 2, TECH_COMBAT = 4)
build_path = /obj/item/aiModule/robocop
sort_string = "XADAC"
/datum/design/aimodule/illegal/antimov
name = "Antimov"
id = "antimov"
req_tech = list(TECH_DATA = 6, TECH_ILLEGAL = 7, TECH_MATERIAL = 7, TECH_COMBAT = 5)
build_path = /obj/item/aiModule/antimov
sort_string = "XADAD"
/datum/design/aimodule/illegal/nanotrasen_aggressive
name = "NT Aggressive"
id = "nanotrasen_aggressive"
req_tech = list(TECH_DATA = 5, TECH_ILLEGAL = 6, TECH_MATERIAL = 3, TECH_COMBAT = 7)
build_path = /obj/item/aiModule/nanotrasen_aggressive
sort_string = "XADAE"
/datum/design/aimodule/illegal/maintenance
name = "Maintenance"
id = "maintenance"
req_tech = list(TECH_DATA = 3, TECH_ILLEGAL = 2, TECH_MATERIAL = 3, TECH_COMBAT = 2)
build_path = /obj/item/aiModule/maintenance
sort_string = "XADAF"
/datum/design/aimodule/illegal/peacekeeper
name = "Peacekeeper"
id = "peacekeeper"
req_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 3, TECH_MATERIAL = 2, TECH_COMBAT = 2)
build_path = /obj/item/aiModule/peacekeeper
sort_string = "XADAG"
/datum/design/aimodule/illegal/reporter
name = "Reporter"
id = "reporter"
req_tech = list(TECH_DATA = 2, TECH_ILLEGAL = 2, TECH_MATERIAL = 3)
build_path = /obj/item/aiModule/reporter
sort_string = "XADAH"
/datum/design/aimodule/illegal/live_and_let_live
name = "Live and Let Live"
id = "live_and_let_live"
req_tech = list(TECH_DATA = 5, TECH_ILLEGAL = 3, TECH_MATERIAL = 4, TECH_COMBAT = 3)
build_path = /obj/item/aiModule/live_and_let_live
sort_string = "XADAI"
/datum/design/aimodule/illegal/balance
name = "Guardian of Balance."
id = "balance"
req_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 2, TECH_MATERIAL = 2, TECH_COMBAT = 3)
build_path = /obj/item/aiModule/balance
sort_string = "XADAJ"
@@ -1,803 +0,0 @@
/*
CIRCUITS BELOW
*/
/datum/design/circuit
build_type = IMPRINTER
req_tech = list(TECH_DATA = 2)
materials = list(MAT_GLASS = 2000)
chemicals = list(REAGENT_ID_SACID = 20)
time = 5
/datum/design/circuit/AssembleDesignName()
..()
if(build_path)
var/obj/item/circuitboard/C = build_path
if(initial(C.board_type) == "machine")
name = "Machine circuit design ([item_name])"
else if(initial(C.board_type) == "computer")
name = "Computer circuit design ([item_name])"
else
name = "Circuit design ([item_name])"
/datum/design/circuit/AssembleDesignDesc()
if(!desc)
desc = "Allows for the construction of \a [item_name] circuit board."
/datum/design/circuit/arcademachine
name = "battle arcade machine"
id = "arcademachine"
req_tech = list(TECH_DATA = 1)
build_path = /obj/item/circuitboard/arcade/battle
sort_string = "MAAAA"
/datum/design/circuit/oriontrail
name = "orion trail arcade machine"
id = "oriontrail"
req_tech = list(TECH_DATA = 1)
build_path = /obj/item/circuitboard/arcade/orion_trail
sort_string = "MAAAB"
/datum/design/circuit/clawmachine
name = "grab-a-gift arcade machine"
id = "clawmachine"
req_tech = list(TECH_DATA = 1)
build_path = /obj/item/circuitboard/arcade/clawmachine
sort_string = "MAAAC"
/datum/design/circuit/jukebox
name = "jukebox"
id = "jukebox"
req_tech = list(TECH_MAGNET = 2, TECH_DATA = 1)
build_path = /obj/item/circuitboard/jukebox
sort_string = "MAAAO"
/datum/design/circuit/seccamera
name = "security camera monitor"
id = "seccamera"
build_path = /obj/item/circuitboard/security
sort_string = "DAAAZ" // Duplicate string, really need to redo this whole thing
/datum/design/circuit/secdata
name = "security records console"
id = "sec_data"
build_path = /obj/item/circuitboard/secure_data
sort_string = "DABAA"
/datum/design/circuit/prisonmanage
name = "prisoner management console"
id = "prisonmanage"
build_path = /obj/item/circuitboard/prisoner
sort_string = "DACAA"
/datum/design/circuit/med_data
name = "medical records console"
id = "med_data"
build_path = /obj/item/circuitboard/med_data
sort_string = "FAAAA"
/datum/design/circuit/operating
name = "patient monitoring console"
id = "operating"
build_path = /obj/item/circuitboard/operating
sort_string = "FACAA"
/datum/design/circuit/scan_console
name = "DNA machine"
id = "scan_console"
build_path = /obj/item/circuitboard/scan_consolenew
sort_string = "FAGAA"
/datum/design/circuit/clonecontrol
name = "cloning control console"
id = "clonecontrol"
req_tech = list(TECH_DATA = 3, TECH_BIO = 3)
build_path = /obj/item/circuitboard/cloning
sort_string = "FAGAC"
/datum/design/circuit/clonepod
name = "clone pod"
id = "clonepod"
req_tech = list(TECH_DATA = 3, TECH_BIO = 3)
build_path = /obj/item/circuitboard/clonepod
sort_string = "FAGAE"
/datum/design/circuit/clonescanner
name = "cloning scanner"
id = "clonescanner"
req_tech = list(TECH_DATA = 3, TECH_BIO = 3)
build_path = /obj/item/circuitboard/clonescanner
sort_string = "FAGAG"
/datum/design/circuit/chem_master
name = "ChemMaster 3000"
id = "chemmaster"
req_tech = list(TECH_DATA = 3, TECH_MAGNET = 2)
build_path = /obj/item/circuitboard/chem_master
sort_string = "FAGAH"
/datum/design/circuit/crewconsole
name = "crew monitoring console"
id = "crewconsole"
req_tech = list(TECH_DATA = 3, TECH_MAGNET = 2, TECH_BIO = 2)
build_path = /obj/item/circuitboard/crew
sort_string = "FAGAI"
/datum/design/circuit/pandemic
name = "PanD.E.M.I.C 2200"
id = "pandemic"
req_tech = list(TECH_DATA = 2, TECH_BIO = 2)
build_path = /obj/item/circuitboard/pandemic
sort_string = "FAGAJ"
/datum/design/circuit/teleconsole
name = "teleporter control console"
id = "teleconsole"
req_tech = list(TECH_DATA = 3, TECH_BLUESPACE = 2)
build_path = /obj/item/circuitboard/teleporter
sort_string = "HAAAA"
/datum/design/circuit/robocontrol
name = "robotics control console"
id = "robocontrol"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/robotics
sort_string = "HAAAB"
/datum/design/circuit/mechacontrol
name = "exosuit control console"
id = "mechacontrol"
req_tech = list(TECH_DATA = 3)
build_path = /obj/item/circuitboard/mecha_control
sort_string = "HAAAC"
/datum/design/circuit/rdconsole
name = "R&D control console"
id = "rdconsole"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/rdconsole
sort_string = "HAAAE"
/datum/design/circuit/aifixer
name = "AI integrity restorer"
id = "aifixer"
req_tech = list(TECH_DATA = 3, TECH_BIO = 2)
build_path = /obj/item/circuitboard/aifixer
sort_string = "HAAAF"
/datum/design/circuit/comm_monitor
name = "telecommunications monitoring console"
id = "comm_monitor"
req_tech = list(TECH_DATA = 3)
build_path = /obj/item/circuitboard/comm_monitor
sort_string = "HAACA"
/datum/design/circuit/comm_server
name = "telecommunications server monitoring console"
id = "comm_server"
req_tech = list(TECH_DATA = 3)
build_path = /obj/item/circuitboard/comm_server
sort_string = "HAACB"
/datum/design/circuit/message_monitor
name = "messaging monitor console"
id = "message_monitor"
req_tech = list(TECH_DATA = 5)
build_path = /obj/item/circuitboard/message_monitor
sort_string = "HAACC"
/datum/design/circuit/aiupload
name = "AI upload console"
id = "aiupload"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/aiupload
sort_string = "HAABA"
/datum/design/circuit/borgupload
name = "cyborg upload console"
id = "borgupload"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/borgupload
sort_string = "HAABB"
/datum/design/circuit/destructive_analyzer
name = "destructive analyzer"
id = "destructive_analyzer"
req_tech = list(TECH_DATA = 2, TECH_MAGNET = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/destructive_analyzer
sort_string = "HABAA"
/datum/design/circuit/protolathe
name = "protolathe"
id = "protolathe"
req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/protolathe
sort_string = "HABAB"
/datum/design/circuit/circuit_imprinter
name = "circuit imprinter"
id = "circuit_imprinter"
req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/circuit_imprinter
sort_string = "HABAC"
/datum/design/circuit/autolathe
name = "autolathe board"
id = "autolathe"
req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/autolathe
sort_string = "HABAD"
/datum/design/circuit/rdservercontrol
name = "R&D server control console"
id = "rdservercontrol"
req_tech = list(TECH_DATA = 3)
build_path = /obj/item/circuitboard/rdservercontrol
sort_string = "HABBA"
/datum/design/circuit/rdserver
name = "R&D server"
id = "rdserver"
req_tech = list(TECH_DATA = 3)
build_path = /obj/item/circuitboard/rdserver
sort_string = "HABBB"
/datum/design/circuit/mechfab
name = "exosuit fabricator"
id = "mechfab"
req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3)
build_path = /obj/item/circuitboard/mechfab
sort_string = "HABAE"
/datum/design/circuit/prosfab
name = "prosthetics fabricator"
id = "prosfab"
req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3)
build_path = /obj/item/circuitboard/prosthetics
sort_string = "HABAF"
/datum/design/circuit/mech_recharger
name = "mech recharger"
id = "mech_recharger"
req_tech = list(TECH_DATA = 2, TECH_POWER = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/mech_recharger
sort_string = "HACAA"
/datum/design/circuit/recharge_station
name = "cyborg recharge station"
id = "recharge_station"
req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/recharge_station
sort_string = "HACAC"
/datum/design/circuit/atmosalerts
name = "atmosphere alert console"
id = "atmosalerts"
build_path = /obj/item/circuitboard/atmos_alert
sort_string = "JAAAA"
/datum/design/circuit/air_management
name = "atmosphere monitoring console"
id = "air_management"
build_path = /obj/item/circuitboard/air_management
sort_string = "JAAAB"
/datum/design/circuit/rcon_console
name = "RCON remote control console"
id = "rcon_console"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_POWER = 5)
build_path = /obj/item/circuitboard/rcon_console
sort_string = "JAAAC"
/datum/design/circuit/dronecontrol
name = "drone control console"
id = "dronecontrol"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/drone_control
sort_string = "JAAAD"
/datum/design/circuit/powermonitor
name = "power monitoring console"
id = "powermonitor"
build_path = /obj/item/circuitboard/powermonitor
sort_string = "JAAAE"
/datum/design/circuit/solarcontrol
name = "solar control console"
id = "solarcontrol"
build_path = /obj/item/circuitboard/solar_control
sort_string = "JAAAF"
/datum/design/circuit/shutoff_monitor
name = "Automatic shutoff valve monitor"
id = "shutoff_monitor"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3)
build_path = /obj/item/circuitboard/shutoff_monitor
sort_string = "JAAAG"
/datum/design/circuit/pacman
name = "PACMAN-type generator"
id = "pacman"
req_tech = list(TECH_DATA = 3, TECH_PHORON = 3, TECH_POWER = 3, TECH_ENGINEERING = 3)
build_path = /obj/item/circuitboard/pacman
sort_string = "JBAAA"
/datum/design/circuit/superpacman
name = "SUPERPACMAN-type generator"
id = "superpacman"
req_tech = list(TECH_DATA = 3, TECH_POWER = 4, TECH_ENGINEERING = 4)
build_path = /obj/item/circuitboard/pacman/super
sort_string = "JBAAB"
/datum/design/circuit/mrspacman
name = "MRSPACMAN-type generator"
id = "mrspacman"
req_tech = list(TECH_DATA = 3, TECH_POWER = 5, TECH_ENGINEERING = 5)
build_path = /obj/item/circuitboard/pacman/mrs
sort_string = "JBAAC"
/datum/design/circuit/batteryrack
name = "cell rack PSU"
id = "batteryrack"
req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/batteryrack
sort_string = "JBABA"
/datum/design/circuit/smes_cell
name = "'SMES' superconductive magnetic energy storage"
desc = "Allows for the construction of circuit boards used to build a SMES."
id = "smes_cell"
req_tech = list(TECH_POWER = 7, TECH_ENGINEERING = 5)
build_path = /obj/item/circuitboard/smes
sort_string = "JBABB"
/datum/design/circuit/grid_checker
name = "power grid checker"
desc = "Allows for the construction of circuit boards used to build a grid checker."
id = "grid_checker"
req_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 3)
build_path = /obj/item/circuitboard/grid_checker
sort_string = "JBABC"
/datum/design/circuit/breakerbox
name = "breaker box"
desc = "Allows for the construction of circuit boards used to build a breaker box."
id = "breakerbox"
req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3)
build_path = /obj/item/circuitboard/breakerbox
sort_string = "JBABD"
/datum/design/circuit/gas_heater
name = "gas heating system"
id = "gasheater"
req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 1)
build_path = /obj/item/circuitboard/unary_atmos/heater
sort_string = "JCAAA"
/datum/design/circuit/gas_cooler
name = "gas cooling system"
id = "gascooler"
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/unary_atmos/cooler
sort_string = "JCAAB"
/datum/design/circuit/secure_airlock
name = "secure airlock electronics"
desc = "Allows for the construction of a tamper-resistant airlock electronics."
id = "securedoor"
req_tech = list(TECH_DATA = 3)
build_path = /obj/item/airlock_electronics/secure
sort_string = "JDAAA"
/datum/design/circuit/ordercomp
name = "supply ordering console"
id = "ordercomp"
build_path = /obj/item/circuitboard/supplycomp
sort_string = "KAAAY" // Duplicate string, really need to redo this whole thing
/datum/design/circuit/supplycomp
name = "supply control console"
id = "supplycomp"
req_tech = list(TECH_DATA = 3)
build_path = /obj/item/circuitboard/supplycomp/control
sort_string = "KAAAZ" // Duplicate string, really need to redo this whole thing
/datum/design/circuit/biogenerator
name = "biogenerator"
id = "biogenerator"
req_tech = list(TECH_DATA = 2)
build_path = /obj/item/circuitboard/biogenerator
sort_string = "KBAAA"
/datum/design/circuit/miningdrill
name = "mining drill head"
id = "mining drill head"
req_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
build_path = /obj/item/circuitboard/miningdrill
sort_string = "KCAAA"
/datum/design/circuit/miningdrillbrace
name = "mining drill brace"
id = "mining drill brace"
req_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
build_path = /obj/item/circuitboard/miningdrillbrace
sort_string = "KCAAB"
/datum/design/circuit/comconsole
name = "communications console"
id = "comconsole"
build_path = /obj/item/circuitboard/communications
sort_string = "LAAAA"
/datum/design/circuit/idcardconsole
name = "ID card modification console"
id = "idcardconsole"
build_path = /obj/item/circuitboard/card
sort_string = "LAAAB"
/datum/design/circuit/emp_data
name = "employment records console"
id = "emp_data"
build_path = /obj/item/circuitboard/skills
sort_string = "LAAAC"
/datum/design/circuit/arf_generator
name = "atmospheric field generator"
id = "arf_generator"
req_tech = list(TECH_MAGNET = 4, TECH_POWER = 4, TECH_BIO = 3)
build_path = /obj/item/circuitboard/arf_generator
sort_string = "LAAAD"
/datum/design/circuit/protean_reconstitutor
name = "protean reconstitutor"
id = "protean_recon"
req_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_DATA = 5)
build_path = /obj/item/circuitboard/protean_reconstitutor
sort_string = "LAAAE"
/datum/design/circuit/mecha
req_tech = list(TECH_DATA = 3)
/datum/design/circuit/mecha/AssembleDesignName()
name = "Exosuit module circuit design ([name])"
/datum/design/circuit/mecha/AssembleDesignDesc()
desc = "Allows for the construction of \a [name] module."
/datum/design/circuit/mecha/ripley_main
name = "APLU 'Ripley' central control"
id = "ripley_main"
build_path = /obj/item/circuitboard/mecha/ripley/main
sort_string = "NAAAA"
/datum/design/circuit/mecha/ripley_peri
name = "APLU 'Ripley' peripherals control"
id = "ripley_peri"
build_path = /obj/item/circuitboard/mecha/ripley/peripherals
sort_string = "NAAAB"
/datum/design/circuit/mecha/odysseus_main
name = "'Odysseus' central control"
id = "odysseus_main"
req_tech = list(TECH_DATA = 3,TECH_BIO = 2)
build_path = /obj/item/circuitboard/mecha/odysseus/main
sort_string = "NAABA"
/datum/design/circuit/mecha/odysseus_peri
name = "'Odysseus' peripherals control"
id = "odysseus_peri"
req_tech = list(TECH_DATA = 3,TECH_BIO = 2)
build_path = /obj/item/circuitboard/mecha/odysseus/peripherals
sort_string = "NAABB"
/datum/design/circuit/mecha/gygax_main
name = "'Gygax' central control"
id = "gygax_main"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/mecha/gygax/main
sort_string = "NAACA"
/datum/design/circuit/mecha/gygax_peri
name = "'Gygax' peripherals control"
id = "gygax_peri"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/mecha/gygax/peripherals
sort_string = "NAACB"
/datum/design/circuit/mecha/gygax_targ
name = "'Gygax' weapon control and targeting"
id = "gygax_targ"
req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2)
build_path = /obj/item/circuitboard/mecha/gygax/targeting
sort_string = "NAACC"
/datum/design/circuit/mecha/gygax_medical
name = "'Serenity' medical control"
id = "gygax_medical"
req_tech = list(TECH_DATA = 4, TECH_BIO = 2)
build_path = /obj/item/circuitboard/mecha/gygax/medical
sort_string = "NAACD"
/datum/design/circuit/mecha/durand_main
name = "'Durand' central control"
id = "durand_main"
req_tech = list(TECH_DATA = 4)
materials = list(MAT_GLASS = 2000, MAT_GRAPHITE = 1250)
chemicals = list(REAGENT_ID_SACID = 20)
build_path = /obj/item/circuitboard/mecha/durand/main
sort_string = "NAADA"
/datum/design/circuit/mecha/durand_peri
name = "'Durand' peripherals control"
id = "durand_peri"
req_tech = list(TECH_DATA = 4)
materials = list(MAT_GLASS = 2000, MAT_GRAPHITE = 1250)
chemicals = list(REAGENT_ID_SACID = 20)
build_path = /obj/item/circuitboard/mecha/durand/peripherals
sort_string = "NAADB"
/datum/design/circuit/mecha/durand_targ
name = "'Durand' weapon control and targeting"
id = "durand_targ"
req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2)
materials = list(MAT_GLASS = 2000, MAT_GRAPHITE = 1250)
chemicals = list(REAGENT_ID_SACID = 20)
build_path = /obj/item/circuitboard/mecha/durand/targeting
sort_string = "NAADC"
/datum/design/circuit/tcom
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4)
/datum/design/circuit/tcom/AssembleDesignName()
name = "Telecommunications machinery circuit design ([name])"
/datum/design/circuit/tcom/AssembleDesignDesc()
desc = "Allows for the construction of a telecommunications [name] circuit board."
/datum/design/circuit/tcom/server
name = "server mainframe"
id = "tcom-server"
build_path = /obj/item/circuitboard/telecomms/server
sort_string = "PAAAA"
/datum/design/circuit/tcom/processor
name = "processor unit"
id = "tcom-processor"
build_path = /obj/item/circuitboard/telecomms/processor
sort_string = "PAAAB"
/datum/design/circuit/tcom/bus
name = "bus mainframe"
id = "tcom-bus"
build_path = /obj/item/circuitboard/telecomms/bus
sort_string = "PAAAC"
/datum/design/circuit/tcom/hub
name = "hub mainframe"
id = "tcom-hub"
build_path = /obj/item/circuitboard/telecomms/hub
sort_string = "PAAAD"
/datum/design/circuit/tcom/relay
name = "relay mainframe"
id = "tcom-relay"
req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 4, TECH_BLUESPACE = 3)
build_path = /obj/item/circuitboard/telecomms/relay
sort_string = "PAAAE"
/datum/design/circuit/tcom/broadcaster
name = "subspace broadcaster"
id = "tcom-broadcaster"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4, TECH_BLUESPACE = 2)
build_path = /obj/item/circuitboard/telecomms/broadcaster
sort_string = "PAAAF"
/datum/design/circuit/tcom/receiver
name = "subspace receiver"
id = "tcom-receiver"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_BLUESPACE = 2)
build_path = /obj/item/circuitboard/telecomms/receiver
sort_string = "PAAAG"
/datum/design/circuit/tcom/exonet_node
name = "exonet node"
id = "tcom-exonet_node"
req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5, TECH_BLUESPACE = 4)
build_path = /obj/item/circuitboard/telecomms/exonet_node
sort_string = "PAAAH"
/datum/design/circuit/shield
req_tech = list(TECH_BLUESPACE = 4, TECH_PHORON = 3)
materials = list(MAT_GLASS = 2000, MAT_GOLD = 1000)
/datum/design/circuit/shield/AssembleDesignName()
name = "Shield generator circuit design ([name])"
/datum/design/circuit/shield/AssembleDesignDesc()
if(!desc)
desc = "Allows for the construction of \a [name] shield generator."
/datum/design/circuit/shield/bubble
name = "bubble (OBSOLETE)" //VOREStation Edit
id = "shield_gen"
build_path = /obj/item/circuitboard/shield_gen
sort_string = "VAAAZ" // Duplicate string, really need to redo this whole thing
/datum/design/circuit/shield/hull
name = "hull (OBSOLETE)" //VOREStation Edit
id = "shield_gen_ex"
build_path = /obj/item/circuitboard/shield_gen_ex
sort_string = "VAAAB"
/datum/design/circuit/shield/capacitor
name = "capacitor (OBSOLETE)" //VOREStation Edit"
desc = "Allows for the construction of a shield capacitor circuit board."
id = "shield_cap"
req_tech = list(TECH_MAGNET = 3, TECH_POWER = 4)
build_path = /obj/item/circuitboard/shield_cap
sort_string = "VAAAC"
/datum/design/circuit/ntnet_relay
name = "NTNet Quantum Relay"
id = "ntnet_relay"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/ntnet_relay
sort_string = "WAAAA"
/datum/design/circuit/aicore
name = "AI core"
id = "aicore"
req_tech = list(TECH_DATA = 4, TECH_BIO = 3)
build_path = /obj/item/circuitboard/aicore
sort_string = "XAAAA"
// Cooking Appliances
/datum/design/circuit/microwave
name = "microwave board"
id = "microwave_board"
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/microwave
sort_string = "HACAM"
/datum/design/circuit/oven
name = "oven board"
id = "oven_board"
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/oven
sort_string = "HACAN"
/datum/design/circuit/fryer
name = "deep fryer board"
id = "fryer_board"
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/fryer
sort_string = "HACAO"
/datum/design/circuit/cerealmaker
name = "cereal maker board"
id = "cerealmaker_board"
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/cerealmaker
sort_string = "HACAP"
/datum/design/circuit/candymaker
name = "candy machine board"
id = "candymachine_board"
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/candymachine
sort_string = "HACAQ"
/datum/design/circuit/microwave/advanced
name = "deluxe microwave"
id = "deluxe microwave"
req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5, TECH_BLUESPACE = 4)
build_path = /obj/item/circuitboard/microwave/advanced
sort_string = "HACAA"
/datum/design/circuit/shield_generator
name = "shield generator"
id = "shield_generator"
req_tech = list(TECH_MAGNET = 3, TECH_POWER = 4, TECH_BLUESPACE = 2, TECH_ENGINEERING = 3)
build_path = /obj/item/circuitboard/shield_generator
sort_string = "OAAAA"
/datum/design/circuit/shield_diffuser
name = "shield diffuser"
id = "shield_diffuser"
req_tech = list(TECH_MAGNET = 4, TECH_POWER = 2, TECH_ENGINEERING = 5)
build_path = /obj/item/circuitboard/shield_diffuser
sort_string = "OAAAB"
/datum/design/circuit/pointdefense
name = "point defense battery"
id = "pointdefense"
req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 3, TECH_COMBAT = 4)
build_path = /obj/item/circuitboard/pointdefense
sort_string = "OAABA"
/datum/design/circuit/pointdefense_control
name = "point defense control"
id = "pointdefense_control"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_COMBAT = 2)
build_path = /obj/item/circuitboard/pointdefense_control
sort_string = "OAABB"
/datum/design/circuit/recycler_crusher
name = "recycler - crusher"
id = "recycler_crusher"
req_tech = list(TECH_MATERIAL = 2)
build_path = /obj/item/circuitboard/recycler_crusher
sort_string = "OAABC"
/datum/design/circuit/recycler_sorter
name = "recycler - sorter"
id = "recycler_sorter"
req_tech = list(TECH_MATERIAL = 2)
build_path = /obj/item/circuitboard/recycler_sorter
sort_string = "OAABD"
/datum/design/circuit/recycler_stamper
name = "recycler - stamper"
id = "recycler_stamper"
req_tech = list(TECH_MATERIAL = 2)
build_path = /obj/item/circuitboard/recycler_stamper
sort_string = "OAABE"
///Fighters///
//Pinnace//
/datum/design/circuit/mecha/fighter/pinnace_main
name = "Pinnace central control board"
id = "pinnace_main"
req_tech = list(TECH_DATA = 3, TECH_POWER = 4)
build_path = /obj/item/circuitboard/mecha/fighter/pinnace/main
sort_string = "NAAGA"
/datum/design/circuit/mecha/fighter/pinnace_flight
name = "Pinnace flight control board"
id = "pinnace_flight"
req_tech = list(TECH_DATA = 3, TECH_POWER = 4)
build_path = /obj/item/circuitboard/mecha/fighter/pinnace/flight
sort_string = "NAAGB"
/datum/design/circuit/mecha/fighter/pinnace_targeting
name = "Pinnace weapon control and targeting board"
id = "pinnace_targeting"
req_tech = list(TECH_DATA = 3, TECH_POWER = 4)
build_path = /obj/item/circuitboard/mecha/fighter/pinnace/targeting
sort_string = "NAAGC"
/datum/design/circuit/mecha/fighter/pinnace_cockpit_control
name = "Pinnace manual flight control instruments"
id = "pinnace_cockpit_control"
req_tech = list(TECH_DATA = 3, TECH_POWER = 4)
build_path = /obj/item/circuitboard/mecha/fighter/pinnace/cockpitboard
sort_string = "NAAGD"
//Baron//
/datum/design/circuit/mecha/fighter/baron_main
name = "Baron central control board"
id = "baron_main"
req_tech = list(TECH_DATA = 5, TECH_POWER = 4)
build_path = /obj/item/circuitboard/mecha/fighter/baron/main
sort_string = "NAAHA"
/datum/design/circuit/mecha/fighter/baron_flight
name = "Baron flight control board"
id = "baron_flight"
req_tech = list(TECH_DATA = 5, TECH_POWER = 4)
build_path = /obj/item/circuitboard/mecha/fighter/baron/flight
sort_string = "NAAHB"
/datum/design/circuit/mecha/fighter/baron_targeting
name = "Baron weapon control and targeting board"
id = "baron_targeting"
req_tech = list(TECH_DATA = 5, TECH_POWER = 4, TECH_COMBAT = 3)
build_path = /obj/item/circuitboard/mecha/fighter/baron/targeting
sort_string = "NAAHC"
/datum/design/circuit/mecha/fighter/baron_cockpit_control
name = "Baron manual flight control instruments"
id = "baron_cockpit_control"
req_tech = list(TECH_DATA = 5, TECH_POWER = 4, TECH_COMBAT = 3)
build_path = /obj/item/circuitboard/mecha/fighter/baron/cockpitboard
sort_string = "NAAHD"
@@ -1,191 +0,0 @@
/datum/design/circuit/algae_farm
name = "Algae Oxygen Generator"
id = "algae_farm"
req_tech = list(TECH_ENGINEERING = 3, TECH_BIO = 2)
build_path = /obj/item/circuitboard/algae_farm
sort_string = "HABAE"
/datum/design/circuit/thermoregulator
name = "thermal regulator"
id = "thermoregulator"
req_tech = list(TECH_ENGINEERING = 4, TECH_POWER = 3)
build_path = /obj/item/circuitboard/thermoregulator
sort_string = "HABAF"
/datum/design/circuit/bomb_tester
name = "Explosive Effect Simulator"
id = "bomb_tester"
req_tech = list(TECH_PHORON = 3, TECH_DATA = 2, TECH_MAGNET = 2)
build_path = /obj/item/circuitboard/bomb_tester
sort_string = "HABAG"
/datum/design/circuit/quantum_pad
name = "Quantum Pad"
id = "quantum_pad"
req_tech = list(TECH_ENGINEERING = 4, TECH_POWER = 4, TECH_BLUESPACE = 4)
build_path = /obj/item/circuitboard/quantumpad
sort_string = "HABAH"
//////Micro mech stuff
/datum/design/circuit/mecha/gopher_main
name = "'Gopher' central control"
id = "gopher_main"
build_path = /obj/item/circuitboard/mecha/gopher/main
sort_string = "NAAEA"
/datum/design/circuit/mecha/gopher_peri
name = "'Gopher' peripherals control"
id = "gopher_peri"
build_path = /obj/item/circuitboard/mecha/gopher/peripherals
sort_string = "NAAEB"
/datum/design/circuit/mecha/polecat_main
name = "'Polecat' central control"
id = "polecat_main"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/mecha/polecat/main
sort_string = "NAAFA"
/datum/design/circuit/mecha/polecat_peri
name = "'Polecat' peripherals control"
id = "polecat_peri"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/mecha/polecat/peripherals
sort_string = "NAAFB"
/datum/design/circuit/mecha/polecat_targ
name = "'Polecat' weapon control and targeting"
id = "polecat_targ"
req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2)
build_path = /obj/item/circuitboard/mecha/polecat/targeting
sort_string = "NAAFC"
/datum/design/circuit/mecha/weasel_main
name = "'Weasel' central control"
id = "weasel_main"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/mecha/weasel/main
sort_string = "NAAGA"
/datum/design/circuit/mecha/weasel_peri
name = "'Weasel' peripherals control"
id = "weasel_peri"
req_tech = list(TECH_DATA = 4)
build_path = /obj/item/circuitboard/mecha/weasel/peripherals
sort_string = "NAAGB"
/datum/design/circuit/mecha/weasel_targ
name = "'Weasel' weapon control and targeting"
id = "weasel_targ"
req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2)
build_path = /obj/item/circuitboard/mecha/weasel/targeting
sort_string = "NAAGC"
/datum/design/circuit/transhuman_clonepod
name = "grower pod"
id = "transhuman_clonepod"
req_tech = list(TECH_DATA = 3, TECH_BIO = 3)
build_path = /obj/item/circuitboard/transhuman_clonepod
sort_string = "HAADA"
/datum/design/circuit/transhuman_synthprinter
name = "SynthFab 3000"
id = "transhuman_synthprinter"
req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3)
build_path = /obj/item/circuitboard/transhuman_synthprinter
sort_string = "HAADB"
/datum/design/circuit/transhuman_resleever
name = "Resleeving pod"
id = "transhuman_resleever"
req_tech = list(TECH_ENGINEERING = 4, TECH_BIO = 4)
build_path = /obj/item/circuitboard/transhuman_resleever
sort_string = "HAADC"
// Resleeving
/datum/design/circuit/resleeving_control
name = "Resleeving control console"
id = "resleeving_control"
req_tech = list(TECH_DATA = 5)
build_path = /obj/item/circuitboard/resleeving_control
sort_string = "HAADE"
/datum/design/circuit/body_designer
name = "Body design console"
id = "body_designer"
req_tech = list(TECH_DATA = 5)
build_path = /obj/item/circuitboard/body_designer
sort_string = "HAADF"
/datum/design/circuit/partslathe
name = "Parts lathe"
id = "partslathe"
req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/partslathe
sort_string = "HABAD"
// Telesci stuff
/datum/design/circuit/telesci_console
name = "Telepad Control Console"
id = "telesci_console"
req_tech = list(TECH_DATA = 3, TECH_BLUESPACE = 3, TECH_PHORON = 4)
build_path = /obj/item/circuitboard/telesci_console
sort_string = "HAAEA"
/datum/design/circuit/telesci_pad
name = "Telepad"
id = "telesci_pad"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4, TECH_PHORON = 4, TECH_BLUESPACE = 5)
build_path = /obj/item/circuitboard/telesci_pad
sort_string = "HAAEB"
/datum/design/circuit/quantum_pad
name = "Quantum Pad"
id = "quantum_pad"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4, TECH_PHORON = 4, TECH_BLUESPACE = 5)
build_path = /obj/item/circuitboard/quantumpad
sort_string = "HAAC"
/datum/design/circuit/rtg
name = "radioisotope TEG"
id = "rtg"
req_tech = list(TECH_DATA = 3, TECH_POWER = 3, TECH_PHORON = 3, TECH_ENGINEERING = 3)
build_path = /obj/item/circuitboard/machine/rtg
sort_string = "HAAD"
/datum/design/circuit/rtg_advanced
name = "advanced radioisotope TEG"
id = "adv_rtg"
req_tech = list(TECH_DATA = 5, TECH_POWER = 5, TECH_PHORON = 5, TECH_ENGINEERING = 5)
build_path = /obj/item/circuitboard/machine/rtg/advanced
sort_string = "HAAE"
/datum/design/circuit/rtg
name = "vitals monitor"
id = "vitals"
req_tech = list(TECH_DATA = 3, TECH_BIO = 4, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/machine/vitals_monitor
sort_string = "HAAF"
/datum/design/circuit/firework_launcher
name = "firework launcher"
id = "fireworklauncher"
req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
build_path = /obj/item/circuitboard/firework_launcher
sort_string = "KBAAB"
/datum/design/circuit/pointdefense
name = "point defense battery"
id = "pointdefense"
req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 3, TECH_COMBAT = 4)
build_path = /obj/item/circuitboard/pointdefense
sort_string = "OAABA"
/datum/design/circuit/pointdefense_control
name = "point defense control"
id = "pointdefense_control"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_COMBAT = 2)
build_path = /obj/item/circuitboard/pointdefense_control
sort_string = "OAABB"
@@ -1,46 +0,0 @@
/datum/design/circuit/disk
build_type = IMPRINTER
req_tech = list(TECH_DATA = 3)
materials = list(MAT_PLASTIC = 2000, MAT_GLASS = 1000)
chemicals = list(REAGENT_ID_PACID = 10)
time = 5
/datum/design/circuit/disk/AssembleDesignName()
..()
if(build_path)
var/obj/item/disk/D = build_path
if(istype(D, /obj/item/disk/species))
name = "Species Prosthetic design ([item_name])"
else if(istype(D, /obj/item/disk/limb))
name = "Transtellar Prosthetic design ([item_name])"
else
name = "Disk design ([item_name])"
/datum/design/circuit/disk/skrellprint
name = SPECIES_SKRELL
id = "prosthetic_skrell"
req_tech = list(TECH_DATA = 3, TECH_BIO = 3)
build_path = /obj/item/disk/species/skrell
sort_string = "DBAAA"
/datum/design/circuit/disk/tajprint
name = SPECIES_TAJARAN
id = "prosthetic_tajaran"
req_tech = list(TECH_DATA = 3, TECH_BIO = 3)
build_path = /obj/item/disk/species/tajaran
sort_string = "DBAAB"
/datum/design/circuit/disk/unathiprint
name = SPECIES_UNATHI
id = "prosthetic_unathi"
req_tech = list(TECH_DATA = 3, TECH_BIO = 4)
build_path = /obj/item/disk/species/unathi
sort_string = "DBAAC"
/datum/design/circuit/disk/teshariprint
name = SPECIES_TESHARI
id = "prosthetic_teshari"
req_tech = list(TECH_DATA = 3, TECH_BIO = 4)
build_path = /obj/item/disk/species/teshari
sort_string = "DBAAD"
@@ -1,92 +0,0 @@
// Tools
/datum/design/item/tool/AssembleDesignName()
..()
name = "Experimental tool prototype ([item_name])"
/datum/design/item/tool/experimental_welder
name = "Experimental welding tool"
desc = "A welding tool that generate fuel for itself."
id = "expwelder"
req_tech = list(TECH_ENGINEERING = 4, TECH_PHORON = 3, TECH_MATERIAL = 4)
materials = list(MAT_STEEL = 70, MAT_GLASS = 120, MAT_PHORON = 100)
build_path = /obj/item/weldingtool/experimental
sort_string = "NAAAA"
/datum/design/item/tool/hand_drill
name = "Hand drill"
desc = "A simple powered hand drill."
id = "handdrill"
req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 300, MAT_SILVER = 100)
build_path = /obj/item/tool/transforming/powerdrill
sort_string = "NAAAB"
/datum/design/item/tool/jaws_life
name = "Jaws of life"
desc = "A set of jaws of life, compressed through the magic of science."
id = "jawslife"
req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 300, MAT_SILVER = 100)
build_path = /obj/item/tool/transforming/jawsoflife
sort_string = "NAAAC"
/datum/design/item/tool/rpd
name = "Rapid Pipe Dispenser"
desc = "A counterpart to the rapid construction device that allows creating and placing atmospheric and disposal pipes."
id = "rapidpipedispenser"
req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 2000)
build_path = /obj/item/pipe_dispenser
sort_string = "NAAAD"
/datum/design/item/tool/qpad_booster
name = "Quantum Pad Particle Booster"
desc = "A deceptively simple interface for increasing the mass of objects a quantum pad is capable of teleporting, at the cost of increased power draw."
id = "qpad_booster"
req_tech = list(TECH_ENGINEERING = 7, TECH_MATERIAL = 7, TECH_BLUESPACE = 6)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 2000, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_VERDANTIUM = 1000)
build_path = /obj/item/quantum_pad_booster
sort_string = "NAAAF"
// Other devices
/datum/design/item/engineering/AssembleDesignName()
..()
name = "Engineering device prototype ([item_name])"
/datum/design/item/engineering/t_scanner
name = "T-ray Scanner"
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
id = "tscanner"
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2, TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 200)
build_path = /obj/item/t_scanner
sort_string = "NBAAA"
/datum/design/item/engineering/t_scanner_upg
name = "Upgraded T-ray Scanner"
desc = "An upgraded version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
id = "upgradedtscanner"
req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 4, TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 500, MAT_PHORON = 150)
build_path = /obj/item/t_scanner/upgraded
sort_string = "NBAAB"
/datum/design/item/engineering/t_scanner_adv
name = "Advanced T-ray Scanner"
desc = "An advanced version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
id = "advancedtscanner"
req_tech = list(TECH_MAGNET = 6, TECH_ENGINEERING = 6, TECH_MATERIAL = 6)
materials = list(MAT_STEEL = 1250, MAT_PHORON = 500, MAT_SILVER = 50)
build_path = /obj/item/t_scanner/advanced
sort_string = "NBAAC"
/datum/design/item/engineering/atmosanalyzer
name = "Analyzer"
desc = "A hand-held environmental scanner which reports current gas levels."
id = "atmosanalyzer"
req_tech = list(TECH_ENGINEERING = 2)
materials = list(MAT_STEEL = 200, MAT_GLASS = 100)
build_path = /obj/item/analyzer
sort_string = "NBABA"
-114
View File
@@ -1,114 +0,0 @@
// Implants
/datum/design/item/implant
materials = list(MAT_STEEL = 50, MAT_GLASS = 50)
/datum/design/item/implant/AssembleDesignName()
..()
name = "Implantable biocircuit design ([item_name])"
/datum/design/item/implant/chemical
name = "chemical"
id = "implant_chem"
req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3)
build_path = /obj/item/implantcase/chem
sort_string = "MFAAA"
/datum/design/item/implant/freedom
name = "freedom"
id = "implant_free"
req_tech = list(TECH_ILLEGAL = 2, TECH_BIO = 3)
build_path = /obj/item/implantcase/freedom
sort_string = "MFAAB"
/datum/design/item/organ/internal/augment/AssembleDesignName()
..()
name = "Biotech implant device prototype ([item_name])"
/datum/design/item/organ/internal/augment/armmounted/hand
desc = "An augment that fits neatly into the hand, useful for determining the usefulness of an object for research."
id = "research_implant"
req_tech = list(TECH_BIO = 5, TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 3000, MAT_GLASS = 3000)
build_path = /obj/item/organ/internal/augment/armmounted/hand
sort_string = "JVACE"
/datum/design/item/organ/internal/augment/armmounted/shoulder/multiple
desc = "A large implant that fits into a subject's arm. It deploys an array of tools by some painful means."
id = "tool_implant"
req_tech = list(TECH_BIO = 5, TECH_MATERIAL = 2, TECH_ENGINEERING = 3)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000)
build_path = /obj/item/organ/internal/augment/armmounted/shoulder/multiple
sort_string = "JVACI"
/datum/design/item/organ/internal/augment/armmounted/shoulder/multiple/medical
desc = "A large implant that fits into a subject's arm. It deploys an array of tools by some painful means."
id = "surgical_implant"
req_tech = list(TECH_BIO = 6, TECH_MATERIAL = 4)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000, MAT_SILVER = 1000)
build_path = /obj/item/organ/internal/augment/armmounted/shoulder/multiple/medical
sort_string = "JVACJ"
/datum/design/item/organ/internal/augment/armmounted/hand/blade
desc = "A large implant that fits into a subject's hand. It deploys a bladed weapon."
id = "blade_implant"
req_tech = list(TECH_BIO = 5, TECH_MATERIAL = 4, TECH_COMBAT = 4)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000, MAT_SILVER = 1000)
build_path = /obj/item/organ/internal/augment/armmounted/hand/blade
sort_string = "JVACK"
/datum/design/item/organ/internal/augment/armmounted/shoulder/blade
desc = "A large implant that fits into a subject's arm. It deploys a large, bladed weapon."
id = "armblade_implant"
req_tech = list(TECH_BIO = 5, TECH_MATERIAL = 5, TECH_COMBAT = 6)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000, MAT_SILVER = 1000, MAT_GOLD = 2000)
build_path = /obj/item/organ/internal/augment/armmounted/shoulder/blade
sort_string = "JVACL"
/datum/design/item/organ/internal/augment/armmounted/hand/sword
desc = "A large implant that fits into a subject's hand. It deploys a large, energetic weapon."
id = "sword_implant"
req_tech = list(TECH_BIO = 5, TECH_MATERIAL = 6, TECH_COMBAT = 6, TECH_ENGINEERING = 5, TECH_ILLEGAL = 2)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000, MAT_SILVER = 1000, MAT_GOLD = 2000, MAT_DIAMOND = 2000)
build_path = /obj/item/organ/internal/augment/armmounted/hand/sword
sort_string = "JVACM"
/datum/design/item/organ/internal/augment/armmounted/dartbow
desc = "A large implant that fits into a subject's arm. It creates a dartbow when activated."
id = "dartbow_implant"
req_tech = list(TECH_BIO = 5, TECH_MATERIAL = 4, TECH_COMBAT = 6, TECH_ILLEGAL = 3)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000, MAT_PHORON = 4000, MAT_GOLD = 4000, MAT_DIAMOND = 6000)
build_path = /obj/item/organ/internal/augment/armmounted/dartbow
sort_string = "JVACN"
/datum/design/item/organ/internal/augment/armmounted/taser
desc = "A large implant that fits into a subject's arm. It turns into a taser when activated."
id = "taser_implant"
req_tech = list(TECH_BIO = 5, TECH_MATERIAL = 4, TECH_COMBAT = 4)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000, MAT_SILVER = 2000, MAT_GOLD = 1000)
build_path = /obj/item/organ/internal/augment/armmounted/taser
sort_string = "JVACO"
/datum/design/item/organ/internal/augment/armmounted/laser
desc = "A large implant that fits into a subject's arm. It turns into a laser when activated."
id = "laser_implant"
req_tech = list(TECH_BIO = 5, TECH_MATERIAL = 4, TECH_COMBAT = 6)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000, MAT_SILVER = 6000, MAT_GOLD = 4000, MAT_DIAMOND = 4000, MAT_PHORON = 2000)
build_path = /obj/item/organ/internal/augment/armmounted
sort_string = "JVACP"
/datum/design/item/organ/internal/augment/armmounted/shoulder/surge
desc = "A large implant that fits into a subject's arm. It floods the subject with stimulants to speed them up."
id = "surge_implant"
req_tech = list(TECH_BIO = 5, TECH_MATERIAL = 4, TECH_POWER = 4)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000, MAT_PHORON = 1000, MAT_GOLD = 2000)
build_path = /obj/item/organ/internal/augment/armmounted/shoulder/surge
sort_string = "JVACQ"
/datum/design/item/internal/augment/bioaugment/thermalshades
desc = "A large implant that fits into a subject's eyes. It allows them to see through walls."
id = "thermal_implant"
req_tech = list(TECH_BIO = 7, TECH_MATERIAL = 4, TECH_POWER = 7, TECH_ENGINEERING = 7, TECH_COMBAT = 5, TECH_ILLEGAL = 2)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 6000, MAT_PHORON = 10000, MAT_GOLD = 2000, MAT_DIAMOND = 10000, MAT_SILVER = 4000, MAT_TITANIUM = 1000) //this is thermals. this is expensive, yo.
build_path = /obj/item/organ/internal/augment/bioaugment/thermalshades
sort_string = "JVACR"
@@ -1,15 +0,0 @@
/datum/design/item/implant/backup
name = "Backup implant"
id = "implant_backup"
req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2, TECH_DATA = 4, TECH_ENGINEERING = 2)
materials = list(MAT_STEEL = 2000, MAT_GLASS = 2000)
build_path = /obj/item/implantcase/backup
sort_string = "MFAVA"
/datum/design/item/implant/sizecontrol
name = "Size control implant"
id = "implant_size"
req_tech = list(TECH_MATERIAL = 3, TECH_BIO = 4, TECH_DATA = 4, TECH_ENGINEERING = 3)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 4000)
build_path = /obj/item/implanter/sizecontrol
sort_string = "MFAVB"
@@ -1,80 +0,0 @@
// GPS
/datum/design/item/gps
req_tech = list(TECH_MATERIAL = 2, TECH_DATA = 2, TECH_BLUESPACE = 2)
materials = list(MAT_STEEL = 500)
/datum/design/item/gps/AssembleDesignName()
..()
name = "Triangulating device design (GPS - [name])"
/datum/design/item/gps/generic
name = "GEN"
id = "gps_gen"
build_path = /obj/item/gps
sort_string = "DAAAA"
/datum/design/item/gps/command
name = "COM"
id = "gps_com"
build_path = /obj/item/gps/command
sort_string = "DAAAB"
/datum/design/item/gps/security
name = "SEC"
id = "gps_sec"
build_path = /obj/item/gps/security
sort_string = "DAAAC"
/datum/design/item/gps/medical
name = "MED"
id = "gps_med"
build_path = /obj/item/gps/medical
sort_string = "DAAAD"
/datum/design/item/gps/engineering
name = "ENG"
id = "gps_eng"
build_path = /obj/item/gps/engineering
sort_string = "DAAAE"
/datum/design/item/gps/science
name = "SCI"
id = "gps_sci"
build_path = /obj/item/gps/science
sort_string = "DAAAF"
/datum/design/item/gps/mining
name = "MINE"
id = "gps_mine"
build_path = /obj/item/gps/mining
sort_string = "DAAAG"
/datum/design/item/gps/explorer
name = "EXP"
id = "gps_exp"
build_path = /obj/item/gps/explorer
sort_string = "DAAAH"
// Other locators
/datum/design/item/locator/AssembleDesignName()
..()
name = "Locator device design ([name])"
/datum/design/item/locator/beacon_locator
name = "Tracking beacon pinpointer"
desc = "Used to scan and locate signals on a particular frequency."
id = "beacon_locator"
req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 2, TECH_BLUESPACE = 3)
materials = list(MAT_STEEL = 1000,MAT_GLASS = 500)
build_path = /obj/item/beacon_locator
sort_string = "DBAAA"
/datum/design/item/locator/beacon
name = "Bluespace tracking beacon"
id = "beacon"
req_tech = list(TECH_BLUESPACE = 1)
materials = list (MAT_STEEL = 20, MAT_GLASS = 10)
build_path = /obj/item/radio/beacon
sort_string = "DBABA"
-114
View File
@@ -1,114 +0,0 @@
/datum/design/item/medical
materials = list(MAT_STEEL = 30, MAT_GLASS = 20)
/datum/design/item/medical/AssembleDesignName()
..()
name = "Medical equipment prototype ([item_name])"
// Surgical devices
/datum/design/item/medical/scalpel_laser1
name = "Basic Laser Scalpel"
desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks basic and could be improved."
id = "scalpel_laser1"
req_tech = list(TECH_BIO = 2, TECH_MATERIAL = 2, TECH_MAGNET = 2)
materials = list(MAT_STEEL = 12500, MAT_GLASS = 7500)
build_path = /obj/item/surgical/scalpel/laser1
sort_string = "KAAAA"
/datum/design/item/medical/scalpel_laser2
name = "Improved Laser Scalpel"
desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks somewhat advanced."
id = "scalpel_laser2"
req_tech = list(TECH_BIO = 3, TECH_MATERIAL = 4, TECH_MAGNET = 4)
materials = list(MAT_STEEL = 12500, MAT_GLASS = 7500, MAT_SILVER = 2500)
build_path = /obj/item/surgical/scalpel/laser2
sort_string = "KAAAB"
/datum/design/item/medical/scalpel_laser3
name = "Advanced Laser Scalpel"
desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks to be the pinnacle of precision energy cutlery!"
id = "scalpel_laser3"
req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 6, TECH_MAGNET = 5)
materials = list(MAT_STEEL = 12500, MAT_GLASS = 7500, MAT_SILVER = 2000, MAT_GOLD = 1500)
build_path = /obj/item/surgical/scalpel/laser3
sort_string = "KAAAC"
/datum/design/item/medical/scalpel_manager
name = "Incision Management System"
desc = "A true extension of the surgeon's body, this marvel instantly and completely prepares an incision allowing for the immediate commencement of therapeutic steps."
id = "scalpel_manager"
req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 7, TECH_MAGNET = 5, TECH_DATA = 4)
materials = list (MAT_STEEL = 12500, MAT_GLASS = 7500, MAT_SILVER = 1500, MAT_GOLD = 1500, MAT_DIAMOND = 750)
build_path = /obj/item/surgical/scalpel/manager
sort_string = "KAAAD"
/datum/design/item/medical/saw_manager
name = "Energetic Bone Diverter"
desc = "A strange development following the I.M.S., this heavy tool can split and open, or close and shut, intentional holes in bones."
id = "advanced_saw"
req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 7, TECH_MAGNET = 6, TECH_DATA = 5)
materials = list (MAT_STEEL = 12500, MAT_PLASTIC = 800, MAT_SILVER = 1500, MAT_GOLD = 1500, MAT_OSMIUM = 1000)
build_path = /obj/item/surgical/circular_saw/manager
sort_string = "KAAAE"
/datum/design/item/medical/organ_ripper
name = "Organ Ripper"
desc = "A modern and horrifying take on an ancient practice, this tool is capable of rapidly removing an organ from a hopefully willing patient, without damaging it."
id = "organ_ripper"
req_tech = list(TECH_BIO = 3, TECH_MATERIAL = 5, TECH_MAGNET = 4, TECH_ILLEGAL = 3)
materials = list (MAT_STEEL = 12500, MAT_PLASTIC = 8000, MAT_OSMIUM = 2500)
build_path = /obj/item/surgical/scalpel/ripper
sort_string = "KAAAF"
/datum/design/item/medical/bone_clamp
name = "Bone Clamp"
desc = "A miracle of modern science, this tool rapidly knits together bone, without the need for bone gel."
id = "bone_clamp"
req_tech = list(TECH_BIO = 4, TECH_MATERIAL = 5, TECH_MAGNET = 4, TECH_DATA = 4)
materials = list (MAT_STEEL = 12500, MAT_GLASS = 7500, MAT_SILVER = 2500)
build_path = /obj/item/surgical/bone_clamp
sort_string = "KAABA"
/datum/design/item/medical/medical_analyzer
name = "health analyzer"
desc = "A hand-held body scanner able to distinguish vital signs of the subject."
id = "medical_analyzer"
req_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
materials = list(MAT_STEEL = 500, MAT_GLASS = 500)
build_path = /obj/item/healthanalyzer
sort_string = "KBAAA"
/datum/design/item/medical/improved_analyzer
name = "improved health analyzer"
desc = "A prototype version of the regular health analyzer, able to distinguish the location of more serious injuries as well as accurately determine radiation levels."
id = "improved_analyzer"
req_tech = list(TECH_MAGNET = 5, TECH_BIO = 6)
materials = list(MAT_STEEL = 2000, MAT_GLASS = 1000, MAT_SILVER = 1000, MAT_GOLD = 1500)
build_path = /obj/item/healthanalyzer/improved
sort_string = "KBAAB"
/datum/design/item/medical/advanced_analyzer
name = "advanced health analyzer"
desc = "An even more advanced handheld health scanner, complete with a full biosign monitor and on-board radiation and neurological analysis suites."
id = "advanced_analyzer"
req_tech = list(TECH_MAGNET = 7, TECH_BIO = 7, TECH_DATA = 5)
materials = list(MAT_STEEL = 2000, MAT_GLASS = 4000, MAT_SILVER = 3500, MAT_GOLD = 2500, MAT_DIAMOND = 1250)
build_path = /obj/item/healthanalyzer/advanced
sort_string = "KBAAC"
/datum/design/item/medical/gene_scanner
name = "Gene Scanner"
id = "gene_scanner"
req_tech = list(TECH_DATA = 1, TECH_BIO = 2)
build_path = /obj/item/gene_scanner
sort_string = "KBAAD"
/datum/design/item/medical/advanced_roller
name = "advanced roller bed"
desc = "A more advanced version of the regular roller bed, with inbuilt surgical stabilisers and an improved folding system."
id = "roller_bed"
req_tech = list(TECH_BIO = 3, TECH_MATERIAL = 3, TECH_MAGNET = 3)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 2000, MAT_PHORON = 2000)
build_path = /obj/item/roller/adv
sort_string = "KCAAA"
-253
View File
@@ -1,253 +0,0 @@
/*
KV - ML3M stuff
KVA - gun
KVB - magazines
KVC - cells
KVCA - tier 0
KVCB - tier 1
KVCC - tier 2
KVCD - tier 3
KVCE - tier 4
KVCO - tierless
*/
//General stuff
/datum/design/item/medical/sleevemate
name = "SleeveMate 3700"
id = "sleevemate"
req_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 2, TECH_BIO = 2)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 4000)
build_path = /obj/item/sleevemate
sort_string = "KCAVA"
/datum/design/item/medical/protohypospray
name = "prototype hypospray"
desc = "This prototype hypospray is a sterile, air-needle autoinjector for rapid administration of drugs to patients."
id = "protohypospray"
req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_POWER = 2, TECH_BIO = 4, TECH_ILLEGAL = 2)
materials = list(MAT_STEEL = 500, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 1500, MAT_URANIUM = 1000)
build_path = /obj/item/reagent_containers/hypospray/science
sort_string = "KCAVB"
/datum/design/item/medical/recombobray
name = "recombobulation ray"
desc = "The Type Gamma Medical Recombobulation ray! A mysterious looking ray gun! It works to change people who have had their form significantly altered back into their original forms!"
id = "recombobray"
req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_POWER = 4, TECH_BIO = 5, TECH_BLUESPACE = 4) //Not like these matter. *Glares at circuit printer.*
materials = list(MAT_STEEL = 1000, MAT_GLASS = 2000, MAT_URANIUM = 500, MAT_PHORON = 1500)
build_path = /obj/item/gun/energy/mouseray/medical
sort_string = "KCAVC"
// ML-3M medigun and cells
/datum/design/item/medical/cell_based/AssembleDesignName()
..()
name = "Cell-based medical prototype ([item_name])"
/datum/design/item/medical/cell_based/cell_medigun
name = "cell-loaded medigun"
id = "cell_medigun"
req_tech = list(TECH_MATERIAL = 6, TECH_MAGNET = 4, TECH_POWER = 3, TECH_BIO = 5)
materials = list(MAT_STEEL = 8000, MAT_PLASTIC = 8000, MAT_GLASS = 5000, MAT_SILVER = 1000, MAT_GOLD = 1000, MAT_URANIUM = 1000)
build_path = /obj/item/gun/projectile/cell_loaded/medical
sort_string = "KVAAA"
/datum/design/item/medical/cell_based/cell_medigun_mag
name = "medical cell magazine"
id = "cell_medigun_mag"
req_tech = list(TECH_MATERIAL = 6, TECH_MAGNET = 4, TECH_POWER = 3, TECH_BIO = 5)
materials = list(MAT_STEEL = 4000, MAT_PLASTIC = 6000, MAT_GLASS = 3000, MAT_SILVER = 500, MAT_GOLD = 500)
build_path = /obj/item/ammo_magazine/cell_mag/medical
sort_string = "KVBAA"
/datum/design/item/medical/cell_based/cell_medigun_mag_advanced
name = "advanced medical cell magazine"
id = "cell_medigun_mag_advanced"
req_tech = list(TECH_MATERIAL = 7, TECH_MAGNET = 6, TECH_POWER = 4, TECH_BIO = 7)
materials = list(MAT_STEEL = 5000, MAT_PLASTIC = 10000, MAT_GLASS = 5000, MAT_SILVER = 1500, MAT_GOLD = 1500, MAT_DIAMOND = 5000)
build_path = /obj/item/ammo_magazine/cell_mag/medical/advanced
sort_string = "KVBAB"
/datum/design/item/ml3m_cell/AssembleDesignName()
..()
name = "Nanite cell prototype ([name])"
//Tier 0
/datum/design/item/ml3m_cell/brute
name = "BRUTE"
id = "ml3m_cell_brute"
req_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 2, TECH_BIO = 2)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000)
build_path = /obj/item/ammo_casing/microbattery/medical/brute
sort_string = "KVCAA"
/datum/design/item/ml3m_cell/burn
name = "BURN"
id = "ml3m_cell_burn"
req_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 2, TECH_BIO = 2)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000)
build_path = /obj/item/ammo_casing/microbattery/medical/burn
sort_string = "KVCAB"
/datum/design/item/ml3m_cell/stabilize
name = "STABILIZE"
id = "ml3m_cell_stabilize"
req_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 2, TECH_BIO = 2)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000)
build_path = /obj/item/ammo_casing/microbattery/medical/stabilize
sort_string = "KVCAC"
//Tier 1
/datum/design/item/ml3m_cell/toxin
name = "TOXIN"
id = "ml3m_cell_toxin"
req_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 3, TECH_BIO = 4)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500)
build_path = /obj/item/ammo_casing/microbattery/medical/toxin
sort_string = "KVCBA"
/datum/design/item/ml3m_cell/omni
name = "OMNI"
id = "ml3m_cell_omni"
req_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 3, TECH_BIO = 4)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500)
build_path = /obj/item/ammo_casing/microbattery/medical/omni
sort_string = "KVCBB"
/datum/design/item/ml3m_cell/antirad
name = "ANTIRAD"
id = "ml3m_cell_antirad"
req_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 3, TECH_BIO = 4)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500)
build_path = /obj/item/ammo_casing/microbattery/medical/antirad
sort_string = "KVCBC"
//Tier 2
/datum/design/item/ml3m_cell/brute2
name = "BRUTE-II"
id = "ml3m_cell_brute2"
req_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 3, TECH_POWER = 2, TECH_BIO = 5)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_GOLD = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/brute2
sort_string = "KVCCA"
/datum/design/item/ml3m_cell/burn2
name = "BURN-II"
id = "ml3m_cell_burn2"
req_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 3, TECH_POWER = 2, TECH_BIO = 5)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_GOLD = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/burn2
sort_string = "KVCCB"
/datum/design/item/ml3m_cell/stabilize2
name = "STABILIZE-II"
id = "ml3m_cell_stabilize2"
req_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 3, TECH_POWER = 2, TECH_BIO = 5)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_SILVER = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/stabilize2
sort_string = "KVCCC"
/datum/design/item/ml3m_cell/omni2
name = "OMNI-II"
id = "ml3m_cell_omni2"
req_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 3, TECH_POWER = 2, TECH_BIO = 5)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_URANIUM = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/omni2
sort_string = "KVCCD"
//Tier 3
/datum/design/item/ml3m_cell/toxin2
name = "TOXIN-II"
id = "ml3m_cell_toxin2"
req_tech = list(TECH_MATERIAL = 6, TECH_MAGNET = 3, TECH_POWER = 3, TECH_BIO = 6)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_URANIUM = 1000, MAT_SILVER = 1000, MAT_DIAMOND = 500)
build_path = /obj/item/ammo_casing/microbattery/medical/toxin2
sort_string = "KVCDA"
/datum/design/item/ml3m_cell/haste
name = "HASTE"
id = "ml3m_cell_haste"
req_tech = list(TECH_MATERIAL = 6, TECH_MAGNET = 3, TECH_POWER = 3, TECH_BIO = 6)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_GOLD = 1000, MAT_SILVER = 1000, MAT_DIAMOND = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/haste
sort_string = "KVCDB"
/datum/design/item/ml3m_cell/resist
name = "RESIST"
id = "ml3m_cell_resist"
req_tech = list(TECH_MATERIAL = 6, TECH_MAGNET = 3, TECH_POWER = 3, TECH_BIO = 6)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_GOLD = 1000, MAT_URANIUM = 1000, MAT_DIAMOND = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/resist
sort_string = "KVCDC"
/datum/design/item/ml3m_cell/corpse_mend
name = "CORPSE MEND"
id = "ml3m_cell_corpse_mend"
req_tech = list(TECH_MATERIAL = 6, TECH_MAGNET = 3, TECH_POWER = 3, TECH_BIO = 6)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_PHORON = 3000, MAT_DIAMOND = 3000)
build_path = /obj/item/ammo_casing/microbattery/medical/corpse_mend
sort_string = "KVCDD"
//Tier 4
/datum/design/item/ml3m_cell/brute3
name = "BRUTE-III"
id = "ml3m_cell_brute3"
req_tech = list(TECH_MATERIAL = 7, TECH_MAGNET = 6, TECH_POWER = 5, TECH_BIO = 7, TECH_PRECURSOR = 2)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_DIAMOND = 500, MAT_VERDANTIUM = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/brute3
sort_string = "KVCEA"
/datum/design/item/ml3m_cell/burn3
name = "BURN-III"
id = "ml3m_cell_burn3"
req_tech = list(TECH_MATERIAL = 7, TECH_MAGNET = 6, TECH_POWER = 5, TECH_BIO = 7, TECH_PRECURSOR = 2)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_DIAMOND = 500, MAT_VERDANTIUM = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/burn3
sort_string = "KVCEB"
/datum/design/item/ml3m_cell/toxin3
name = "TOXIN-III"
id = "ml3m_cell_toxin3"
req_tech = list(TECH_MATERIAL = 7, TECH_MAGNET = 6, TECH_POWER = 5, TECH_BIO = 7, TECH_ARCANE = 2)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_DIAMOND = 500, MAT_VERDANTIUM = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/toxin3
sort_string = "KVCEC"
/datum/design/item/ml3m_cell/omni3
name = "OMNI-III"
id = "ml3m_cell_omni3"
req_tech = list(TECH_MATERIAL = 7, TECH_MAGNET = 6, TECH_POWER = 5, TECH_BIO = 7, TECH_ARCANE = 2)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_DIAMOND = 500, MAT_VERDANTIUM = 1000)
build_path = /obj/item/ammo_casing/microbattery/medical/omni3
sort_string = "KVCED"
//Tierless
/datum/design/item/ml3m_cell/shrink
name = "SHRINK"
id = "ml3m_cell_shrink"
req_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 3, TECH_BLUESPACE = 3, TECH_BIO = 5, TECH_ILLEGAL = 5)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_URANIUM = 2000)
build_path = /obj/item/ammo_casing/microbattery/medical/shrink
sort_string = "KVCOA"
/datum/design/item/ml3m_cell/grow
name = "GROW"
id = "ml3m_cell_grow"
req_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 3, TECH_BLUESPACE = 3, TECH_BIO = 5, TECH_ILLEGAL = 5)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_URANIUM = 2000)
build_path = /obj/item/ammo_casing/microbattery/medical/grow
sort_string = "KVCOB"
/datum/design/item/ml3m_cell/normalsize
name = "NORMALSIZE"
id = "ml3m_cell_normalsize"
req_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 3, TECH_BLUESPACE = 3, TECH_BIO = 5, TECH_ILLEGAL = 5)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_PLASTIC = 2500, MAT_URANIUM = 2000)
build_path = /obj/item/ammo_casing/microbattery/medical/normalsize
sort_string = "KVCOC"
@@ -1,73 +0,0 @@
/datum/design/item/weapon/mining/AssembleDesignName()
..()
name = "Mining equipment design ([item_name])"
// Mining digging devices
/datum/design/item/weapon/mining/drill
id = "drill"
req_tech = list(TECH_MATERIAL = 1, TECH_POWER = 2, TECH_ENGINEERING = 1)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 500) //expensive, but no need for miners.
build_path = /obj/item/pickaxe/drill
sort_string = "FAAAA"
/datum/design/item/weapon/mining/advdrill
id = "advanced_drill"
req_tech = list(TECH_MATERIAL = 2, TECH_POWER = 3, TECH_ENGINEERING = 2)
materials = list(MAT_STEEL = 6000, MAT_GLASS = 1000) //expensive, but no need for miners.
build_path = /obj/item/pickaxe/advdrill
sort_string = "FAAAB"
/datum/design/item/weapon/mining/jackhammer
id = "jackhammer"
req_tech = list(TECH_MATERIAL = 3, TECH_POWER = 2, TECH_ENGINEERING = 2)
materials = list(MAT_STEEL = 2000, MAT_GLASS = 500, MAT_SILVER = 500)
build_path = /obj/item/pickaxe/jackhammer
sort_string = "FAAAC"
/datum/design/item/weapon/mining/plasmacutter
id = "plasmacutter"
req_tech = list(TECH_MATERIAL = 4, TECH_PHORON = 3, TECH_ENGINEERING = 3)
materials = list(MAT_STEEL = 1500, MAT_GLASS = 500, MAT_GOLD = 500, MAT_PHORON = 500)
build_path = /obj/item/pickaxe/plasmacutter
sort_string = "FAAAD"
/datum/design/item/weapon/mining/pick_diamond
id = "pick_diamond"
req_tech = list(TECH_MATERIAL = 6)
materials = list(MAT_DIAMOND = 3000)
build_path = /obj/item/pickaxe/diamond
sort_string = "FAAAE"
/datum/design/item/weapon/mining/drill_diamond
id = "drill_diamond"
req_tech = list(TECH_MATERIAL = 6, TECH_POWER = 4, TECH_ENGINEERING = 4)
materials = list(MAT_STEEL = 3000, MAT_GLASS = 1000, MAT_DIAMOND = 2000)
build_path = /obj/item/pickaxe/diamonddrill
sort_string = "FAAAF"
// Mining other equipment
/datum/design/item/weapon/mining/depth_scanner
desc = "Used to check spatial depth and density of rock outcroppings."
id = "depth_scanner"
req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2, TECH_BLUESPACE = 2)
materials = list(MAT_STEEL = 1000,MAT_GLASS = 1000)
build_path = /obj/item/depth_scanner
sort_string = "FBAAA"
/datum/design/item/weapon/mining/mining_scanner
id = "mining_scanner"
req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 4, TECH_BLUESPACE = 1)
materials = list(MAT_STEEL = 1000,MAT_GLASS = 500)
build_path = /obj/item/mining_scanner/advanced
sort_string = "FBAAB"
/datum/design/item/weapon/mining/upgradeAOE
name = "Mining Explosion Upgrade"
desc = "An area of effect upgrade for the Proto-Kinetic Accelerator."
id = "pka_mineaoe"
req_tech = list(TECH_COMBAT = 7, TECH_MATERIAL = 8, TECH_ENGINEERING = 7) // Lets make this endgame level tech, due to it's power.
materials = list(MAT_STEEL = 5000, MAT_GLASS = 5000, MAT_SILVER = 500, MAT_GOLD = 500, MAT_URANIUM = 2000, MAT_PHORON = 2000)
build_path = /obj/item/borg/upgrade/modkit/aoe/turfs
sort_string = "FAAF"
-179
View File
@@ -1,179 +0,0 @@
// Everything that didn't fit elsewhere
/datum/design/item/general/AssembleDesignName()
..()
name = "General purpose design ([item_name])"
/datum/design/item/general/communicator
name = "Communicator"
id = "communicator"
req_tech = list(TECH_DATA = 2, TECH_MAGNET = 2)
materials = list(MAT_STEEL = 500, MAT_GLASS = 500)
build_path = /obj/item/communicator
sort_string = "TAAAA"
/datum/design/item/general/laserpointer
name = "laser pointer"
desc = "Don't shine it in your eyes!"
id = "laser_pointer"
req_tech = list(TECH_MAGNET = 3)
materials = list(MAT_STEEL = 100, MAT_GLASS = 50)
build_path = /obj/item/laser_pointer
sort_string = "TAABA"
/datum/design/item/general/translator
name = "handheld translator"
id = "translator"
req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3)
materials = list(MAT_STEEL = 3000, MAT_GLASS = 3000)
build_path = /obj/item/universal_translator
sort_string = "TAACA"
/datum/design/item/general/ear_translator
name = "earpiece translator"
id = "ear_translator"
req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5) //It's been hella miniaturized.
materials = list(MAT_STEEL = 2000, MAT_GLASS = 2000, MAT_GOLD = 1000)
build_path = /obj/item/universal_translator/ear
sort_string = "TAACB"
/datum/design/item/general/light_replacer
name = "Light replacer"
desc = "A device to automatically replace lights. Refill with working lightbulbs."
id = "light_replacer"
req_tech = list(TECH_MAGNET = 3, TECH_MATERIAL = 4)
materials = list(MAT_STEEL = 1500, MAT_SILVER = 150, MAT_GLASS = 3000)
build_path = /obj/item/lightreplacer
sort_string = "TAADA"
/datum/design/item/general/binaryencrypt
name = "Binary encryption key"
desc = "Allows for deciphering the binary channel on-the-fly."
id = "binaryencrypt"
req_tech = list(TECH_ILLEGAL = 2)
materials = list(MAT_STEEL = 300, MAT_GLASS = 300)
build_path = /obj/item/encryptionkey/binary
sort_string = "TBAAA"
/datum/design/item/general/chameleon
name = "Holographic equipment kit"
desc = "A kit of dangerous, high-tech equipment with changeable looks."
id = "chameleon"
req_tech = list(TECH_ILLEGAL = 2)
materials = list(MAT_STEEL = 500)
build_path = /obj/item/storage/box/syndie_kit/chameleon
sort_string = "TBAAB"
/datum/design/item/general/bsflare
name = "bluespace flare"
desc = "A marker that can be detected by shuttle landing systems."
id = "bsflare"
req_tech = list(TECH_DATA = 3, TECH_BLUESPACE = 4)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 2000, MAT_SILVER = 2000)
build_path = /obj/item/spaceflare
sort_string = "TBAAC"
/datum/design/item/general/riflescope
name = "rifle scope"
desc = "A scope that can be mounted to certain rifles."
id = "riflescope"
req_tech = list(TECH_ILLEGAL = 2, TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 4000)
build_path = /obj/item/binoculars/scope
sort_string = "TBAAD"
/datum/design/item/general/advmop
name = "advanced mop"
desc = "An advanced mop with pressured water jets that break away the toughest stains."
id = "advmop"
req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 5, TECH_BIO = 1)
materials = list(MAT_STEEL = 5000, MAT_GLASS = 2000, MAT_GOLD = 1000)
build_path = /obj/item/mop/advanced
sort_string = "TBAAE"
/datum/design/item/general/hyperfiber_jumpsuit
name = "HYPER jumpsuit"
id = "hfjumpsuit"
req_tech = list(TECH_BLUESPACE = 2)
materials = list(MAT_STEEL = 2000, MAT_GLASS = 1000)
build_path = /obj/item/clothing/under/hyperfiber
sort_string = "TAVAA"
/datum/design/item/general/bluespace_jumpsuit
name = "Bluespace jumpsuit"
id = "bsjumpsuit"
req_tech = list(TECH_BLUESPACE = 2, TECH_MATERIAL = 3, TECH_POWER = 2)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 4000)
build_path = /obj/item/clothing/under/hyperfiber/bluespace
sort_string = "TAVAB"
/datum/design/item/general/sizegun
name = "Size gun"
id = "sizegun"
req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
materials = list(MAT_STEEL = 3000, MAT_GLASS = 2000)
build_path = /obj/item/gun/energy/sizegun
sort_string = "TAVBA"
/datum/design/item/general/sizegun_gradual
name = "Gradual size gun"
id = "gradsizegun"
req_tech = list(TECH_BLUESPACE = 2, TECH_MATERIAL = 3, TECH_POWER = 2)
materials = list(MAT_STEEL = 3000, MAT_GLASS = 2000)
build_path = /obj/item/slow_sizegun
sort_string = "TAVBB"
/datum/design/item/general/bluespace_collar
name = "Bluespace collar"
id = "bluespacecollar"
req_tech = list(TECH_BLUESPACE = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
materials = list(MAT_STEEL = 2000, MAT_GLASS = 2000)
build_path = /obj/item/clothing/accessory/collar/shock/bluespace
sort_string = "TAVBC"
/datum/design/item/general/bodysnatcher
name = "Body Snatcher"
id = "bodysnatcher"
req_tech = list(TECH_MAGNET = 3, TECH_BIO = 3, TECH_ILLEGAL = 2)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 4000, MAT_URANIUM = 2000)
build_path = /obj/item/bodysnatcher
sort_string = "TBVAA"
/datum/design/item/general/inducer_sci
name = "Inducer (Scientific)"
id = "inducersci"
req_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 5, TECH_POWER = 6)
materials = list(MAT_STEEL = 8000, MAT_GLASS = 2000, MAT_URANIUM = 4000, MAT_PHORON = 4000)
build_path = /obj/item/inducer/sci
sort_string = "TCVAA"
/datum/design/item/general/inducer_eng
name = "Inducer (Industrial)"
id = "inducerind"
req_tech = list(TECH_BLUESPACE = 5, TECH_MATERIAL = 7, TECH_POWER = 7)
materials = list(MAT_STEEL = 3000, MAT_GLASS = 2000, MAT_URANIUM = 2000, MAT_TITANIUM = 2000)
build_path = /obj/item/inducer/unloaded
sort_string = "TCVAB"
/datum/design/item/general/walkpod
name = "PodZu Music Player"
id = "walkpod"
req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3)
materials = list(MAT_STEEL = 2000, MAT_GLASS = 2000)
build_path = /obj/item/walkpod
sort_string = "TCVAD"
/datum/design/item/general/juke_remote
name = "BoomTown Cordless Speaker"
id = "juke_remote"
req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 4, TECH_BLUESPACE = 1)
materials = list(MAT_STEEL = 4000, MAT_GLASS = 4000, MAT_URANIUM = 2000)
build_path = /obj/item/juke_remote
sort_string = "TCVAE"
/datum/design/item/general/motion_tracker
name = "Motion Tracker"
id = "motion_tracker"
req_tech = list(TECH_MAGNET = 1, TECH_DATA = 2)
build_path = /obj/item/motiontracker
sort_string = "TAADC"
-100
View File
@@ -1,100 +0,0 @@
// PDA
/datum/design/item/general/pda
name = "PDA"
desc = "Cheaper than whiny non-digital assistants."
id = "pda"
req_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 3)
materials = list(MAT_STEEL = 50, MAT_GLASS = 50)
build_path = /obj/item/pda
sort_string = "WAAAA"
// Cartridges
/datum/design/item/pda_cartridge
req_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 3)
materials = list(MAT_STEEL = 50, MAT_GLASS = 50)
/datum/design/item/pda_cartridge/AssembleDesignName()
..()
name = "PDA accessory ([item_name])"
/datum/design/item/pda_cartridge/cart_basic
id = "cart_basic"
build_path = /obj/item/cartridge
sort_string = "WBAAA"
/datum/design/item/pda_cartridge/engineering
id = "cart_engineering"
build_path = /obj/item/cartridge/engineering
sort_string = "WBAAB"
/datum/design/item/pda_cartridge/atmos
id = "cart_atmos"
build_path = /obj/item/cartridge/atmos
sort_string = "WBAAC"
/datum/design/item/pda_cartridge/medical
id = "cart_medical"
build_path = /obj/item/cartridge/medical
sort_string = "WBAAD"
/datum/design/item/pda_cartridge/chemistry
id = "cart_chemistry"
build_path = /obj/item/cartridge/chemistry
sort_string = "WBAAE"
/datum/design/item/pda_cartridge/security
id = "cart_security"
build_path = /obj/item/cartridge/security
sort_string = "WBAAF"
/datum/design/item/pda_cartridge/janitor
id = "cart_janitor"
build_path = /obj/item/cartridge/janitor
sort_string = "WBAAG"
/datum/design/item/pda_cartridge/science
id = "cart_science"
build_path = /obj/item/cartridge/signal/science
sort_string = "WBAAH"
/datum/design/item/pda_cartridge/quartermaster
id = "cart_quartermaster"
build_path = /obj/item/cartridge/quartermaster
sort_string = "WBAAI"
/datum/design/item/pda_cartridge/head
id = "cart_head"
build_path = /obj/item/cartridge/head
sort_string = "WBAAJ"
/datum/design/item/pda_cartridge/hop
id = "cart_hop"
build_path = /obj/item/cartridge/hop
sort_string = "WBAAK"
/datum/design/item/pda_cartridge/hos
id = "cart_hos"
build_path = /obj/item/cartridge/hos
sort_string = "WBAAL"
/datum/design/item/pda_cartridge/ce
id = "cart_ce"
build_path = /obj/item/cartridge/ce
sort_string = "WBAAM"
/datum/design/item/pda_cartridge/cmo
id = "cart_cmo"
build_path = /obj/item/cartridge/cmo
sort_string = "WBAAN"
/datum/design/item/pda_cartridge/rd
id = "cart_rd"
build_path = /obj/item/cartridge/rd
sort_string = "WBAAO"
/datum/design/item/pda_cartridge/captain
id = "cart_captain"
build_path = /obj/item/cartridge/captain
sort_string = "WBAAP"
@@ -1,88 +0,0 @@
/datum/design/item/powercell
build_type = PROTOLATHE | MECHFAB
/datum/design/item/powercell/AssembleDesignName()
name = "Power Cell Model ([item_name])"
/datum/design/item/powercell/AssembleDesignDesc()
if(build_path)
var/obj/item/cell/C = build_path
desc = "Allows the construction of power cells that can hold [initial(C.maxcharge)] units of energy."
/datum/design/item/powercell/Fabricate()
var/obj/item/cell/C = ..()
C.charge = 0 //shouldn't produce power out of thin air.
C.update_icon()
return C
/datum/design/item/powercell/basic
name = "basic"
id = "basic_cell"
req_tech = list(TECH_POWER = 1)
materials = list(MAT_STEEL = 700, MAT_GLASS = 50)
build_path = /obj/item/cell
category = list("Misc")
sort_string = "BAAAA"
/datum/design/item/powercell/high
name = "high-capacity"
id = "high_cell"
req_tech = list(TECH_POWER = 2)
materials = list(MAT_STEEL = 700, MAT_GLASS = 60)
build_path = /obj/item/cell/high
category = list("Misc")
sort_string = "BAAAB"
/datum/design/item/powercell/super
name = "super-capacity"
id = "super_cell"
req_tech = list(TECH_POWER = 3, TECH_MATERIAL = 2)
materials = list(MAT_STEEL = 700, MAT_GLASS = 70)
build_path = /obj/item/cell/super
category = list("Misc")
sort_string = "BAAAC"
/datum/design/item/powercell/hyper
name = "hyper-capacity"
id = "hyper_cell"
req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4)
materials = list(MAT_STEEL = 400, MAT_GOLD = 150, MAT_SILVER = 150, MAT_GLASS = 70)
build_path = /obj/item/cell/hyper
category = list("Misc")
sort_string = "BAAAD"
/datum/design/item/powercell/device
name = "device"
build_type = PROTOLATHE
id = "device"
materials = list(MAT_STEEL = 350, MAT_GLASS = 25)
build_path = /obj/item/cell/device
category = list("Misc")
sort_string = "BAABA"
/datum/design/item/powercell/weapon
name = "weapon"
build_type = PROTOLATHE
id = "weapon"
materials = list(MAT_STEEL = 700, MAT_GLASS = 50)
build_path = /obj/item/cell/device/weapon
category = list("Misc")
sort_string = "BAABB"
/datum/design/item/powercell/mecha/high
name = "high-capacity mecha"
id = "high_mech_cell"
req_tech = list(TECH_POWER = 3, TECH_MATERIAL = 3)
materials = list(MAT_STEEL = 600, MAT_SILVER = 150, MAT_GLASS = 70)
build_path = /obj/item/cell/mech/high
category = list("Misc")
sort_string = "BAACA"
/datum/design/item/powercell/mecha/super
name = "super-capacity mecha"
id = "super_mech_cell"
req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4)
materials = list(MAT_STEEL = 500, MAT_GOLD = 200, MAT_SILVER = 200, MAT_GLASS = 80)
build_path = /obj/item/cell/mech/super
category = list("Misc")
sort_string = "BAACB"
@@ -1,93 +0,0 @@
//Anomaly
/datum/design/item/anomaly/AssembleDesignName()
..()
name = "Anomalous prototype ([item_name])"
/datum/design/item/anomaly/AssembleDesignDesc()
if(!desc)
if(build_path)
var/obj/item/I = build_path
desc = initial(I.desc)
..()
/datum/design/item/anomaly/camotrap
name = "Chameleon Trap"
desc = "A self-miraging mechanical trap, capable of producing short bursts of electric current when triggered."
id = "hunt_trap"
materials = list(MAT_DURASTEEL = 3000, MAT_METALHYDROGEN = 1000, MAT_PHORON = 2000)
req_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_PHORON = 2, TECH_ARCANE = 2)
build_path = /obj/item/beartrap/hunting
sort_string = "ZAAAA"
// Precursor
/datum/design/item/precursor/AssembleDesignName()
..()
name = "Alien prototype ([item_name])"
/datum/design/item/precursor/AssembleDesignDesc()
if(!desc)
if(build_path)
var/obj/item/I = build_path
desc = initial(I.desc)
..()
/datum/design/item/precursor/crowbar
name = "Hybrid Crowbar"
desc = "A tool utilizing cutting edge modern technology, and ancient component designs."
id = "hybridcrowbar"
req_tech = list(TECH_ENGINEERING = 6, TECH_MATERIAL = 6, TECH_BLUESPACE = 3, TECH_PRECURSOR = 1)
materials = list(MAT_PLASTEEL = 2000, MAT_VERDANTIUM = 3000, MAT_GOLD = 250, MAT_URANIUM = 2500)
build_path = /obj/item/tool/crowbar/hybrid
sort_string = "ZBAAA"
/datum/design/item/precursor/wrench
name = "Hybrid Wrench"
desc = "A tool utilizing cutting edge modern technology, and ancient component designs."
id = "hybridwrench"
req_tech = list(TECH_ENGINEERING = 6, TECH_MATERIAL = 5, TECH_BLUESPACE = 2, TECH_MAGNET = 3, TECH_PRECURSOR = 1)
materials = list(MAT_PLASTEEL = 2000, MAT_VERDANTIUM = 3000, MAT_SILVER = 300, MAT_URANIUM = 2000)
build_path = /obj/item/tool/wrench/hybrid
sort_string = "ZBAAB"
/datum/design/item/precursor/screwdriver
name = "Hybrid Screwdriver"
desc = "A tool utilizing cutting edge modern technology, and ancient component designs."
id = "hybridscrewdriver"
req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 5, TECH_BLUESPACE = 2, TECH_MAGNET = 3, TECH_PRECURSOR = 1)
materials = list(MAT_PLASTEEL = 2000, MAT_VERDANTIUM = 3000, MAT_PLASTIC = 8000, MAT_DIAMOND = 2000)
build_path = /obj/item/tool/screwdriver/hybrid
sort_string = "ZBAAC"
/datum/design/item/precursor/wirecutters
name = "Hybrid Wirecutters"
desc = "A tool utilizing cutting edge modern technology, and ancient component designs."
id = "hybridwirecutters"
req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 5, TECH_PHORON = 2, TECH_PRECURSOR = 1)
materials = list(MAT_PLASTEEL = 2000, MAT_VERDANTIUM = 3000, MAT_PLASTIC = 8000, MAT_PHORON = 2750, MAT_DIAMOND = 2000)
build_path = /obj/item/tool/wirecutters/hybrid
sort_string = "ZBAAD"
/datum/design/item/precursor/welder
name = "Hybrid Welding Tool"
desc = "A tool utilizing cutting edge modern technology, and ancient component designs."
id = "hybridwelder"
req_tech = list(TECH_ENGINEERING = 6, TECH_MATERIAL = 6, TECH_BLUESPACE = 3, TECH_PHORON = 3, TECH_MAGNET = 5, TECH_PRECURSOR = 1)
materials = list(MAT_DURASTEEL = 2000, MAT_MORPHIUM = 3000, MAT_METALHYDROGEN = 4750, MAT_URANIUM = 6000)
build_path = /obj/item/weldingtool/experimental/hybrid
sort_string = "ZBAAE"
/datum/design/item/precursor/janusmodule
name = "Blackbox Circuit Datamass"
desc = "A design that seems to be in a constantly shifting superposition."
id = "janus_module"
materials = list(MAT_DURASTEEL = 3000, MAT_MORPHIUM = 2000, MAT_METALHYDROGEN = 6000, MAT_URANIUM = 6000, MAT_VERDANTIUM = 1500)
req_tech = list(TECH_MATERIAL = 7, TECH_BLUESPACE = 5, TECH_MAGNET = 6, TECH_PHORON = 3, TECH_ARCANE = 1, TECH_PRECURSOR = 2)
build_path = /obj/random/janusmodule
sort_string = "ZBBAA"
/datum/design/item/precursor/janusmodule/Fabricate(var/newloc, var/fabricator)
var/type_to_spawn = pick(subtypesof(/obj/item/circuitboard/mecha/imperion))
return new type_to_spawn(newloc)
@@ -1,91 +0,0 @@
/*
This is a guide to sort strings and categorization of designs.
Its really helpful and neat-looking when items are sorted properly in general R&D list and not just haphazardly.
sort_string basically sorts items in alphabetic order, using sort_string itself as reference.
A - stock parts all always go first, and above everything else
AA - parts themselves
AAAA - matter bins
AAAB - micro manipulators
AAAC - capacitors
AAAD - scanners
AAAE - micro-lasers
AB - part replacer(s)
B - power cells
BAAA - regular power cells
BAAB - small power cells
C - Tech disks
D - GPS/beacons/locators/etc
DA - GPSs
DB - beacon/locator
DBAA - locator
DBAB - beacon
E - HUDs
F - Mining equipment
FA - drills
FB - scanners and such
G - Xenoarch equipment
H - Xenobiology equipment
HA - weapons
HB - other
I - Beakers
J - Biotech scanners and such
JAAA - mass spectrometers
JAAB - reagent scanners
JAAC - borg stuff
JAAD - plant stuff
K - Medical equipment
KA - surgery equipment
KAAA - scalpels/IMS
KAAB - bone clamp
KB - health analyzers
KC - misc
L - Implants
M - Weapons
MA - Ranged weapon
MAA - Energy ranged weapons
MAB - Ballistic ranged weapons
MABB - Ballistic ammo
MAC - Phase weapons
MAD - Other ranged weapons (darts/sprayer/fuelrod)
MADB - misc ammo
MB - Melee weapons
MC - grenade casings
N - Engineering equipment
NA - tools
NB - scanners
O, P - placeholders in case new category is needed
Q - Bags of Holding
R - Telecomms stock parts
S - AI-holders
SA - brain holders
SB - pAI
SC - intellicore
T - Misc stuff
TA - general
TB - illegal
U - Integrated circuits stuff
UA - printer
UB - upgrade disks
UC - tools
UD - holders
V - Modular computer parts
VA - hard drives
VB - network cards
VC - batteries
VD - cpus
VE - accessories without upgrades
VF - data crystals
W - PDA stuff
WA - PDA
WB - PDA cartridges
X, Y - more placeholders
Z - anomaly/precursor items
ZA - anomaly
ZB - precursor
ZBA - precursor tools
ZBB - precursor other
*/
@@ -1,278 +0,0 @@
/*
Various Stock Parts
*/
/datum/design/item/stock_part
build_type = PROTOLATHE
time = 3 //Sets an independent time for stock parts, currently one third normal print time.
/datum/design/item/stock_part/AssembleDesignName()
..()
name = "Component design ([item_name])"
/datum/design/item/stock_part/AssembleDesignDesc()
if(!desc)
desc = "A stock part used in the construction of various devices."
// Matter Bins
/datum/design/item/stock_part/basic_matter_bin
id = "basic_matter_bin"
req_tech = list(TECH_MATERIAL = 1)
materials = list(MAT_STEEL = 80)
build_path = /obj/item/stock_parts/matter_bin
sort_string = "AAAAA"
/datum/design/item/stock_part/adv_matter_bin
id = "adv_matter_bin"
req_tech = list(TECH_MATERIAL = 3)
materials = list(MAT_STEEL = 80)
build_path = /obj/item/stock_parts/matter_bin/adv
sort_string = "AAAAB"
/datum/design/item/stock_part/super_matter_bin
id = "super_matter_bin"
req_tech = list(TECH_MATERIAL = 5)
materials = list(MAT_STEEL = 80)
build_path = /obj/item/stock_parts/matter_bin/super
sort_string = "AAAAC"
/datum/design/item/stock_part/hyper_matter_bin
id = "hyper_matter_bin"
req_tech = list(TECH_MATERIAL = 6, TECH_ARCANE = 2)
materials = list(MAT_STEEL = 200, MAT_VERDANTIUM = 60, MAT_DURASTEEL = 75)
build_path = /obj/item/stock_parts/matter_bin/hyper
sort_string = "AAAAD"
/datum/design/item/stock_part/omni_matter_bin
id = "omni_matter_bin"
req_tech = list(TECH_MATERIAL = 7, TECH_PRECURSOR = 2)
materials = list(MAT_STEEL = 2000, MAT_PLASTEEL = 100, MAT_MORPHIUM = 100, MAT_DURASTEEL = 100)
build_path = /obj/item/stock_parts/matter_bin/omni
sort_string = "AAAAE"
// Micro-manipulators
/datum/design/item/stock_part/micro_mani
id = "micro_mani"
req_tech = list(TECH_MATERIAL = 1, TECH_DATA = 1)
materials = list(MAT_STEEL = 30)
build_path = /obj/item/stock_parts/manipulator
sort_string = "AAABA"
/datum/design/item/stock_part/nano_mani
id = "nano_mani"
req_tech = list(TECH_MATERIAL = 3, TECH_DATA = 2)
materials = list(MAT_STEEL = 30)
build_path = /obj/item/stock_parts/manipulator/nano
sort_string = "AAABB"
/datum/design/item/stock_part/pico_mani
id = "pico_mani"
req_tech = list(TECH_MATERIAL = 5, TECH_DATA = 2)
materials = list(MAT_STEEL = 30)
build_path = /obj/item/stock_parts/manipulator/pico
sort_string = "AAABC"
/datum/design/item/stock_part/hyper_mani
id = "hyper_mani"
req_tech = list(TECH_MATERIAL = 6, TECH_DATA = 3, TECH_ARCANE = 2)
materials = list(MAT_STEEL = 200, MAT_VERDANTIUM = 50, MAT_DURASTEEL = 50)
build_path = /obj/item/stock_parts/manipulator/hyper
sort_string = "AAABD"
/datum/design/item/stock_part/omni_mani
id = "omni_mani"
req_tech = list(TECH_MATERIAL = 7, TECH_DATA = 4, TECH_PRECURSOR = 2)
materials = list(MAT_STEEL = 2000, MAT_PLASTEEL = 500, MAT_MORPHIUM = 100, MAT_DURASTEEL = 100)
build_path = /obj/item/stock_parts/manipulator/omni
sort_string = "AAABE"
// Capacitors
/datum/design/item/stock_part/basic_capacitor
id = "basic_capacitor"
req_tech = list(TECH_POWER = 1)
materials = list(MAT_STEEL = 50, MAT_GLASS = 50)
build_path = /obj/item/stock_parts/capacitor
sort_string = "AAACA"
/datum/design/item/stock_part/adv_capacitor
id = "adv_capacitor"
req_tech = list(TECH_POWER = 3)
materials = list(MAT_STEEL = 50, MAT_GLASS = 50)
build_path = /obj/item/stock_parts/capacitor/adv
sort_string = "AAACB"
/datum/design/item/stock_part/super_capacitor
id = "super_capacitor"
req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4)
materials = list(MAT_STEEL = 50, MAT_GLASS = 50, MAT_GOLD = 20)
build_path = /obj/item/stock_parts/capacitor/super
sort_string = "AAACC"
/datum/design/item/stock_part/hyper_capacitor
id = "hyper_capacitor"
req_tech = list(TECH_POWER = 6, TECH_MATERIAL = 5, TECH_BLUESPACE = 1, TECH_ARCANE = 1)
materials = list(MAT_STEEL = 200, MAT_GLASS = 100, MAT_VERDANTIUM = 30, MAT_DURASTEEL = 25)
build_path = /obj/item/stock_parts/capacitor/hyper
sort_string = "AAACD"
/datum/design/item/stock_part/omni_capacitor
id = "omni_capacitor"
req_tech = list(TECH_POWER = 7, TECH_MATERIAL = 6, TECH_BLUESPACE = 3, TECH_PRECURSOR = 1)
materials = list(MAT_STEEL = 2000, MAT_DIAMOND = 1000, MAT_GLASS = 1000, MAT_MORPHIUM = 100, MAT_DURASTEEL = 100)
build_path = /obj/item/stock_parts/capacitor/omni
sort_string = "AAACE"
// Sensors
/datum/design/item/stock_part/basic_sensor
id = "basic_sensor"
req_tech = list(TECH_MAGNET = 1)
materials = list(MAT_STEEL = 50, MAT_GLASS = 20)
build_path = /obj/item/stock_parts/scanning_module
sort_string = "AAADA"
/datum/design/item/stock_part/adv_sensor
id = "adv_sensor"
req_tech = list(TECH_MAGNET = 3)
materials = list(MAT_STEEL = 50, MAT_GLASS = 20)
build_path = /obj/item/stock_parts/scanning_module/adv
sort_string = "AAADB"
/datum/design/item/stock_part/phasic_sensor
id = "phasic_sensor"
req_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 3)
materials = list(MAT_STEEL = 50, MAT_GLASS = 20, MAT_SILVER = 10)
build_path = /obj/item/stock_parts/scanning_module/phasic
sort_string = "AAADC"
/datum/design/item/stock_part/hyper_sensor
id = "hyper_sensor"
req_tech = list(TECH_MAGNET = 6, TECH_MATERIAL = 4, TECH_ARCANE = 1)
materials = list(MAT_STEEL = 50, MAT_GLASS = 20, MAT_SILVER = 50, MAT_VERDANTIUM = 40, MAT_DURASTEEL = 50)
build_path = /obj/item/stock_parts/scanning_module/hyper
sort_string = "AAADD"
/datum/design/item/stock_part/omni_sensor
id = "omni_sensor"
req_tech = list(TECH_MAGNET = 7, TECH_MATERIAL = 5, TECH_PRECURSOR = 1)
materials = list(MAT_STEEL = 1000, MAT_PLASTEEL = 500, MAT_GLASS = 750, MAT_SILVER = 500, MAT_MORPHIUM = 60, MAT_DURASTEEL = 100)
build_path = /obj/item/stock_parts/scanning_module/omni
sort_string = "AAADE"
// Micro-lasers
/datum/design/item/stock_part/basic_micro_laser
id = "basic_micro_laser"
req_tech = list(TECH_MAGNET = 1)
materials = list(MAT_STEEL = 10, MAT_GLASS = 20)
build_path = /obj/item/stock_parts/micro_laser
sort_string = "AAAEA"
/datum/design/item/stock_part/high_micro_laser
id = "high_micro_laser"
req_tech = list(TECH_MAGNET = 3)
materials = list(MAT_STEEL = 10, MAT_GLASS = 20)
build_path = /obj/item/stock_parts/micro_laser/high
sort_string = "AAAEB"
/datum/design/item/stock_part/ultra_micro_laser
id = "ultra_micro_laser"
req_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 5)
materials = list(MAT_STEEL = 10, MAT_GLASS = 20, MAT_URANIUM = 10)
build_path = /obj/item/stock_parts/micro_laser/ultra
sort_string = "AAAEC"
/datum/design/item/stock_part/hyper_micro_laser
id = "hyper_micro_laser"
req_tech = list(TECH_MAGNET = 6, TECH_MATERIAL = 6, TECH_ARCANE = 2)
materials = list(MAT_STEEL = 200, MAT_GLASS = 20, MAT_URANIUM = 30, MAT_VERDANTIUM = 50, MAT_DURASTEEL = 100)
build_path = /obj/item/stock_parts/micro_laser/hyper
sort_string = "AAAED"
/datum/design/item/stock_part/omni_micro_laser
id = "omni_micro_laser"
req_tech = list(TECH_MAGNET = 7, TECH_MATERIAL = 7, TECH_PRECURSOR = 2)
materials = list(MAT_STEEL = 2000, MAT_GLASS = 500, MAT_URANIUM = 2000, MAT_MORPHIUM = 50, MAT_DURASTEEL = 100)
build_path = /obj/item/stock_parts/micro_laser/omni
sort_string = "AAAEE"
// part bundles, because i HATE queues and i don't want to rewrite it for stack-printing
/datum/design/item/stock_part/bundle/t1
id = "parts_bundle_t1"
req_tech = list(TECH_MATERIAL = 1, TECH_DATA = 1, TECH_POWER = 1, TECH_MAGNET = 1)
materials = list(MAT_STEEL = 1100, MAT_GLASS = 450)
build_path = /obj/effect/spawner/parts/t1
sort_string = "AAAFA"
/datum/design/item/stock_part/bundle/t2
id = "parts_bundle_t2"
req_tech = list(TECH_MATERIAL = 3, TECH_DATA = 2, TECH_POWER = 3, TECH_MAGNET = 3)
materials = list(MAT_STEEL = 1100, MAT_GLASS = 450)
build_path = /obj/effect/spawner/parts/t2
sort_string = "AAAFB"
/datum/design/item/stock_part/bundle/t3
id = "parts_bundle_t3"
req_tech = list(TECH_MATERIAL = 5, TECH_DATA = 2, TECH_POWER = 5, TECH_MAGNET = 5)
materials = list(MAT_STEEL = 1100, MAT_GLASS = 450, MAT_SILVER = 50, MAT_GOLD = 100, MAT_URANIUM = 50)
build_path = /obj/effect/spawner/parts/t3
sort_string = "AAAFC"
/datum/design/item/stock_part/bundle/t4
id = "parts_bundle_t4"
req_tech = list(TECH_MATERIAL = 6, TECH_DATA = 3, TECH_POWER = 6, TECH_MAGNET = 6, TECH_ARCANE = 2)
materials = list(MAT_STEEL = 4250, MAT_GLASS = 700, MAT_SILVER = 250, MAT_URANIUM = 150, MAT_DURASTEEL = 1450, MAT_VERDANTIUM = 900)
build_path = /obj/effect/spawner/parts/t4
sort_string = "AAAFD"
/datum/design/item/stock_part/bundle/t5
id = "parts_bundle_t5"
req_tech = list(TECH_MATERIAL = 7, TECH_DATA = 4, TECH_POWER = 7, TECH_MAGNET = 7, TECH_PRECURSOR = 2)
materials = list(MAT_STEEL = 45000, MAT_PLASTEEL = 5500, MAT_GLASS = 11250, MAT_SILVER = 2500, MAT_URANIUM = 10000, MAT_DIAMOND = 5000, MAT_DURASTEEL = 2500, MAT_MORPHIUM = 2050)
build_path = /obj/effect/spawner/parts/t5
sort_string = "AAAFE"
// RPEDs
/datum/design/item/stock_part/RPED
name = "Rapid Part Exchange Device"
desc = "Special mechanical module made to store, sort, and apply standard machine parts."
id = "rped"
req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 3)
materials = list(MAT_STEEL = 15000, MAT_GLASS = 5000)
build_path = /obj/item/storage/part_replacer
sort_string = "ABAAA"
/datum/design/item/stock_part/ARPED
name = "Advanced Rapid Part Exchange Device"
desc = "Special mechanical module made to store, sort, and apply standard machine parts. This one has a greatly upgraded storage capacity, \
and the ability to manipulate beakers."
id = "arped"
req_tech = list(TECH_ENGINEERING = 5, TECH_MATERIAL = 5)
materials = list(MAT_STEEL = 30000, MAT_GLASS = 10000)
build_path = /obj/item/storage/part_replacer/adv
sort_string = "ABAAB"
/datum/design/item/stock_part/PBRPED
name = "Prototype Bluespace Rapid Part Exchange Device"
desc = "Special mechanical module made to store, sort, and apply standard machine parts. This one has a remarkably upgraded storage capacity, \
and the ability to manipulate beakers."
id = "pbrped"
req_tech = list(TECH_ENGINEERING = 7, TECH_MATERIAL = 7, TECH_BLUESPACE = 5)
materials = list(MAT_STEEL = 30000, MAT_GLASS = 10000, MAT_SILVER = 5000, MAT_GOLD = 5000, MAT_DIAMOND = 1000)
build_path = /obj/item/storage/part_replacer/adv/discount_bluespace
sort_string = "ABAAB"
/datum/design/item/stock_part/BRPED
name = "Bluespace Rapid Part Exchange Device"
desc = "Special mechanical module made to store, sort, and apply standard machine parts. This one has a remarkably upgraded storage capacity, \
the ability to manipulate beakers, and works at range."
id = "brped"
req_tech = list(TECH_ENGINEERING = 7, TECH_MATERIAL = 7, TECH_BLUESPACE = 5, TECH_PRECURSOR = 1)
materials = list(MAT_STEEL = 30000, MAT_GLASS = 10000, MAT_SILVER = 5000, MAT_GOLD = 5000, MAT_DIAMOND = 1000)
build_path = /obj/item/storage/part_replacer/adv/bluespace
sort_string = "ABAAB"
@@ -1,54 +0,0 @@
// Telecomm parts
/datum/design/item/stock_part/subspace/AssembleDesignName()
..()
name = "Subspace component design ([item_name])"
/datum/design/item/stock_part/subspace/subspace_ansible
id = "s-ansible"
req_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2)
materials = list(MAT_STEEL = 80, MAT_SILVER = 20)
build_path = /obj/item/stock_parts/subspace/ansible
sort_string = "RAAAA"
/datum/design/item/stock_part/subspace/hyperwave_filter
id = "s-filter"
req_tech = list(TECH_DATA = 3, TECH_MAGNET = 3)
materials = list(MAT_STEEL = 40, MAT_SILVER = 10)
build_path = /obj/item/stock_parts/subspace/sub_filter
sort_string = "RAAAB"
/datum/design/item/stock_part/subspace/subspace_amplifier
id = "s-amplifier"
req_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2)
materials = list(MAT_STEEL = 10, MAT_GOLD = 30, MAT_URANIUM = 15)
build_path = /obj/item/stock_parts/subspace/amplifier
sort_string = "RAAAC"
/datum/design/item/stock_part/subspace/subspace_treatment
id = "s-treatment"
req_tech = list(TECH_DATA = 3, TECH_MAGNET = 2, TECH_MATERIAL = 4, TECH_BLUESPACE = 2)
materials = list(MAT_STEEL = 10, MAT_SILVER = 20)
build_path = /obj/item/stock_parts/subspace/treatment
sort_string = "RAAAD"
/datum/design/item/stock_part/subspace/subspace_analyzer
id = "s-analyzer"
req_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2)
materials = list(MAT_STEEL = 10, MAT_GOLD = 15)
build_path = /obj/item/stock_parts/subspace/analyzer
sort_string = "RAAAE"
/datum/design/item/stock_part/subspace/subspace_crystal
id = "s-crystal"
req_tech = list(TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2)
materials = list(MAT_GLASS = 1000, MAT_SILVER = 20, MAT_GOLD = 20)
build_path = /obj/item/stock_parts/subspace/crystal
sort_string = "RAAAF"
/datum/design/item/stock_part/subspace/subspace_transmitter
id = "s-transmitter"
req_tech = list(TECH_MAGNET = 5, TECH_MATERIAL = 5, TECH_BLUESPACE = 3)
materials = list(MAT_GLASS = 100, MAT_SILVER = 10, MAT_URANIUM = 15)
build_path = /obj/item/stock_parts/subspace/transmitter
sort_string = "RAAAG"
@@ -1,21 +0,0 @@
/datum/design/item/disk/AssembleDesignName()
..()
name = "Data storage design ([name])"
/datum/design/item/disk/design_disk
name = "Design Storage Disk"
desc = "Produce additional disks for storing device designs."
id = "design_disk"
req_tech = list(TECH_DATA = 1)
materials = list(MAT_STEEL = 30, MAT_GLASS = 10)
build_path = /obj/item/disk/design_disk
sort_string = "CAAAA"
/datum/design/item/disk/tech_disk
name = "Technology Data Storage Disk"
desc = "Produce additional disks for storing technology data."
id = "tech_disk"
req_tech = list(TECH_DATA = 1)
materials = list(MAT_STEEL = 30, MAT_GLASS = 10)
build_path = /obj/item/disk/tech_disk
sort_string = "CAAAB"
@@ -1,69 +0,0 @@
/* Uncomment if someone makes these buildable
/datum/design/circuit/general_alert
name = "general alert console"
id = "general_alert"
build_path = /obj/item/circuitboard/general_alert
// Removal of loyalty implants. Can't think of a way to add this to the config option.
/datum/design/item/implant/loyalty
name = "loyalty"
id = "implant_loyal"
req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3)
materials = list(MAT_STEEL = 7000, MAT_GLASS = 7000)
build_path = /obj/item/implantcase/loyalty"
/datum/design/rust_core_control
name = "Circuit Design (RUST core controller)"
desc = "Allows for the construction of circuit boards used to build a core control console for the RUST fusion engine."
id = "rust_core_control"
req_tech = list("programming" = 4, "engineering" = 4)
build_type = IMPRINTER
materials = list(MAT_GLASS = 2000, REAGENT_ID_SACID = 20)
build_path = "/obj/item/circuitboard/rust_core_control"
/datum/design/rust_fuel_control
name = "Circuit Design (RUST fuel controller)"
desc = "Allows for the construction of circuit boards used to build a fuel injector control console for the RUST fusion engine."
id = "rust_fuel_control"
req_tech = list("programming" = 4, "engineering" = 4)
build_type = IMPRINTER
materials = list(MAT_GLASS = 2000, REAGENT_ID_SACID = 20)
build_path = "/obj/item/circuitboard/rust_fuel_control"
/datum/design/rust_fuel_port
name = "Internal circuitry (RUST fuel port)"
desc = "Allows for the construction of circuit boards used to build a fuel injection port for the RUST fusion engine."
id = "rust_fuel_port"
req_tech = list("engineering" = 4, "materials" = 5)
build_type = IMPRINTER
materials = list(MAT_GLASS = 2000, REAGENT_ID_SACID = 20, MAT_URANIUM = 3000)
build_path = "/obj/item/module/rust_fuel_port"
/datum/design/rust_fuel_compressor
name = "Circuit Design (RUST fuel compressor)"
desc = "Allows for the construction of circuit boards used to build a fuel compressor of the RUST fusion engine."
id = "rust_fuel_compressor"
req_tech = list("materials" = 6, "phorontech" = 4)
build_type = IMPRINTER
materials = list(MAT_GLASS = 2000, REAGENT_ID_SACID = 20, MAT_PHORON = 3000, MAT_DIAMOND = 1000)
build_path = "/obj/item/module/rust_fuel_compressor"
/datum/design/rust_core
name = "Internal circuitry (RUST tokamak core)"
desc = "The circuit board that for a RUST-pattern tokamak fusion core."
id = "pacman"
req_tech = list(bluespace = 3, phorontech = 4, magnets = 5, powerstorage = 6)
build_type = IMPRINTER
materials = list(MAT_GLASS = 2000, REAGENT_ID_SACID = 20, MAT_PHORON = 3000, MAT_DIAMOND = 2000)
build_path = "/obj/item/circuitboard/rust_core"
/datum/design/rust_injector
name = "Internal circuitry (RUST tokamak core)"
desc = "The circuit board that for a RUST-pattern particle accelerator."
id = "pacman"
req_tech = list(powerstorage = 3, engineering = 4, phorontech = 4, materials = 6)
build_type = IMPRINTER
materials = list(MAT_GLASS = 2000, REAGENT_ID_SACID = 20, MAT_PHORON = 3000, MAT_URANIUM = 2000)
build_path = "/obj/item/circuitboard/rust_core"
*/

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