mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 08:34:16 +01:00
[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:
@@ -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)
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+19
-19
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user