[READY FOR TM] R&D Rework Part 2 - Death to the experimentor (#27472)

* PT1 - Death to experimentor

* I cant fail CI this fast come on

* PT2 - DA -> SA

* CRLF to LF

* Strange icons in the SA now

* Lets give this a go

* AGH

* Dirt

* WORK

* Oops - cere was missing the RD locker

* Map fixes

* Adds delivery chute back

* Warrior review

* Also removes magnetics

---------

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
This commit is contained in:
AffectedArc07
2024-12-04 17:55:39 +00:00
committed by GitHub
parent 543fc9b6fe
commit d663dfc3fb
27 changed files with 3449 additions and 3351 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4 -12
View File
@@ -14,18 +14,6 @@
name = "\improper Robotics Showroom"
icon_state = "showroom"
// Experimentor
/area/station/science/explab
name = "\improper E.X.P.E.R.I-MENTOR Lab"
icon_state = "scilab"
request_console_flags = RC_SUPPLY
request_console_name = "Science"
/area/station/science/explab/chamber
name = "\improper E.X.P.E.R.I-MENTOR Chamber"
icon_state = "scitest"
/area/station/science/research
name = "Research Division"
icon_state = "sci"
@@ -34,6 +22,10 @@
name = "Research Division Lobby"
icon_state = "sci"
/area/station/science/testrange
name = "Research Test Range"
icon_state = "sci"
/area/station/science/break_room
name = "\improper Science Break Room"
icon_state = "scibreak"
@@ -363,11 +363,7 @@
icon_state = "science"
build_path = /obj/machinery/computer/rdconsole/core
req_access = list(ACCESS_TOX) // This is for adjusting the type of computer we're building
var/list/access_types = list("R&D Core", "E.X.P.E.R.I-MENTOR", "Public")
/obj/item/circuitboard/rdconsole/experiment
board_name = "RD Console - E.X.P.E.R.I-MENTOR"
build_path = /obj/machinery/computer/rdconsole/experiment
var/list/access_types = list("R&D Core", "Public")
/obj/item/circuitboard/rdconsole/public
board_name = "RD Console - Public"
@@ -540,9 +536,6 @@
if("R&D Core")
board_name = "RD Console"
build_path = /obj/machinery/computer/rdconsole/core
if("E.X.P.E.R.I-MENTOR")
board_name = "RD Console - E.X.P.E.R.I-MENTOR"
build_path = /obj/machinery/computer/rdconsole/experiment
if("Public")
board_name = "RD Console - Public"
build_path = /obj/machinery/computer/rdconsole/public
+3 -15
View File
@@ -716,22 +716,10 @@ to destroy them and players will be able to make replacements.
/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/matter_bin = 1)
//Almost the same recipe as destructive analyzer to give people choices.
/obj/item/circuitboard/experimentor
board_name = "E.X.P.E.R.I-MENTOR"
/obj/item/circuitboard/scientific_analyzer // fucking US spelling
board_name = "Scientific Analyzer"
icon_state = "science"
build_path = /obj/machinery/r_n_d/experimentor
board_type = "machine"
origin_tech = "magnets=1;engineering=1;programming=1;biotech=1;bluespace=2"
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/micro_laser = 2)
/obj/item/circuitboard/destructive_analyzer
board_name = "Destructive Analyzer"
icon_state = "science"
build_path = /obj/machinery/r_n_d/destructive_analyzer
build_path = /obj/machinery/r_n_d/scientific_analyzer
board_type = "machine"
origin_tech = "magnets=2;engineering=2;programming=2"
req_components = list(
@@ -117,7 +117,7 @@
/obj/item/autosurgeon/organ = 50,
/obj/item/mod/construction/plating/research = 25,
// Research / Experimentor
// Research
/obj/item/paper/researchnotes = 125, // papers that give random R&D levels
/obj/item/storage/box/telescience = 25, // Code green or blue. Probably not antags. People haven't touched it in ages. Let us see what happens.
@@ -51,7 +51,6 @@
/obj/item/book/manual/wiki/chef_recipes,
/obj/item/book/manual/wiki/engineering_construction,
/obj/item/book/manual/wiki/engineering_guide,
/obj/item/book/manual/wiki/experimentor,
/obj/item/book/manual/wiki/faxes,
/obj/item/book/manual/wiki/hacking,
/obj/item/book/manual/wiki/hydroponics,
+6 -14
View File
@@ -666,19 +666,19 @@
<h1>Science For Dummies</h1>
So you want to further SCIENCE? Good man/woman/thing! However, SCIENCE is a complicated process even though it's quite easy. For the most part, it's a three step process:
<ol>
<li> 1) Deconstruct items in the Destructive Analyzer to advance technology or improve the design.</li>
<li> 1) Deconstruct items in the Scientific Analyzer to advance technology or improve the design.</li>
<li> 2) Build unlocked designs in the Protolathe and Circuit Imprinter</li>
<li> 3) Repeat!</li>
</ol>
Those are the basic steps to furthing science. What do you do science with, however? Well, you have four major tools: R&D Console, the Destructive Analyzer, the Protolathe, and the Circuit Imprinter.
Those are the basic steps to furthing science. What do you do science with, however? Well, you have four major tools: R&D Console, the Scientific Analyzer, the Protolathe, and the Circuit Imprinter.
<h2>The R&D Console</h2>
The R&D console is the cornerstone of any research lab. It is the central system from which the Destructive Analyzer, Protolathe, and Circuit Imprinter (your R&D systems) are controled. More on those systems in their own sections. On its own, the R&D console acts as a database for all your technological gains and new devices you discover. So long as the R&D console remains intact, you'll retain all that SCIENCE you've discovered. Protect it though, because if it gets damaged, you'll lose your data! In addition to this important purpose, the R&D console has a disk menu that lets you transfer data from the database onto disk or from the disk into the database. It also has a settings menu that lets you re-sync with nearby R&D devices (if they've become disconnected), lock the console from the unworthy, upload the data to all other R&D consoles in the network (all R&D consoles are networked by default), connect/disconnect from the network, and purge all data from the database.
The R&D console is the cornerstone of any research lab. It is the central system from which the Scientific Analyzer, Protolathe, and Circuit Imprinter (your R&D systems) are controled. More on those systems in their own sections. On its own, the R&D console acts as a database for all your technological gains and new devices you discover. So long as the R&D console remains intact, you'll retain all that SCIENCE you've discovered. Protect it though, because if it gets damaged, you'll lose your data! In addition to this important purpose, the R&D console has a disk menu that lets you transfer data from the database onto disk or from the disk into the database. It also has a settings menu that lets you re-sync with nearby R&D devices (if they've become disconnected), lock the console from the unworthy, upload the data to all other R&D consoles in the network (all R&D consoles are networked by default), connect/disconnect from the network, and purge all data from the database.
<b>NOTE:</b> The technology list screen, circuit imprinter, and protolathe menus are accessible by non-scientists. This is intended to allow 'public' systems for the plebians to utilize some new devices.
<h2>Destructive Analyzer</h2>
This is the source of all technology. Whenever you put a handheld object in it, it analyzes it and determines what sort of technological advancements you can discover from it. If the technology of the object is equal or higher then your current knowledge, you can destroy the object to further those sciences. Some devices (notably, some devices made from the protolathe and circuit imprinter) aren't 100% reliable when you first discover them. If these devices break down, you can put them into the Destructive Analyzer and improve their reliability rather then futher science. If their reliability is high enough ,it'll also advance their related technologies.
<h2>Scientific Analyzer</h2>
This is the source of all technology. Whenever you put a handheld object in it, it analyzes it and determines what sort of technological advancements you can discover from it. If the technology of the object is equal or higher then your current knowledge, you can destroy the object to further those sciences. Some devices (notably, some devices made from the protolathe and circuit imprinter) aren't 100% reliable when you first discover them. If these devices break down, you can put them into the Scientific Analyzer and improve their reliability rather then futher science. If their reliability is high enough ,it'll also advance their related technologies.
<h2>Circuit Imprinter</h2>
This machine, along with the Protolathe, is used to actually produce new devices. The Circuit Imprinter takes glass and various chemicals (depends on the design) to produce new circuit boards to build new machines or computers. It can even be used to print AI modules.
@@ -687,7 +687,7 @@
This machine is an advanced form of the Autolathe that produce non-circuit designs. Unlike the Autolathe, it can use processed metal, glass, solid plasma, silver, gold, and diamonds along with a variety of chemicals to produce devices. The downside is that, again, not all devices you make are 100% reliable when you first discover them.
<h1>Reliability and You</h1>
As it has been stated, many devices when they're first discovered do not have a 100% reliablity when you first discover them. Instead, the reliablity of the device is dependent upon a base reliability value, whatever improvements to the design you've discovered through the Destructive Analyzer, and any advancements you've made with the device's source technologies. To be able to improve the reliability of a device, you have to use the device until it breaks beyond repair. Once that happens, you can analyze it in a Destructive Analyzer. Once the device reachs a certain minimum reliability, you'll gain tech advancements from it.
As it has been stated, many devices when they're first discovered do not have a 100% reliablity when you first discover them. Instead, the reliablity of the device is dependent upon a base reliability value, whatever improvements to the design you've discovered through the Scientific Analyzer, and any advancements you've made with the device's source technologies. To be able to improve the reliability of a device, you have to use the device until it breaks beyond repair. Once that happens, you can analyze it in a Scientific Analyzer. Once the device reachs a certain minimum reliability, you'll gain tech advancements from it.
<h1>Building a Better Machine</h1>
Many machines produces from circuit boards and inserted into a machine frame require a variety of parts to construct. These are parts like capacitors, batteries, matter bins, and so forth. As your knowledge of science improves, more advanced versions are unlocked. If you use these parts when constructing something, its attributes may be improved. For example, if you use an advanced matter bin when constructing an autolathe (rather then a regular one), it'll hold more materials. Experiment around with stock parts of various qualities to see how they affect the end results! Be warned, however: Tier 3 and higher stock parts don't have 100% reliability and their low reliability may affect the reliability of the end machine.
@@ -867,14 +867,6 @@
title = "Cyborgs for Dummies"
wiki_article_title = "Guide_to_Robotics"
/obj/item/book/manual/wiki/experimentor
name = "Mentoring your Experiments"
desc = "A madman's ramblings on how to experiment with the E.X.P.E.R.I-MENTOR."
icon_state = "rdbook"
author = "Dr. H.P. Kritz"
title = "Mentoring your Experiments"
wiki_article_title = "Guide_to_the_E.X.P.E.R.I-MENTOR"
/obj/item/book/manual/wiki/chef_recipes
name = "Chef Recipes"
desc = "Knives, Ovens, and You: A guide to cooking."
@@ -324,7 +324,7 @@
new /obj/item/circuitboard/rdserver(src)
new /obj/item/circuitboard/rdconsole(src)
new /obj/item/circuitboard/protolathe(src)
new /obj/item/circuitboard/destructive_analyzer(src)
new /obj/item/circuitboard/scientific_analyzer(src)
new /obj/item/circuitboard/circuit_imprinter(src)
new /obj/item/stock_parts/manipulator(src)
new /obj/item/stock_parts/manipulator(src)
@@ -1142,7 +1142,7 @@
/obj/item/storage/box/rndboards/populate_contents()
new /obj/item/circuitboard/protolathe(src)
new /obj/item/circuitboard/destructive_analyzer(src)
new /obj/item/circuitboard/scientific_analyzer(src)
new /obj/item/circuitboard/circuit_imprinter(src)
new /obj/item/circuitboard/rdconsole/public(src)
new /obj/item/circuitboard/rnd_network_controller(src)
@@ -40,7 +40,6 @@
/obj/machinery/sleeper,
/obj/machinery/bodyscanner,
/obj/machinery/photocopier, // HI YES ONE FLAYER FAXED TO MY OFFICE PLEASE
/obj/machinery/r_n_d/experimentor, // Like anyone is ever gonna teleport to this
/obj/machinery/barsign
))
@@ -393,7 +393,7 @@
/obj/structure/closet/crate/secure/oldstation/research/populate_contents()
new /obj/item/circuitboard/circuit_imprinter(src)
new /obj/item/circuitboard/destructive_analyzer(src)
new /obj/item/circuitboard/scientific_analyzer(src)
new /obj/item/circuitboard/protolathe(src)
new /obj/item/circuitboard/rdconsole/public(src)
new /obj/item/circuitboard/rnd_network_controller(src)
+4 -3
View File
@@ -1040,17 +1040,18 @@
/obj/item/paper/researchnotes
name = "paper - 'Research Notes'"
info = "<b>The notes appear gibberish to you. Perhaps a destructive analyzer in R&D could make sense of them.</b>"
info = "<b>The notes appear gibberish to you. Perhaps a scientific analyzer in R&D could make sense of them?</b>"
origin_tech = "combat=4;materials=4;engineering=4;biotech=4"
/obj/item/paper/researchnotes/New()
..()
/obj/item/paper/researchnotes/Initialize(mapload)
. = ..()
var/list/possible_techs = list("materials", "engineering", "plasmatech", "powerstorage", "bluespace", "biotech", "combat", "magnets", "programming", "syndicate")
var/mytech = pick(possible_techs)
var/mylevel = rand(7, 9)
origin_tech = "[mytech]=[mylevel]"
name = "research notes - [mytech] [mylevel]"
// I want this type dead
/obj/item/paper/instruction
name = "Instruction Notes"
@@ -292,14 +292,14 @@
build_path = /obj/item/circuitboard/cyborgrecharger
category = list("Research Machinery")
/datum/design/destructive_analyzer
name = "Machine Board (Destructive Analyzer)"
desc = "The circuit board for a Destructive Analyzer."
id = "destructive_analyzer"
/datum/design/scientific_analyzer
name = "Machine Board (Scientific Analyzer)"
desc = "The circuit board for a Scientific Analyzer."
id = "scientific_analyzer"
req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2)
build_type = IMPRINTER
materials = list(MAT_GLASS = 1000)
build_path = /obj/item/circuitboard/destructive_analyzer
build_path = /obj/item/circuitboard/scientific_analyzer
category = list("Research Machinery")
/datum/design/mechfab
@@ -322,16 +322,6 @@
build_path = /obj/item/circuitboard/mech_recharger
category = list("Research Machinery")
/datum/design/experimentor
name = "Machine Design (E.X.P.E.R.I-MENTOR Board)"
desc = "The circuit board for an E.X.P.E.R.I-MENTOR."
id = "experimentor"
req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2, "bluespace" = 2)
build_type = IMPRINTER
materials = list(MAT_GLASS = 1000)
build_path = /obj/item/circuitboard/experimentor
category = list("Research Machinery")
/datum/design/protolathe
name = "Machine Board (Protolathe)"
desc = "The circuit board for a Protolathe."
-605
View File
@@ -1,605 +0,0 @@
//this is designed to replace the destructive analyzer
#define SCANTYPE_POKE 1
#define SCANTYPE_IRRADIATE 2
#define SCANTYPE_GAS 3
#define SCANTYPE_HEAT 4
#define SCANTYPE_COLD 5
#define SCANTYPE_OBLITERATE 6
#define SCANTYPE_DISCOVER 7
#define EFFECT_PROB_VERYLOW 20
#define EFFECT_PROB_LOW 35
#define EFFECT_PROB_MEDIUM 50
#define EFFECT_PROB_HIGH 75
#define EFFECT_PROB_VERYHIGH 95
#define FAIL 8
/obj/machinery/r_n_d/experimentor
name = "\improper E.X.P.E.R.I-MENTOR"
icon = 'icons/obj/machines/heavy_lathe.dmi'
icon_state = "h_lathe"
density = TRUE
anchored = TRUE
power_state = IDLE_POWER_USE
var/recentlyExperimented = 0
var/badThingCoeff = 0
var/resetTime = 15
var/cloneMode = FALSE
var/cloneCount = 0
var/list/item_reactions = list()
var/list/valid_items = list() //valid items for special reactions like transforming
var/list/critical_items = list() //items that can cause critical reactions
var/list/blocked_items = list(/obj/item/reagent_containers/drinks/bottle/dragonsbreath,
/obj/item/reagent_containers/drinks/bottle/immortality)
/// Used for linking with rnd consoles
var/range = 5
/obj/machinery/r_n_d/experimentor/proc/ConvertReqString2List(list/source_list)
var/list/temp_list = params2list(source_list)
for(var/O in temp_list)
temp_list[O] = text2num(temp_list[O])
return temp_list
/obj/machinery/r_n_d/experimentor/proc/SetTypeReactions()
var/probWeight = 0
for(var/I in typesof(/obj/item))
if(istype(I,/obj/item/relic)) //does istype even work here
item_reactions["[I]"] = SCANTYPE_DISCOVER
else
item_reactions["[I]"] = pick(SCANTYPE_POKE,SCANTYPE_IRRADIATE,SCANTYPE_GAS,SCANTYPE_HEAT,SCANTYPE_COLD,SCANTYPE_OBLITERATE)
if(ispath(I,/obj/item/stock_parts) || ispath(I,/obj/item/grenade/chem_grenade) || ispath(I,/obj/item/kitchen))
var/obj/item/tempCheck = I
if(initial(tempCheck.icon_state) != null) //check it's an actual usable item, in a hacky way
valid_items += 15
valid_items += I
probWeight++
if(ispath(I,/obj/item/food))
var/obj/item/tempCheck = I
if(I in blocked_items)
continue
if(initial(tempCheck.icon_state) != null) //check it's an actual usable item, in a hacky way
valid_items += rand(1,max(2,35-probWeight))
valid_items += I
if(ispath(I,/obj/item/rcd) || ispath(I,/obj/item/grenade) || ispath(I,/obj/item/aicard) || ispath(I,/obj/item/storage/backpack/holding) || ispath(I,/obj/item/slime_extract) || ispath(I,/obj/item/onetankbomb) || ispath(I,/obj/item/transfer_valve))
var/obj/item/tempCheck = I
if(initial(tempCheck.icon_state) != null)
critical_items += I
/obj/machinery/r_n_d/experimentor/Initialize(mapload) // DIEEEEEEEEEEEEEEEEEEEEEEE
. = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/experimentor(src)
component_parts += new /obj/item/stock_parts/scanning_module(src)
component_parts += new /obj/item/stock_parts/manipulator(src)
component_parts += new /obj/item/stock_parts/manipulator(src)
component_parts += new /obj/item/stock_parts/micro_laser(src)
component_parts += new /obj/item/stock_parts/micro_laser(src)
SetTypeReactions()
RefreshParts()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/r_n_d/experimentor/RefreshParts()
for(var/obj/item/stock_parts/manipulator/M in component_parts)
if(resetTime > 0 && (resetTime - M.rating) >= 1)
resetTime -= M.rating
for(var/obj/item/stock_parts/scanning_module/M in component_parts)
badThingCoeff += M.rating*2
for(var/obj/item/stock_parts/micro_laser/M in component_parts)
badThingCoeff += M.rating
/obj/machinery/r_n_d/experimentor/proc/checkCircumstances(obj/item/O)
//snowflake check to only take "made" bombs
if(istype(O,/obj/item/transfer_valve))
var/obj/item/transfer_valve/T = O
if(!T.tank_one || !T.tank_two || !T.attached_device)
return FALSE
return TRUE
/obj/machinery/r_n_d/experimentor/attackby__legacy__attackchain(obj/item/O, mob/user, params)
if(istype(O, /obj/item/storage/part_replacer))
return ..()
if(!checkCircumstances(O))
to_chat(user, "<span class='warning'>[O] is not yet valid for [src] and must be completed!</span>")
return
if(!linked_console)
to_chat(user, "<span class='warning'>[src] must be linked to an R&D console first!</span>")
return
if(loaded_item)
to_chat(user, "<span class='warning'>[src] is already loaded.</span>")
return
if(isitem(O))
if(!O.origin_tech)
to_chat(user, "<span class='warning'>This doesn't seem to have a tech origin!</span>")
return
var/list/temp_tech = ConvertReqString2List(O.origin_tech)
if(length(temp_tech) == 0)
to_chat(user, "<span class='warning'>You cannot experiment on this item!</span>")
return
if(!user.drop_item())
return
loaded_item = O
O.loc = src
to_chat(user, "<span class='notice'>You add [O] to the machine.</span>")
flick("h_lathe_load", src)
/obj/machinery/r_n_d/experimentor/crowbar_act(mob/user, obj/item/I)
if(!panel_open)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
ejectItem()
default_deconstruction_crowbar(user, I)
/obj/machinery/r_n_d/experimentor/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
default_deconstruction_screwdriver(user, "h_lathe_maint", "h_lathe", I)
if(linked_console)
linked_console.linked_destroy = null
linked_console = null
/obj/machinery/r_n_d/experimentor/attack_hand(mob/user)
if(..())
return
interact(user)
/obj/machinery/r_n_d/experimentor/interact(mob/living/carbon/human/user)
user.set_machine(src)
var/dat = "<center>"
if(!linked_console)
dat += "<b><a href='byond://?src=[UID()];function=search'>Scan for R&D Console</A></b><br>"
if(loaded_item)
dat += "<b>Loaded Item:</b> [loaded_item]<br>"
dat += "<b>Technology</b>:<br>"
var/list/D = ConvertReqString2List(loaded_item.origin_tech)
for(var/T in D)
dat += "[T]<br>"
dat += "<br><br>Available tests:"
dat += "<br><b><a href='byond://?src=[UID()];item=\ref[loaded_item];function=[SCANTYPE_POKE]'>Poke</A></b>"
dat += "<br><b><a href='byond://?src=[UID()];item=\ref[loaded_item];function=[SCANTYPE_IRRADIATE];'>Irradiate</A></b>"
dat += "<br><b><a href='byond://?src=[UID()];item=\ref[loaded_item];function=[SCANTYPE_GAS]'>Gas</A></b>"
dat += "<br><b><a href='byond://?src=[UID()];item=\ref[loaded_item];function=[SCANTYPE_HEAT]'>Burn</A></b>"
dat += "<br><b><a href='byond://?src=[UID()];item=\ref[loaded_item];function=[SCANTYPE_COLD]'>Freeze</A></b>"
dat += "<br><b><a href='byond://?src=[UID()];item=\ref[loaded_item];function=[SCANTYPE_OBLITERATE]'>Destroy</A></b><br>"
if(istype(loaded_item,/obj/item/relic))
dat += "<br><b><a href='byond://?src=[UID()];item=\ref[loaded_item];function=[SCANTYPE_DISCOVER]'>Discover</A></b><br>"
dat += "<br><b><a href='byond://?src=[UID()];function=eject'>Eject</A>"
else
dat += "<b>Nothing loaded.</b>"
dat += "<br><a href='byond://?src=[UID()];function=refresh'>Refresh</A><br>"
dat += "<br><a href='byond://?src=[UID()];close=1'>Close</A><br></center>"
var/datum/browser/popup = new(user, "experimentor","Experimentor", 700, 400)
popup.set_content(dat)
popup.open()
onclose(user, "experimentor")
/obj/machinery/r_n_d/experimentor/proc/matchReaction(matching,reaction)
var/obj/item/D = matching
if(D)
if(item_reactions.Find("[D.type]"))
var/tor = item_reactions["[D.type]"]
if(tor == text2num(reaction))
return tor
else
return FAIL
else
return FAIL
else
return FAIL
/obj/machinery/r_n_d/experimentor/proc/ejectItem(delete=FALSE)
if(loaded_item)
if(cloneMode && cloneCount > 0)
visible_message("<span class='notice'>A duplicate [loaded_item] pops out!</span>")
var/type_to_make = loaded_item.type
new type_to_make(get_turf(pick(oview(1,src))))
--cloneCount
if(cloneCount == 0)
cloneMode = FALSE
return
var/turf/dropturf = get_turf(pick(view(1,src)))
if(!dropturf) //Failsafe to prevent the object being lost in the void forever.
dropturf = get_turf(src)
loaded_item.loc = dropturf
if(delete)
qdel(loaded_item)
loaded_item = null
/obj/machinery/r_n_d/experimentor/proc/throwSmoke(turf/where)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(1, FALSE, where)
smoke.start()
/obj/machinery/r_n_d/experimentor/proc/pickWeighted(list/from)
var/result = FALSE
var/counter = 1
while(!result)
var/probtocheck = from[counter]
if(prob(probtocheck))
result = TRUE
return from[counter+1]
if(counter + 2 < length(from))
counter = counter + 2
else
counter = 1
/obj/machinery/r_n_d/experimentor/proc/experiment(exp,obj/item/exp_on)
recentlyExperimented = 1
icon_state = "h_lathe_wloop"
var/chosenchem
var/criticalReaction = (exp_on.type in critical_items) ? TRUE : FALSE
////////////////////////////////////////////////////////////////////////////////////////////////
if(exp == SCANTYPE_POKE)
visible_message("[src] prods at [exp_on] with mechanical arms.")
if(prob(EFFECT_PROB_LOW) && criticalReaction)
visible_message("[exp_on] is gripped in just the right way, enhancing its focus.")
badThingCoeff++
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
visible_message("<span class='danger'>[src] malfunctions and destroys [exp_on], lashing its arms out at nearby people!</span>")
for(var/mob/living/m in oview(1, src))
m.apply_damage(15,BRUTE,pick("head","chest","groin"))
investigate_log("Experimentor dealt minor brute to [m].", "experimentor")
ejectItem(TRUE)
if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("<span class='warning'>[src] malfunctions!</span>")
exp = SCANTYPE_OBLITERATE
if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
visible_message("<span class='danger'>[src] malfunctions, throwing [exp_on]!</span>")
var/mob/living/target = locate(/mob/living) in oview(7,src)
if(target)
var/obj/item/throwing = loaded_item
investigate_log("Experimentor has thrown [loaded_item] at [target]", "experimentor")
ejectItem()
if(throwing)
throwing.throw_at(target, 10, 1)
////////////////////////////////////////////////////////////////////////////////////////////////
if(exp == SCANTYPE_IRRADIATE)
visible_message("<span class='danger'>[src] reflects radioactive rays at [exp_on]!</span>")
if(prob(EFFECT_PROB_LOW) && criticalReaction)
visible_message("[exp_on] has activated an unknown subroutine!")
cloneMode = TRUE
cloneCount = badThingCoeff
investigate_log("Experimentor has made a clone of [exp_on]", "experimentor")
ejectItem()
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
visible_message("<span class='danger'>[src] malfunctions, melting [exp_on] and leaking radiation!</span>")
radiation_pulse(src, 500)
ejectItem(TRUE)
if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("<span class='warning'>[src] malfunctions, spewing toxic waste!</span>")
for(var/turf/T in oview(1, src))
if(!T.density)
if(prob(EFFECT_PROB_VERYHIGH))
new /obj/effect/decal/cleanable/greenglow(T)
if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
var/savedName = "[exp_on]"
ejectItem(TRUE)
var/newPath = pickWeighted(valid_items)
loaded_item = new newPath(src)
visible_message("<span class='warning'>[src] malfunctions, transforming [savedName] into [loaded_item]!</span>")
investigate_log("Experimentor has transformed [savedName] into [loaded_item]", "experimentor")
if(istype(loaded_item,/obj/item/grenade/chem_grenade))
var/obj/item/grenade/chem_grenade/CG = loaded_item
CG.prime()
ejectItem()
////////////////////////////////////////////////////////////////////////////////////////////////
if(exp == SCANTYPE_GAS)
visible_message("<span class='warning'>[src] fills its chamber with gas, [exp_on] included.</span>")
if(prob(EFFECT_PROB_LOW) && criticalReaction)
visible_message("[exp_on] achieves the perfect mix!")
new /obj/item/stack/sheet/mineral/plasma(get_turf(pick(oview(1,src))))
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
visible_message("<span class='danger'>[src] destroys [exp_on], leaking dangerous gas!</span>")
chosenchem = pick("carbon","radium","toxin","condensedcapsaicin","psilocybin","space_drugs","ethanol","beepskysmash")
var/datum/reagents/R = new/datum/reagents(15)
R.my_atom = src
R.add_reagent(chosenchem , 15)
investigate_log("Experimentor has released [chosenchem] smoke.", "experimentor")
var/datum/effect_system/smoke_spread/chem/smoke = new
smoke.set_up(R, src, TRUE)
playsound(loc, 'sound/effects/smoke.ogg', 50, TRUE, -3)
smoke.start()
qdel(R)
ejectItem(TRUE)
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
visible_message("<span class='danger'>[src]'s chemical chamber has sprung a leak!</span>")
chosenchem = pick("mutationtoxin","nanomachines","sacid")
var/datum/reagents/R = new/datum/reagents(15)
R.my_atom = src
R.add_reagent(chosenchem , 15)
var/datum/effect_system/smoke_spread/chem/smoke = new
smoke.set_up(R, src, TRUE)
playsound(loc, 'sound/effects/smoke.ogg', 50, TRUE, -3)
smoke.start()
qdel(R)
ejectItem(TRUE)
warn_admins(usr, "[chosenchem] smoke")
investigate_log("Experimentor has released <font color='red'>[chosenchem]</font> smoke!", "experimentor")
if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("[src] malfunctions, spewing harmless gas.>")
throwSmoke(loc)
if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
visible_message("<span class='warning'>[src] melts [exp_on], ionizing the air around it!</span>")
empulse(loc, 4, 0) //change this to 4,6 once the EXPERI-Mentor is moved.
investigate_log("Experimentor has generated an Electromagnetic Pulse.", "experimentor")
ejectItem(TRUE)
////////////////////////////////////////////////////////////////////////////////////////////////
if(exp == SCANTYPE_HEAT)
visible_message("[src] raises [exp_on]'s temperature.")
if(prob(EFFECT_PROB_LOW) && criticalReaction)
visible_message("<span class='warning'>[src]'s emergency coolant system gives off a small ding!</span>")
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
var/obj/item/reagent_containers/drinks/coffee/C = new /obj/item/reagent_containers/drinks/coffee(get_turf(pick(oview(1,src))))
chosenchem = pick("plasma","capsaicin","ethanol")
C.reagents.remove_any(25)
C.reagents.add_reagent(chosenchem , 50)
C.name = "Cup of Suspicious Liquid"
C.desc = "It has a large hazard symbol printed on the side in fading ink."
investigate_log("Experimentor has made a cup of [chosenchem] coffee.", "experimentor")
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
var/turf/start = get_turf(src)
var/mob/M = locate(/mob/living) in view(src, 3)
var/turf/MT = get_turf(M)
if(MT)
visible_message("<span class='danger'>[src] dangerously overheats, launching a flaming fuel orb!</span>")
investigate_log("Experimentor has launched a <font color='red'>fireball</font> at [M]!", "experimentor")
var/obj/item/projectile/magic/fireball/FB = new /obj/item/projectile/magic/fireball(start)
FB.original = MT
FB.current = start
FB.yo = MT.y - start.y
FB.xo = MT.x - start.x
FB.fire()
if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("<span class='danger'>[src] malfunctions, melting [exp_on] and releasing a burst of flame!</span>")
explosion(loc, -1, 0, 0, 0, 0, flame_range = 2)
investigate_log("Experimentor started a fire.", "experimentor")
ejectItem(TRUE)
if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
visible_message("<span class='warning'>[src] malfunctions, melting [exp_on] and leaking hot air!</span>")
var/datum/milla_safe/experimentor_temperature/milla = new()
milla.invoke_async(src, 100000, 1000)
investigate_log("Experimentor has released hot air.", "experimentor")
ejectItem(TRUE)
if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
visible_message("<span class='warning'>[src] malfunctions, activating its emergency coolant systems!</span>")
throwSmoke(loc)
for(var/mob/living/m in oview(1, src))
m.apply_damage(5,BURN,pick("head","chest","groin"))
investigate_log("Experimentor has dealt minor burn damage to [m]", "experimentor")
ejectItem()
////////////////////////////////////////////////////////////////////////////////////////////////
if(exp == SCANTYPE_COLD)
visible_message("[src] lowers [exp_on]'s temperature.")
if(prob(EFFECT_PROB_LOW) && criticalReaction)
visible_message("<span class='warning'>[src]'s emergency coolant system gives off a small ding!</span>")
var/obj/item/reagent_containers/drinks/coffee/C = new /obj/item/reagent_containers/drinks/coffee(get_turf(pick(oview(1,src))))
playsound(loc, 'sound/machines/ding.ogg', 50, 1) //Ding! Your death coffee is ready!
chosenchem = pick("uranium","frostoil","ephedrine")
C.reagents.remove_any(25)
C.reagents.add_reagent(chosenchem , 50)
C.name = "Cup of Suspicious Liquid"
C.desc = "It has a large hazard symbol printed on the side in fading ink."
investigate_log("Experimentor has made a cup of [chosenchem] coffee.", "experimentor")
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
visible_message("<span class='danger'>[src] malfunctions, shattering [exp_on] and releasing a dangerous cloud of coolant!</span>")
var/datum/reagents/R = new/datum/reagents(15)
R.my_atom = src
R.add_reagent("frostoil" , 15)
investigate_log("Experimentor has released frostoil gas.", "experimentor")
var/datum/effect_system/smoke_spread/chem/smoke = new
smoke.set_up(R, src, TRUE)
playsound(loc, 'sound/effects/smoke.ogg', 50, TRUE, -3)
smoke.start()
qdel(R)
ejectItem(TRUE)
if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("<span class='warning'>[src] malfunctions, shattering [exp_on] and leaking cold air!</span>")
var/datum/milla_safe/experimentor_temperature/milla = new()
milla.invoke_async(src, -75000, 1000, TCMB)
investigate_log("Experimentor has released cold air.", "experimentor")
ejectItem(TRUE)
if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
visible_message("<span class='warning'>[src] malfunctions, releasing a flurry of chilly air as [exp_on] pops out!</span>")
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(1, FALSE, loc)
smoke.start()
ejectItem()
////////////////////////////////////////////////////////////////////////////////////////////////
if(exp == SCANTYPE_OBLITERATE)
visible_message("<span class='warning'>[exp_on] activates the crushing mechanism, [exp_on] is destroyed!</span>")
if(prob(EFFECT_PROB_LOW) && criticalReaction)
visible_message("<span class='warning'>[src]'s crushing mechanism slowly and smoothly descends, flattening [exp_on]!</span>")
new /obj/item/stack/sheet/plasteel(get_turf(pick(oview(1,src))))
if(linked_console.linked_lathe)
var/datum/component/material_container/linked_materials = linked_console.linked_lathe.GetComponent(/datum/component/material_container)
for(var/material in exp_on.materials)
linked_materials.insert_amount( min((linked_materials.max_amount - linked_materials.total_amount), (exp_on.materials[material])), material)
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
visible_message("<span class='danger'>[src]'s crusher goes way too many levels too high, crushing right through space-time!</span>")
playsound(loc, 'sound/effects/supermatter.ogg', 50, TRUE, -3)
investigate_log("Experimentor has triggered the 'throw things' reaction.", "experimentor")
for(var/atom/movable/AM in oview(7,src))
if(!AM.anchored)
spawn(0)
AM.throw_at(src,10,1)
if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("<span class='danger'>[src]'s crusher goes one level too high, crushing right into space-time!</span>")
playsound(loc, 'sound/effects/supermatter.ogg', 50, TRUE, -3)
investigate_log("Experimentor has triggered the 'minor throw things' reaction.", "experimentor")
var/list/throwAt = list()
for(var/atom/movable/AM in oview(7,src))
if(!AM.anchored)
throwAt.Add(AM)
for(var/counter = 1, counter < length(throwAt), ++counter)
var/atom/movable/cast = throwAt[counter]
spawn(0)
cast.throw_at(pick(throwAt),10,1)
ejectItem(TRUE)
////////////////////////////////////////////////////////////////////////////////////////////////
if(exp == FAIL)
var/a = pick("rumbles","shakes","vibrates","shudders")
var/b = pick("crushes","spins","viscerates","smashes","insults")
visible_message("<span class='warning'>[exp_on] [a], and [b], the experiment was a failure.</span>")
if(exp == SCANTYPE_DISCOVER)
visible_message("[src] scans [exp_on], revealing its true nature!")
playsound(loc, 'sound/effects/supermatter.ogg', 50, 3, -1)
var/obj/item/relic/R = loaded_item
R.reveal()
investigate_log("Experimentor has revealed a relic with effect ID <span class='danger'>[R.function_id]</span> effect.", "experimentor")
ejectItem()
//Global reactions
if(prob(EFFECT_PROB_VERYLOW) && prob(13))
visible_message("<span class='warning'>Experimentor draws the life essence of those nearby!</span>")
for(var/mob/living/m in view(4,src))
to_chat(m, "<span class='danger'>You feel your flesh being torn from you, mists of blood drifting to [src]!</span>")
m.take_overall_damage(50)
investigate_log("Experimentor has taken 50 brute a blood sacrifice from [m]", "experimentor")
if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(87))
var/globalMalf = rand(1,87)
if(globalMalf < 15)
visible_message("<span class='warning'>[src]'s onboard detection system has malfunctioned!</span>")
item_reactions["[exp_on.type]"] = pick(SCANTYPE_POKE,SCANTYPE_IRRADIATE,SCANTYPE_GAS,SCANTYPE_HEAT,SCANTYPE_COLD,SCANTYPE_OBLITERATE)
ejectItem()
if(globalMalf > 16 && globalMalf < 35)
visible_message("<span class='warning'>[src] melts [exp_on], ian-izing the air around it!</span>")
throwSmoke(loc)
var/mob/living/tracked_ian = locate(/mob/living/simple_animal/pet/dog/corgi/ian) in GLOB.mob_living_list
if(tracked_ian)
throwSmoke(tracked_ian.loc)
tracked_ian.loc = loc
if(tracked_ian.buckled)
tracked_ian.unbuckle(force = TRUE)
investigate_log("Experimentor has stolen Ian!", "experimentor") //...if anyone ever fixes it...
else
new /mob/living/simple_animal/pet/dog/corgi(loc)
investigate_log("Experimentor has spawned a new corgi.", "experimentor")
ejectItem(TRUE)
if(globalMalf > 36 && globalMalf < 59)
visible_message("<span class='warning'>[src] encounters a run-time error!</span>")
throwSmoke(loc)
var/mob/living/tracked_runtime = locate(/mob/living/simple_animal/pet/cat/runtime) in GLOB.mob_living_list
if(tracked_runtime)
throwSmoke(tracked_runtime.loc)
tracked_runtime.loc = loc
if(tracked_runtime.buckled)
tracked_runtime.unbuckle(force = TRUE)
investigate_log("Experimentor has stolen Runtime!", "experimentor")
else
new /mob/living/simple_animal/pet/cat(loc)
investigate_log("Experimentor failed to steal runtime, and instead spawned a new cat.", "experimentor")
ejectItem(TRUE)
if(globalMalf > 60)
visible_message("<span class='warning'>[src] begins to smoke and hiss, shaking violently!</span>")
use_power(500000)
investigate_log("Experimentor has drained power from its APC", "experimentor")
spawn(resetTime)
icon_state = "h_lathe"
recentlyExperimented = 0
/datum/milla_safe/experimentor_temperature
/datum/milla_safe/experimentor_temperature/on_run(obj/machinery/r_n_d/experimentor/experimentor, delta, min_new_temp)
var/turf/T = get_turf(experimentor)
var/datum/gas_mixture/env = get_turf_air(T)
var/transfer_moles = 0.25 * env.total_moles()
var/datum/gas_mixture/removed = env.remove(transfer_moles)
if(removed)
var/heat_capacity = removed.heat_capacity()
if(heat_capacity == 0 || heat_capacity == null)
heat_capacity = 1
removed.set_temperature(max(min_new_temp, (removed.temperature() * heat_capacity + delta) / heat_capacity))
env.merge(removed)
/obj/machinery/r_n_d/experimentor/Topic(href, href_list)
if(..())
return
if(!Adjacent(usr) && !issilicon(usr))
return
usr.set_machine(src)
var/scantype = href_list["function"]
var/obj/item/process = locate(href_list["item"]) in src
if(href_list["close"])
usr << browse(null, "window=experimentor")
return
else if(scantype == "search")
var/obj/machinery/computer/rdconsole/D = locate(/obj/machinery/computer/rdconsole) in orange(range, src)
if(D)
linked_console = D
else if(scantype == "eject")
ejectItem()
else if(scantype == "refresh")
updateUsrDialog()
else
if(recentlyExperimented)
to_chat(usr, "<span class='warning'>[src] has been used too recently!</span>")
return
else if(!loaded_item)
updateUsrDialog() //Set the interface to unloaded mode
to_chat(usr, "<span class='warning'>[src] is not currently loaded!</span>")
return
else if(!process || process != loaded_item) //Interface exploit protection (such as hrefs or swapping items with interface set to old item)
updateUsrDialog() //Refresh interface to update interface hrefs
to_chat(usr, "<span class='danger'>Interface failure detected in [src]. Please try again.</span>")
return
var/dotype
if(text2num(scantype) == SCANTYPE_DISCOVER)
dotype = SCANTYPE_DISCOVER
else
dotype = matchReaction(process,scantype)
experiment(dotype,process)
use_power(750)
if(dotype != FAIL)
if(process && process.origin_tech)
var/list/temp_tech = ConvertReqString2List(process.origin_tech)
var/datum/research/F = linked_console.get_files()
if(!F)
return
for(var/T in temp_tech)
F.UpdateTech(T, temp_tech[T])
updateUsrDialog()
return
//~~~~~~~~Admin logging proc, aka the Powergamer Alarm~~~~~~~~
/obj/machinery/r_n_d/experimentor/proc/warn_admins(mob/user, ReactionName)
var/turf/T = get_turf(src)
message_admins("Experimentor reaction: [ReactionName] generated by [key_name_admin(user)] at ([T.x], [T.y], [T.z] - <A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
log_game("Experimentor reaction: [ReactionName] generated by [key_name(user)] in ([T.x], [T.y], [T.z])")
#undef SCANTYPE_POKE
#undef SCANTYPE_IRRADIATE
#undef SCANTYPE_GAS
#undef SCANTYPE_HEAT
#undef SCANTYPE_COLD
#undef SCANTYPE_OBLITERATE
#undef SCANTYPE_DISCOVER
#undef EFFECT_PROB_VERYLOW
#undef EFFECT_PROB_LOW
#undef EFFECT_PROB_MEDIUM
#undef EFFECT_PROB_HIGH
#undef EFFECT_PROB_VERYHIGH
#undef FAIL
+2 -3
View File
@@ -14,14 +14,13 @@ The major research and development is performed using a combination of four mach
- R&D Console: A computer console that allows you to manipulate the other devices that are linked to it and view/manipulate the
technologies you have researched so far.
- Protolathe: Used to make new hand-held devices and parts for larger devices. All metals and reagents as raw materials.
- Destructive Analyzer: You can put hand-held objects into it and it'll analyze them for technological advancements but it destroys
them in the process. Destroyed items will send their raw materials to a linked Protolathe (if any)
- Scientific Analyzer: You can put hand-held objects into it and it'll analyze them for technological advancements
- Circuit Imprinter: Similar to the Protolathe, it allows for the construction of circuit boards. Uses glass and acid as the raw
materials.
While researching you are dealing with two different types of information: Technology Paths and Device Designs. Technology Paths
are the "Tech Trees" of the game. You start out with a number of them at the game start and they are improved by using the
Destructive Analyzer. By themselves, they don't do a whole lot. However, they unlock Device Designs. This is the information used
Scientific Analyzer. By themselves, they don't do a whole lot. However, they unlock Device Designs. This is the information used
by the circuit imprinter and the protolathe to produce objects.
//EXISTING TECH
+91 -63
View File
@@ -1,7 +1,7 @@
/*
Research and Development (R&D) Console
This is the main work horse of the R&D system. It contains the menus/controls for the Destructive Analyzer, Protolathe, and Circuit
This is the main work horse of the R&D system. It contains the menus/controls for the Scientific Analyzer, Protolathe, and Circuit
imprinter. It also contains the /datum/research holder with all the known/possible technology paths and device designs.
Basic use: When it first is created, it will attempt to link up to related devices within 3 squares. It'll only link up if they
@@ -43,7 +43,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
#define MENU_MAIN 0
#define MENU_DISK 2
#define MENU_DESTROY 3
#define MENU_ANALYZER 3
#define MENU_LATHE 4
#define MENU_IMPRINTER 5
#define MENU_SETTINGS 6
@@ -69,8 +69,8 @@ won't update every console in existence) but it's more of a hassle to do. Also,
var/obj/item/disk/tech_disk/t_disk = null
/// Holder for the inserted design disk
var/obj/item/disk/design_disk/d_disk = null
/// Linked destructive analyser
var/obj/machinery/r_n_d/destructive_analyzer/linked_destroy = null
/// Linked scientific analyser
var/obj/machinery/r_n_d/scientific_analyzer/linked_analyzer = null
/// Linked protolathe
var/obj/machinery/r_n_d/protolathe/linked_lathe = null
/// Linked circuit imprinter
@@ -128,9 +128,9 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if(!isnull(D.linked_console) || D.panel_open)
continue
if(istype(D, /obj/machinery/r_n_d/destructive_analyzer))
if(linked_destroy == null)
linked_destroy = D
if(istype(D, /obj/machinery/r_n_d/scientific_analyzer))
if(linked_analyzer == null)
linked_analyzer = D
D.linked_console = src
else if(istype(D, /obj/machinery/r_n_d/protolathe))
@@ -159,9 +159,9 @@ won't update every console in existence) but it's more of a hassle to do. Also,
QDEL_NULL(t_disk)
QDEL_NULL(d_disk)
matching_designs.Cut()
if(linked_destroy)
linked_destroy.linked_console = null
linked_destroy = null
if(linked_analyzer)
linked_analyzer.linked_console = null
linked_analyzer = null
if(linked_lathe)
linked_lathe.linked_console = null
linked_lathe = null
@@ -196,7 +196,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
return
D.loc = src
to_chat(user, "<span class='notice'>You add the disk to the machine!</span>")
else if(!(linked_destroy && linked_destroy.busy) && !(linked_lathe && linked_lathe.busy) && !(linked_imprinter && linked_imprinter.busy))
else if(!(linked_analyzer && linked_analyzer.busy) && !(linked_lathe && linked_lathe.busy) && !(linked_imprinter && linked_imprinter.busy))
..()
SStgui.update_uis(src)
return
@@ -247,23 +247,23 @@ won't update every console in existence) but it's more of a hassle to do. Also,
clear_wait_message()
SStgui.update_uis(src)
/obj/machinery/computer/rdconsole/proc/start_destroyer(mob/user)
if(!linked_destroy)
/obj/machinery/computer/rdconsole/proc/start_analyzer_destroy(mob/user)
if(!linked_analyzer)
return
if(linked_destroy.busy)
to_chat(user, "<span class='danger'>[linked_destroy] is busy at the moment.</span>")
if(linked_analyzer.busy)
to_chat(user, "<span class='danger'>[linked_analyzer] is busy at the moment.</span>")
return
if(!linked_destroy.loaded_item)
to_chat(user, "<span class='danger'>[linked_destroy] appears to be empty.</span>")
if(!linked_analyzer.loaded_item)
to_chat(user, "<span class='danger'>[linked_analyzer] appears to be empty.</span>")
return
var/datum/research/files = get_files()
if(!files)
return
var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech)
var/list/temp_tech = linked_analyzer.ConvertReqString2List(linked_analyzer.loaded_item.origin_tech)
var/pointless = FALSE
for(var/T in temp_tech)
@@ -273,63 +273,93 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if(!pointless)
var/choice = alert(user, "This item does not raise tech levels. Proceed destroying loaded item anyway?", "Are you sure you want to destroy this item?", "Proceed", "Cancel")
if(choice == "Cancel" || !linked_destroy)
if(choice == "Cancel" || !linked_analyzer)
return
linked_destroy.busy = TRUE
linked_analyzer.busy = TRUE
add_wait_message("Processing and Updating Database...", DECONSTRUCT_DELAY)
flick("d_analyzer_process", linked_destroy)
addtimer(CALLBACK(src, PROC_REF(finish_destroyer), user, temp_tech), DECONSTRUCT_DELAY)
flick("s_analyzer_process", linked_analyzer)
addtimer(CALLBACK(src, PROC_REF(finish_analyzer), user, temp_tech), DECONSTRUCT_DELAY)
/obj/machinery/computer/rdconsole/proc/start_analyzer_discover(mob/user)
if(!linked_analyzer)
return
if(linked_analyzer.busy)
to_chat(user, "<span class='danger'>[linked_analyzer] is busy at the moment.</span>")
return
if(!linked_analyzer.loaded_item)
to_chat(user, "<span class='danger'>[linked_analyzer] appears to be empty.</span>")
return
if(!istype(linked_analyzer.loaded_item, /obj/item/relic))
message_admins("[key_name_admin(user)] attempted to discover something that isnt a strange object. Possible HREF exploit.")
return
var/obj/item/relic/R = linked_analyzer.loaded_item
visible_message("[linked_analyzer] scans [linked_analyzer.loaded_item], revealing its true nature!")
playsound(loc, 'sound/effects/supermatter.ogg', 50, 3, -1)
// LETS GO GAMBLING
R.reveal()
R.forceMove(get_turf(linked_analyzer))
linked_analyzer.loaded_item = null
investigate_log("Scientific analyser has revealed a relic with effect ID <span class='danger'>[R.function_id]</span> effect.", "strangeobjects")
linked_analyzer.icon_state = "s_analyzer"
SStgui.update_uis(src)
// Sends salvaged materials to a linked protolathe, if any.
/obj/machinery/computer/rdconsole/proc/send_mats()
if(!linked_lathe || !linked_destroy || !linked_destroy.loaded_item)
if(!linked_lathe || !linked_analyzer || !linked_analyzer.loaded_item)
return
for(var/material in linked_destroy.loaded_item.materials)
for(var/material in linked_analyzer.loaded_item.materials)
var/space = linked_lathe.materials.max_amount - linked_lathe.materials.total_amount
// as item rating increases, amount salvageable increases
var/salvageable = linked_destroy.loaded_item.materials[material] * (linked_destroy.decon_mod / 10)
var/salvageable = linked_analyzer.loaded_item.materials[material] * (linked_analyzer.decon_mod / 10)
// but you shouldn't salvage more than the raw materials amount
var/available = linked_destroy.loaded_item.materials[material]
var/available = linked_analyzer.loaded_item.materials[material]
var/can_insert = min(space, salvageable, available)
linked_lathe.materials.insert_amount(can_insert, material)
/obj/machinery/computer/rdconsole/proc/finish_destroyer(mob/user, list/temp_tech)
/obj/machinery/computer/rdconsole/proc/finish_analyzer(mob/user, list/temp_tech)
clear_wait_message()
if(!linked_destroy || !temp_tech)
if(!linked_analyzer || !temp_tech)
return
var/datum/research/files = get_files()
if(!files)
return
if(!linked_destroy.loaded_item)
to_chat(user, "<span class='danger'>[linked_destroy] appears to be empty.</span>")
if(!linked_analyzer.loaded_item)
to_chat(user, "<span class='danger'>[linked_analyzer] appears to be empty.</span>")
else
for(var/T in temp_tech)
files.UpdateTech(T, temp_tech[T])
send_mats()
linked_destroy.loaded_item = null
linked_analyzer.loaded_item = null
for(var/obj/I in linked_destroy.contents)
for(var/obj/I in linked_analyzer.contents)
for(var/mob/M in I.contents)
M.death()
if(istype(I, /obj/item/stack))//Only deconstructs one item in a stack at a time instead of the entire stack
var/obj/item/stack/S = I
if(S.amount > 1)
S.amount--
linked_destroy.loaded_item = S
linked_analyzer.loaded_item = S
else
qdel(S)
linked_destroy.icon_state = "d_analyzer"
else if(!(I in linked_destroy.component_parts))
linked_analyzer.icon_state = "s_analyzer"
else if(!(I in linked_analyzer.component_parts))
qdel(I)
linked_destroy.icon_state = "d_analyzer"
linked_analyzer.icon_state = "s_analyzer"
linked_destroy.busy = FALSE
linked_analyzer.busy = FALSE
use_power(DECONSTRUCT_POWER)
menu = MENU_DESTROY
menu = MENU_ANALYZER
SStgui.update_uis(src)
@@ -590,18 +620,21 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if(design && d_disk && can_copy_design(design))
d_disk.blueprint = design
if("eject_item") //Eject the item inside the destructive analyzer.
if(linked_destroy)
if(linked_destroy.busy)
to_chat(ui.user, "<span class='danger'>[linked_destroy] is busy at the moment.</span>")
if("eject_item") //Eject the item inside the scientific analyzer.
if(linked_analyzer)
if(linked_analyzer.busy)
to_chat(ui.user, "<span class='danger'>[linked_analyzer] is busy at the moment.</span>")
else if(linked_destroy.loaded_item)
linked_destroy.loaded_item.forceMove(linked_destroy.loc)
linked_destroy.loaded_item = null
linked_destroy.icon_state = "d_analyzer"
else if(linked_analyzer.loaded_item)
linked_analyzer.loaded_item.forceMove(linked_analyzer.loc)
linked_analyzer.loaded_item = null
linked_analyzer.icon_state = "s_analyzer"
if("deconstruct") //Deconstruct the item in the destructive analyzer and update the research holder.
start_destroyer(ui.user)
if("deconstruct") //Deconstruct the item in the scientific analyzer and update the research holder.
start_analyzer_destroy(ui.user)
if("discover") // Analyse the object in the scientific analyser and discover it
start_analyzer_discover(ui.user)
if("build") //Causes the Protolathe to build something.
start_machine(linked_lathe, params["id"], text2num(params["amount"]))
@@ -637,10 +670,10 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if("disconnect") //The R&D console disconnects with a specific device.
switch(params["item"])
if("destroy")
if(linked_destroy)
linked_destroy.linked_console = null
linked_destroy = null
if("analyze")
if(linked_analyzer)
linked_analyzer.linked_console = null
linked_analyzer = null
if("lathe")
if(linked_lathe)
linked_lathe.linked_console = null
@@ -849,7 +882,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
data["wait_message"] = wait_message
data["src_ref"] = UID()
data["linked_destroy"] = linked_destroy ? 1 : 0
data["linked_analyzer"] = linked_analyzer ? 1 : 0
data["linked_lathe"] = linked_lathe ? 1 : 0
data["linked_imprinter"] = linked_imprinter ? 1 : 0
data["disk_type"] = d_disk ? "design" : (t_disk ? "tech" : null)
@@ -933,11 +966,12 @@ won't update every console in existence) but it's more of a hassle to do. Also,
material["name"] = CallMaterialName(M)
material["amount"] = d_disk.blueprint.materials[M]
else if(menu == MENU_DESTROY && linked_destroy && linked_destroy.loaded_item)
else if(menu == MENU_ANALYZER && linked_analyzer && linked_analyzer.loaded_item)
var/list/loaded_item_list = list()
data["loaded_item"] = loaded_item_list
loaded_item_list["name"] = linked_destroy.loaded_item.name
var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech)
data["can_discover"] = istype(linked_analyzer.loaded_item, /obj/item/relic)
loaded_item_list["name"] = linked_analyzer.loaded_item.name
var/list/temp_tech = linked_analyzer.ConvertReqString2List(linked_analyzer.loaded_item.origin_tech)
var/list/tech_levels = list()
data["tech_levels"] = tech_levels
for(var/v in files.known_tech)
@@ -986,12 +1020,6 @@ won't update every console in existence) but it's more of a hassle to do. Also,
desc = "A console used to interface with R&D tools."
autolink_id = "station_rnd"
/obj/machinery/computer/rdconsole/experiment
name = "\improper E.X.P.E.R.I-MENTOR R&D console"
autolink_id = "station_rnd"
range = 5
circuit = /obj/item/circuitboard/rdconsole/experiment
/obj/machinery/computer/rdconsole/public
name = "public R&D console"
req_one_access = list()
@@ -1007,7 +1035,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
#undef IMPRINTER_DELAY
#undef MENU_MAIN
#undef MENU_DISK
#undef MENU_DESTROY
#undef MENU_ANALYZER
#undef MENU_LATHE
#undef MENU_IMPRINTER
#undef MENU_SETTINGS
@@ -1,60 +1,60 @@
/*
Destructive Analyzer
Scientific Analyzer
It is used to destroy hand-held objects and advance technological research. Controls are in the linked R&D console.
It is used to analyze hand-held objects and advance technological research. Controls are in the linked R&D console.
Note: Must be placed within 3 tiles of the R&D Console
*/
/obj/machinery/r_n_d/destructive_analyzer
name = "Destructive Analyzer"
desc = "Learn science by destroying things!"
icon_state = "d_analyzer"
/obj/machinery/r_n_d/scientific_analyzer
name = "Scientific Analyzer"
desc = "Learn science by analyzing things!"
icon_state = "s_analyzer"
var/decon_mod = 0
/obj/machinery/r_n_d/destructive_analyzer/Initialize(mapload)
/obj/machinery/r_n_d/scientific_analyzer/Initialize(mapload)
. = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/destructive_analyzer(null)
component_parts += new /obj/item/circuitboard/scientific_analyzer(null)
component_parts += new /obj/item/stock_parts/scanning_module(null)
component_parts += new /obj/item/stock_parts/manipulator(null)
component_parts += new /obj/item/stock_parts/micro_laser(null)
RefreshParts()
/obj/machinery/r_n_d/destructive_analyzer/upgraded/Initialize(mapload)
/obj/machinery/r_n_d/scientific_analyzer/upgraded/Initialize(mapload)
. = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/destructive_analyzer(null)
component_parts += new /obj/item/circuitboard/scientific_analyzer(null)
component_parts += new /obj/item/stock_parts/scanning_module/phasic(null)
component_parts += new /obj/item/stock_parts/manipulator/pico(null)
component_parts += new /obj/item/stock_parts/micro_laser/ultra(null)
RefreshParts()
/obj/machinery/r_n_d/destructive_analyzer/Destroy()
/obj/machinery/r_n_d/scientific_analyzer/Destroy()
if(linked_console)
linked_console.linked_destroy = null
linked_console.linked_analyzer = null
return ..()
/obj/machinery/r_n_d/destructive_analyzer/RefreshParts()
/obj/machinery/r_n_d/scientific_analyzer/RefreshParts()
var/T = 0
for(var/obj/item/stock_parts/S in component_parts)
T += S.rating
decon_mod = T
/obj/machinery/r_n_d/destructive_analyzer/proc/ConvertReqString2List(list/source_list)
/obj/machinery/r_n_d/scientific_analyzer/proc/ConvertReqString2List(list/source_list)
var/list/temp_list = params2list(source_list)
for(var/O in temp_list)
temp_list[O] = text2num(temp_list[O])
return temp_list
/obj/machinery/r_n_d/destructive_analyzer/attackby__legacy__attackchain(obj/item/O as obj, mob/user as mob, params)
/obj/machinery/r_n_d/scientific_analyzer/attackby__legacy__attackchain(obj/item/O as obj, mob/user as mob, params)
if(istype(O, /obj/item/storage/part_replacer))
return ..()
if(default_deconstruction_screwdriver(user, "d_analyzer_t", "d_analyzer", O))
if(default_deconstruction_screwdriver(user, "s_analyzer_t", "s_analyzer", O))
if(linked_console)
linked_console.linked_destroy = null
linked_console.linked_analyzer = null
linked_console = null
return
@@ -91,7 +91,7 @@ Note: Must be placed within 3 tiles of the R&D Console
O.loc = src
to_chat(user, "<span class='notice'>You add [O] to [src]!</span>")
SStgui.update_uis(linked_console)
flick("d_analyzer_la", src)
flick("s_analyzer_la", src)
spawn(10)
icon_state = "d_analyzer_l"
icon_state = "s_analyzer_l"
busy = FALSE
+7 -8
View File
@@ -57,6 +57,10 @@
/mob/living/carbon/human/monkey,
)
// Assign it a random tech level
var/list/possible_techs = list("materials", "engineering", "plasmatech", "powerstorage", "bluespace", "biotech", "combat", "magnets", "programming")
origin_tech = "[pick(possible_techs)]=[rand(2, 5)]"
/obj/item/relic/proc/reveal()
if(revealed) //Re-rolling your relics seems a bit overpowered, yes?
@@ -76,13 +80,8 @@
STRANGEOBJECT_FUNCTION_PET_SPAWN,
)
origin_tech = pick(
"engineering=[rand(2,5)]",
"magnets=[rand(2,5)]",
"plasmatech=[rand(2,5)]",
"programming=[rand(2,5)]",
"powerstorage=[rand(2,5)]",
)
// You discovered it - you gambled your possible fortune! AW DANGIT!
origin_tech = null
/obj/item/relic/attack_self__legacy__attackchain(mob/user)
@@ -199,7 +198,7 @@
message_admins("[RelicType] relic activated by [key_name_admin(user)] in ([T.x], [T.y], [T.z] - <A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
log_game(log_msg)
investigate_log(log_msg, "experimentor")
investigate_log(log_msg, "strangeobjects")
// Make some magic smoke
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 22 KiB

+2 -3
View File
@@ -2585,7 +2585,6 @@
#include "code\modules\pda\cart_apps.dm"
#include "code\modules\pda\core_apps.dm"
#include "code\modules\pda\games.dm"
#include "code\modules\pda\games\minesweeper.dm"
#include "code\modules\pda\messenger.dm"
#include "code\modules\pda\messenger_plugins.dm"
#include "code\modules\pda\nanobank.dm"
@@ -2593,6 +2592,7 @@
#include "code\modules\pda\pda_tgui.dm"
#include "code\modules\pda\pdas.dm"
#include "code\modules\pda\utilities.dm"
#include "code\modules\pda\games\minesweeper.dm"
#include "code\modules\persistence\persistence.dm"
#include "code\modules\point\point.dm"
#include "code\modules\power\cell.dm"
@@ -2753,8 +2753,6 @@
#include "code\modules\research\backup_console.dm"
#include "code\modules\research\circuitprinter.dm"
#include "code\modules\research\designs.dm"
#include "code\modules\research\destructive_analyzer.dm"
#include "code\modules\research\experimentor.dm"
#include "code\modules\research\message_server.dm"
#include "code\modules\research\protolathe.dm"
#include "code\modules\research\rd-readme.dm"
@@ -2762,6 +2760,7 @@
#include "code\modules\research\rdmachines.dm"
#include "code\modules\research\research.dm"
#include "code\modules\research\rnd_network_controller.dm"
#include "code\modules\research\scientific_analyzer.dm"
#include "code\modules\research\server.dm"
#include "code\modules\research\strange_objects.dm"
#include "code\modules\research\anomaly\anomaly.dm"
@@ -2,17 +2,17 @@ import { classes } from 'common/react';
import { useBackend } from '../../backend';
import { Button, Icon, LabeledList, Section, Table } from '../../components';
export const DeconstructionMenu = (props, context) => {
export const AnalyzerMenu = (props, context) => {
const { data, act } = useBackend(context);
const { tech_levels, loaded_item, linked_destroy } = data;
const { tech_levels, loaded_item, linked_analyzer, can_discover } = data;
if (!linked_destroy) {
return <Section title="Deconstruction Menu">NO DESTRUCTIVE ANALYZER LINKED TO CONSOLE</Section>;
if (!linked_analyzer) {
return <Section title="Analysis Menu">NO SCIENTIFIC ANALYZER LINKED TO CONSOLE</Section>;
}
if (!loaded_item) {
return <Section title="Deconstruction Menu">No item loaded. Standing by...</Section>;
return <Section title="Analysis Menu">No item loaded. Standing by...</Section>;
}
return (
@@ -35,6 +35,15 @@ export const DeconstructionMenu = (props, context) => {
act('eject_item');
}}
/>
{!can_discover || (
<Button
content="Discover"
icon="atom"
onClick={() => {
act('discover');
}}
/>
)}
</>
}
>
@@ -30,7 +30,7 @@ const MainSettings = (props, context) => {
const DeviceSettings = (props, context) => {
const { data, act } = useBackend(context);
const { linked_destroy, linked_lathe, linked_imprinter } = data;
const { linked_analyzer, linked_lathe, linked_imprinter } = data;
return (
<Section
@@ -38,12 +38,12 @@ const DeviceSettings = (props, context) => {
buttons={<Button icon="link" content="Re-sync with Nearby Devices" onClick={() => act('find_device')} />}
>
<LabeledList>
<LabeledList.Item label="Destructive Analyzer">
<LabeledList.Item label="Scientific Analyzer">
<Button
icon="unlink"
disabled={!linked_destroy}
content={linked_destroy ? 'Unlink' : 'Undetected'}
onClick={() => act('disconnect', { item: 'destroy' })}
disabled={!linked_analyzer}
content={linked_analyzer ? 'Unlink' : 'Undetected'}
onClick={() => act('disconnect', { item: 'analyze' })}
/>
</LabeledList.Item>
<LabeledList.Item label="Protolathe">
@@ -6,14 +6,14 @@ import { DataDiskMenu } from './DataDiskMenu';
import { LatheMenu } from './LatheMenu';
import { LinkMenu } from './LinkMenu';
import { SettingsMenu } from './SettingsMenu';
import { DeconstructionMenu } from './DeconstructionMenu';
import { AnalyzerMenu } from './AnalyzerMenu';
const Tab = Tabs.Tab;
export const MENU = {
MAIN: 0,
DISK: 2,
DESTROY: 3,
ANALYZE: 3,
LATHE: 4,
IMPRINTER: 5,
SETTINGS: 6,
@@ -32,8 +32,8 @@ const decideTab = (tab) => {
return <MainMenu />;
case MENU.DISK:
return <DataDiskMenu />;
case MENU.DESTROY:
return <DeconstructionMenu />;
case MENU.ANALYZE:
return <AnalyzerMenu />;
case MENU.LATHE:
case MENU.IMPRINTER:
return <LatheMenu />;
@@ -58,7 +58,7 @@ export const RndConsole = (properties, context) => {
return <LinkMenu />;
}
const { menu, linked_destroy, linked_lathe, linked_imprinter, wait_message } = data;
const { menu, linked_analyzer, linked_lathe, linked_imprinter, wait_message } = data;
return (
<Window width={800} height={550}>
@@ -68,8 +68,8 @@ export const RndConsole = (properties, context) => {
<ConsoleTab icon="flask" menu={MENU.MAIN}>
Research
</ConsoleTab>
{!!linked_destroy && (
<ConsoleTab icon="microscope" menu={MENU.DESTROY}>
{!!linked_analyzer && (
<ConsoleTab icon="microscope" menu={MENU.ANALYZE}>
Analyze
</ConsoleTab>
)}
File diff suppressed because one or more lines are too long