diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 05a6862dd034..a3284f85f3fc 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -35,6 +35,7 @@ var/list/valid_items = list() //valid items for special reactions like transforming var/list/critical_items_typecache //items that can cause critical reactions var/banned_typecache // items that won't be produced + var/autoexperiment = 0 /obj/machinery/rnd/experimentor/proc/ConvertReqString2List(list/source_list) var/list/temp_list = params2list(source_list) @@ -86,13 +87,18 @@ /obj/item/transfer_valve)) /obj/machinery/rnd/experimentor/RefreshParts() + var/new_resetTime = 15 + var/new_badThingCoeff = 0 for(var/obj/item/stock_parts/manipulator/M in component_parts) - if(resetTime > 0 && (resetTime - M.rating) >= 1) - resetTime -= M.rating + new_resetTime -= M.rating + if(new_resetTime < 1) + new_resetTime = 1 for(var/obj/item/stock_parts/scanning_module/M in component_parts) - badThingCoeff += M.rating*2 + new_badThingCoeff += M.rating*2 for(var/obj/item/stock_parts/micro_laser/M in component_parts) - badThingCoeff += M.rating + new_badThingCoeff += M.rating + resetTime = min(resetTime, new_resetTime) + badThingCoeff = max(badThingCoeff, new_badThingCoeff) /obj/machinery/rnd/experimentor/examine(mob/user) . = ..() @@ -130,14 +136,14 @@ dat += "Loaded Item: [loaded_item]" dat += "
Available tests:" - dat += "Poke" - dat += "Irradiate" - dat += "Gas" - dat += "Burn" - dat += "Freeze" - dat += "Destroy
" + dat += "PokeA" + dat += "IrradiateA" + dat += "GasA" + dat += "BurnA" + dat += "FreezeA" + dat += "DestroyA" if(istype(loaded_item,/obj/item/relic)) - dat += "Discover" + dat += "Discover" dat += "Eject" var/list/listin = techweb_item_boost_check(src) if(listin) @@ -170,7 +176,7 @@ usr.set_machine(src) var/scantype = href_list["function"] - var/obj/item/process = locate(href_list["item"]) in src + var/toggle_auto = href_list["toggle_auto"] if(href_list["close"]) usr << browse(null, "window=experimentor") @@ -184,27 +190,39 @@ else if(scantype == "refresh") updateUsrDialog() else - if(recentlyExperimented) - to_chat(usr, "[src] has been used too recently!") - else if(!loaded_item) - to_chat(usr, "[src] is not currently loaded!") - else if(!process || process != loaded_item) //Interface exploit protection (such as hrefs or swapping items with interface set to old item) - to_chat(usr, "Interface failure detected in [src]. Please try again.") + if(toggle_auto && scantype == autoexperiment) + autoexperiment = 0 else - var/dotype - if(text2num(scantype) == SCANTYPE_DISCOVER) - dotype = SCANTYPE_DISCOVER - else - dotype = matchReaction(process,scantype) - experiment(dotype,process) - use_power(750) - if(dotype != FAIL) - var/list/nodes = techweb_item_boost_check(process) - var/picked = pickweight(nodes) //This should work. - if(linked_console) - linked_console.stored_research.boost_with_path(SSresearch.techweb_node_by_id(picked), process.type) + if(toggle_auto) + autoexperiment = text2num(scantype) + do_experiment(scantype) updateUsrDialog() +/obj/machinery/rnd/experimentor/proc/do_experiment(scantype = autoexperiment) + var/obj/item/process = loaded_item + if(!scantype) + return + if(recentlyExperimented) + to_chat(usr, "[src] has been used too recently!") + else if(!loaded_item) + to_chat(usr, "[src] is not currently loaded!") + autoexperiment = 0 + else if(!process || process != loaded_item) //Interface exploit protection (such as hrefs or swapping items with interface set to old item) + to_chat(usr, "Interface failure detected in [src]. Please try again.") + else + var/dotype + if(text2num(scantype) == SCANTYPE_DISCOVER) + dotype = SCANTYPE_DISCOVER + else + dotype = matchReaction(process,scantype) + experiment(dotype,process) + use_power(750) + if(dotype != FAIL) + var/list/nodes = techweb_item_boost_check(process) + var/picked = pickweight(nodes) //This should work. + if(linked_console) + linked_console.stored_research.boost_with_path(SSresearch.techweb_node_by_id(picked), process.type) + /obj/machinery/rnd/experimentor/proc/matchReaction(matching,reaction) var/obj/item/D = matching if(D) @@ -241,28 +259,32 @@ smoke.start() -/* yogs start - moved to yogstation/ folder /obj/machinery/rnd/experimentor/proc/experiment(exp,obj/item/exp_on) recentlyExperimented = 1 icon_state = "h_lathe_wloop" var/chosenchem var/criticalReaction = is_type_in_typecache(exp_on, critical_items_typecache) + var/badThingCoeffIfCrit = criticalReaction ? badThingCoeff : 0 // certain malfunctions are desirable for non-critical items //////////////////////////////////////////////////////////////////////////////////////////////// if(exp == SCANTYPE_POKE) visible_message("[src] prods at [exp_on] with mechanical arms.") if(prob(EFFECT_PROB_LOW) && criticalReaction) + autoexperiment = 0 visible_message("[exp_on] is gripped in just the right way, enhancing its focus.") badThingCoeff++ else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions and destroys [exp_on], lashing its arms out at nearby people!") for(var/mob/living/m in oview(1, src)) m.apply_damage(15, BRUTE, pick(BODY_ZONE_HEAD,BODY_ZONE_CHEST,BODY_ZONE_PRECISE_GROIN)) investigate_log("Experimentor dealt minor brute to [m].", INVESTIGATE_EXPERIMENTOR) ejectItem(TRUE) else if(prob(EFFECT_PROB_LOW-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions!") exp = SCANTYPE_OBLITERATE else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, throwing the [exp_on]!") var/mob/living/target = locate(/mob/living) in oview(7,src) if(target) @@ -275,22 +297,26 @@ if(exp == SCANTYPE_IRRADIATE) visible_message("[src] reflects radioactive rays at [exp_on]!") if(prob(EFFECT_PROB_LOW) && criticalReaction) + autoexperiment = 0 visible_message("[exp_on] has activated an unknown subroutine!") cloneMode = TRUE investigate_log("Experimentor has made a clone of [exp_on]", INVESTIGATE_EXPERIMENTOR) ejectItem() else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, melting [exp_on] and leaking radiation!") radiation_pulse(src, 500) ejectItem(TRUE) else if(prob(EFFECT_PROB_LOW-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, spewing toxic waste!") for(var/turf/T in oview(1, src)) if(!T.density) if(prob(EFFECT_PROB_VERYHIGH) && !(locate(/obj/effect/decal/cleanable/greenglow) in T)) var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/greenglow(T) reagentdecal.reagents.add_reagent(/datum/reagent/uranium/radium, 7) - else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) + else if(prob(EFFECT_PROB_MEDIUM-badThingCoeffIfCrit)) + autoexperiment = 0 var/savedName = "[exp_on]" ejectItem(TRUE) var/newPath = text2path(pickweight(valid_items)) @@ -305,9 +331,11 @@ if(exp == SCANTYPE_GAS) visible_message("[src] fills its chamber with gas, [exp_on] included.") if(prob(EFFECT_PROB_LOW) && criticalReaction) + autoexperiment = 0 visible_message("[exp_on] achieves the perfect mix!") new /obj/item/stack/sheet/mineral/plasma(get_turf(pick(oview(1,src)))) - else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) + else if(prob(EFFECT_PROB_VERYLOW-badThingCoeffIfCrit)) + autoexperiment = 0 visible_message("[src] destroys [exp_on], leaking dangerous gas!") chosenchem = pick(/datum/reagent/carbon,/datum/reagent/uranium/radium,/datum/reagent/toxin,/datum/reagent/consumable/condensedcapsaicin,/datum/reagent/drug/mushroomhallucinogen,/datum/reagent/drug/space_drugs,/datum/reagent/consumable/ethanol,/datum/reagent/consumable/ethanol/beepsky_smash) var/datum/reagents/R = new/datum/reagents(50) @@ -320,9 +348,10 @@ smoke.start() qdel(R) ejectItem(TRUE) - else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) + else if(prob(EFFECT_PROB_VERYLOW-badThingCoeffIfCrit)) + autoexperiment = 0 visible_message("[src]'s chemical chamber has sprung a leak!") - chosenchem = pick(/datum/reagent/mutationtoxin/classic,/datum/reagent/nanomachines,/datum/reagent/toxin/acid) + chosenchem = pick(/datum/reagent/mutationtoxin/felinid,/datum/reagent/nanomachines,/datum/reagent/toxin/acid) var/datum/reagents/R = new/datum/reagents(50) R.my_atom = src R.add_reagent(chosenchem , 50) @@ -335,9 +364,11 @@ warn_admins(usr, "[chosenchem] smoke") investigate_log("Experimentor has released [chosenchem] smoke!", INVESTIGATE_EXPERIMENTOR) else if(prob(EFFECT_PROB_LOW-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, spewing harmless gas.") throwSmoke(loc) else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) + autoexperiment = 0 visible_message("[src] melts [exp_on], ionizing the air around it!") empulse(loc, 4, 6) investigate_log("Experimentor has generated an Electromagnetic Pulse.", INVESTIGATE_EXPERIMENTOR) @@ -346,16 +377,18 @@ if(exp == SCANTYPE_HEAT) visible_message("[src] raises [exp_on]'s temperature.") if(prob(EFFECT_PROB_LOW) && criticalReaction) + autoexperiment = 0 visible_message("[src]'s emergency coolant system gives off a small ding!") playsound(src, 'sound/machines/ding.ogg', 50, 1) var/obj/item/reagent_containers/food/drinks/coffee/C = new /obj/item/reagent_containers/food/drinks/coffee(get_turf(pick(oview(1,src)))) - chosenchem = pick(/datum/reagent/toxin/plasma,/datum/reagent/consumable/capsaicin,/datum/reagent/consumable/ethanol) + 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.", INVESTIGATE_EXPERIMENTOR) else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) + autoexperiment = 0 var/turf/start = get_turf(src) var/mob/M = locate(/mob/living) in view(src, 3) var/turf/MT = get_turf(M) @@ -366,11 +399,13 @@ FB.preparePixelProjectile(MT, start) FB.fire() else if(prob(EFFECT_PROB_LOW-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, melting [exp_on] and releasing a burst of flame!") explosion(loc, -1, 0, 0, 0, 0, flame_range = 2) investigate_log("Experimentor started a fire.", INVESTIGATE_EXPERIMENTOR) ejectItem(TRUE) else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, melting [exp_on] and leaking hot air!") var/datum/gas_mixture/env = loc.return_air() var/transfer_moles = 0.25 * env.total_moles() @@ -385,6 +420,7 @@ investigate_log("Experimentor has released hot air.", INVESTIGATE_EXPERIMENTOR) ejectItem(TRUE) else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, activating its emergency coolant systems!") throwSmoke(loc) for(var/mob/living/m in oview(1, src)) @@ -395,20 +431,22 @@ if(exp == SCANTYPE_COLD) visible_message("[src] lowers [exp_on]'s temperature.") if(prob(EFFECT_PROB_LOW) && criticalReaction) + autoexperiment = 0 visible_message("[src]'s emergency coolant system gives off a small ding!") var/obj/item/reagent_containers/food/drinks/coffee/C = new /obj/item/reagent_containers/food/drinks/coffee(get_turf(pick(oview(1,src)))) playsound(src, 'sound/machines/ding.ogg', 50, 1) //Ding! Your death coffee is ready! - chosenchem = pick(/datum/reagent/uranium,/datum/reagent/consumable/frostoil,/datum/reagent/medicine/ephedrine) + 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.", INVESTIGATE_EXPERIMENTOR) else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, shattering [exp_on] and releasing a dangerous cloud of coolant!") var/datum/reagents/R = new/datum/reagents(50) R.my_atom = src - R.add_reagent(/datum/reagent/consumable/frostoil , 50) + R.add_reagent(/datum/reagent/consumable/frostoil, 50) investigate_log("Experimentor has released frostoil gas.", INVESTIGATE_EXPERIMENTOR) var/datum/effect_system/smoke_spread/chem/smoke = new smoke.set_up(R, 0, src, silent = TRUE) @@ -417,6 +455,7 @@ qdel(R) ejectItem(TRUE) else if(prob(EFFECT_PROB_LOW-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, shattering [exp_on] and leaking cold air!") var/datum/gas_mixture/env = loc.return_air() var/transfer_moles = 0.25 * env.total_moles() @@ -431,6 +470,7 @@ investigate_log("Experimentor has released cold air.", INVESTIGATE_EXPERIMENTOR) ejectItem(TRUE) else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) + autoexperiment = 0 visible_message("[src] malfunctions, releasing a flurry of chilly air as [exp_on] pops out!") var/datum/effect_system/smoke_spread/smoke = new smoke.set_up(0, loc) @@ -438,6 +478,7 @@ ejectItem() //////////////////////////////////////////////////////////////////////////////////////////////// if(exp == SCANTYPE_OBLITERATE) + autoexperiment = 0 visible_message("[exp_on] activates the crushing mechanism, [exp_on] is destroyed!") if(linked_console.linked_lathe) var/datum/component/material_container/linked_materials = linked_console.linked_lathe.GetComponent(/datum/component/material_container) @@ -472,6 +513,7 @@ visible_message("[exp_on] [a], and [b], the experiment was a failure.") if(exp == SCANTYPE_DISCOVER) + autoexperiment = 0 visible_message("[src] scans the [exp_on], revealing its true nature!") playsound(src, 'sound/effects/supermatter.ogg', 50, 3, -1) var/obj/item/relic/R = loaded_item @@ -479,52 +521,58 @@ investigate_log("Experimentor has revealed a relic with [R.realProc] effect.", INVESTIGATE_EXPERIMENTOR) ejectItem() + var/badThingCoeffIfSuccess = (exp == FAIL) ? 0 : badThingCoeff + //Global reactions - if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && loaded_item) - var/globalMalf = rand(1,100) - if(globalMalf < 15) - visible_message("[src]'s onboard detection system has malfunctioned!") - 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("[src] melts [exp_on], ian-izing the air around it!") - throwSmoke(loc) - if(trackedIan) - throwSmoke(trackedIan.loc) - trackedIan.forceMove(loc) - investigate_log("Experimentor has stolen Ian!", INVESTIGATE_EXPERIMENTOR) //...if anyone ever fixes it... - else - new /mob/living/simple_animal/pet/dog/corgi(loc) - investigate_log("Experimentor has spawned a new corgi.", INVESTIGATE_EXPERIMENTOR) - ejectItem(TRUE) - if(globalMalf > 36 && globalMalf < 50) - visible_message("Experimentor draws the life essence of those nearby!") - for(var/mob/living/m in view(4,src)) - to_chat(m, "You feel your flesh being torn from you, mists of blood drifting to [src]!") - m.apply_damage(50, BRUTE, BODY_ZONE_CHEST) - investigate_log("Experimentor has taken 50 brute a blood sacrifice from [m]", INVESTIGATE_EXPERIMENTOR) - if(globalMalf > 51 && globalMalf < 75) - visible_message("[src] encounters a run-time error!") - throwSmoke(loc) - if(trackedRuntime) - throwSmoke(trackedRuntime.loc) - trackedRuntime.forceMove(drop_location()) - investigate_log("Experimentor has stolen Runtime!", INVESTIGATE_EXPERIMENTOR) - else - new /mob/living/simple_animal/pet/cat(loc) - investigate_log("Experimentor failed to steal runtime, and instead spawned a new cat.", INVESTIGATE_EXPERIMENTOR) - ejectItem(TRUE) - if(globalMalf > 76) - visible_message("[src] begins to smoke and hiss, shaking violently!") - use_power(500000) - investigate_log("Experimentor has drained power from its APC", INVESTIGATE_EXPERIMENTOR) + if(prob(EFFECT_PROB_VERYLOW-badThingCoeffIfSuccess) && prob(14) && loaded_item) + autoexperiment = 0 + visible_message("[src]'s onboard detection system has malfunctioned!") + item_reactions["[exp_on.type]"] = pick(SCANTYPE_POKE,SCANTYPE_IRRADIATE,SCANTYPE_GAS,SCANTYPE_HEAT,SCANTYPE_COLD,SCANTYPE_OBLITERATE) + ejectItem() + if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(19) && loaded_item) + autoexperiment = 0 + visible_message("[src] melts [exp_on], ian-izing the air around it!") + throwSmoke(loc) + if(trackedIan) + throwSmoke(trackedIan.loc) + trackedIan.forceMove(loc) + investigate_log("Experimentor has stolen Ian!", INVESTIGATE_EXPERIMENTOR) //...if anyone ever fixes it... + else + new /mob/living/simple_animal/pet/dog/corgi(loc) + investigate_log("Experimentor has spawned a new corgi.", INVESTIGATE_EXPERIMENTOR) + ejectItem(TRUE) + if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(14) && loaded_item) + autoexperiment = 0 + visible_message("Experimentor draws the life essence of those nearby!") + for(var/mob/living/m in view(4,src)) + to_chat(m, "You feel your flesh being torn from you, mists of blood drifting to [src]!") + m.apply_damage(50, BRUTE, BODY_ZONE_CHEST) + investigate_log("Experimentor has taken 50 brute a blood sacrifice from [m]", INVESTIGATE_EXPERIMENTOR) + if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(23) && loaded_item) + autoexperiment = 0 + visible_message("[src] encounters a run-time error!") + throwSmoke(loc) + if(trackedRuntime) + throwSmoke(trackedRuntime.loc) + trackedRuntime.forceMove(drop_location()) + investigate_log("Experimentor has stolen Runtime!", INVESTIGATE_EXPERIMENTOR) + else + new /mob/living/simple_animal/pet/cat(loc) + investigate_log("Experimentor failed to steal runtime, and instead spawned a new cat.", INVESTIGATE_EXPERIMENTOR) + ejectItem(TRUE) + if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(23) && loaded_item) + autoexperiment = 0 + visible_message("[src] begins to smoke and hiss, shaking violently!") + use_power(500000) + investigate_log("Experimentor has drained power from its APC", INVESTIGATE_EXPERIMENTOR) addtimer(CALLBACK(src, .proc/reset_exp), resetTime) -*/ // yogs end /obj/machinery/rnd/experimentor/proc/reset_exp() update_icon() recentlyExperimented = FALSE + if(autoexperiment) + do_experiment() /obj/machinery/rnd/experimentor/update_icon() icon_state = "h_lathe" diff --git a/yogstation.dme b/yogstation.dme index efd4a1737688..1ad227ca9f5f 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -3344,7 +3344,6 @@ #include "yogstation\code\modules\reagents\reagents\other_reagents.dm" #include "yogstation\code\modules\reagents\recipes\pyrotechnics.dm" #include "yogstation\code\modules\recycling\disposal\pipe_sorting.dm" -#include "yogstation\code\modules\research\experimentor.dm" #include "yogstation\code\modules\research\rdconsole.dm" #include "yogstation\code\modules\research\designs\biogenerator_designs.dm" #include "yogstation\code\modules\research\designs\bluespace_designs.dm" diff --git a/yogstation/code/modules/research/experimentor.dm b/yogstation/code/modules/research/experimentor.dm deleted file mode 100644 index 762853648127..000000000000 --- a/yogstation/code/modules/research/experimentor.dm +++ /dev/null @@ -1,311 +0,0 @@ -#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/rnd/experimentor/proc/experiment(exp,obj/item/exp_on) - recentlyExperimented = 1 - icon_state = "h_lathe_wloop" - var/chosenchem - var/criticalReaction = is_type_in_typecache(exp_on, critical_items_typecache) - var/badThingCoeffIfCrit = criticalReaction ? badThingCoeff : 0 // certain malfunctions are desirable for non-critical items - //////////////////////////////////////////////////////////////////////////////////////////////// - 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++ - else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) - visible_message("[src] malfunctions and destroys [exp_on], lashing its arms out at nearby people!") - for(var/mob/living/m in oview(1, src)) - m.apply_damage(15, BRUTE, pick(BODY_ZONE_HEAD,BODY_ZONE_CHEST,BODY_ZONE_PRECISE_GROIN)) - investigate_log("Experimentor dealt minor brute to [m].", INVESTIGATE_EXPERIMENTOR) - ejectItem(TRUE) - else if(prob(EFFECT_PROB_LOW-badThingCoeff)) - visible_message("[src] malfunctions!") - exp = SCANTYPE_OBLITERATE - else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) - visible_message("[src] malfunctions, throwing the [exp_on]!") - 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 [key_name(target)]", INVESTIGATE_EXPERIMENTOR) - ejectItem() - if(throwing) - throwing.throw_at(target, 10, 1) - //////////////////////////////////////////////////////////////////////////////////////////////// - if(exp == SCANTYPE_IRRADIATE) - visible_message("[src] reflects radioactive rays at [exp_on]!") - if(prob(EFFECT_PROB_LOW) && criticalReaction) - visible_message("[exp_on] has activated an unknown subroutine!") - cloneMode = TRUE - investigate_log("Experimentor has made a clone of [exp_on]", INVESTIGATE_EXPERIMENTOR) - ejectItem() - else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) - visible_message("[src] malfunctions, melting [exp_on] and leaking radiation!") - radiation_pulse(src, 500) - ejectItem(TRUE) - else if(prob(EFFECT_PROB_LOW-badThingCoeff)) - visible_message("[src] malfunctions, spewing toxic waste!") - for(var/turf/T in oview(1, src)) - if(!T.density) - if(prob(EFFECT_PROB_VERYHIGH) && !(locate(/obj/effect/decal/cleanable/greenglow) in T)) - var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/greenglow(T) - reagentdecal.reagents.add_reagent(/datum/reagent/uranium/radium, 7) - else if(prob(EFFECT_PROB_MEDIUM-badThingCoeffIfCrit)) - var/savedName = "[exp_on]" - ejectItem(TRUE) - var/newPath = text2path(pickweight(valid_items)) - loaded_item = new newPath(src) - visible_message("[src] malfunctions, transforming [savedName] into [loaded_item]!") - investigate_log("Experimentor has transformed [savedName] into [loaded_item]", INVESTIGATE_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("[src] fills its chamber with gas, [exp_on] included.") - 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)))) - else if(prob(EFFECT_PROB_VERYLOW-badThingCoeffIfCrit)) - visible_message("[src] destroys [exp_on], leaking dangerous gas!") - chosenchem = pick(/datum/reagent/carbon,/datum/reagent/uranium/radium,/datum/reagent/toxin,/datum/reagent/consumable/condensedcapsaicin,/datum/reagent/drug/mushroomhallucinogen,/datum/reagent/drug/space_drugs,/datum/reagent/consumable/ethanol,/datum/reagent/consumable/ethanol/beepsky_smash) - var/datum/reagents/R = new/datum/reagents(50) - R.my_atom = src - R.add_reagent(chosenchem , 50) - investigate_log("Experimentor has released [chosenchem] smoke.", INVESTIGATE_EXPERIMENTOR) - var/datum/effect_system/smoke_spread/chem/smoke = new - smoke.set_up(R, 0, src, silent = TRUE) - playsound(src, 'sound/effects/smoke.ogg', 50, 1, -3) - smoke.start() - qdel(R) - ejectItem(TRUE) - else if(prob(EFFECT_PROB_VERYLOW-badThingCoeffIfCrit)) - visible_message("[src]'s chemical chamber has sprung a leak!") - chosenchem = pick(/datum/reagent/mutationtoxin/felinid,/datum/reagent/nanomachines,/datum/reagent/toxin/acid) - var/datum/reagents/R = new/datum/reagents(50) - R.my_atom = src - R.add_reagent(chosenchem , 50) - var/datum/effect_system/smoke_spread/chem/smoke = new - smoke.set_up(R, 0, src, silent = TRUE) - playsound(src, 'sound/effects/smoke.ogg', 50, 1, -3) - smoke.start() - qdel(R) - ejectItem(TRUE) - warn_admins(usr, "[chosenchem] smoke") - investigate_log("Experimentor has released [chosenchem] smoke!", INVESTIGATE_EXPERIMENTOR) - else if(prob(EFFECT_PROB_LOW-badThingCoeff)) - visible_message("[src] malfunctions, spewing harmless gas.") - throwSmoke(loc) - else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) - visible_message("[src] melts [exp_on], ionizing the air around it!") - empulse(loc, 4, 6) - investigate_log("Experimentor has generated an Electromagnetic Pulse.", INVESTIGATE_EXPERIMENTOR) - ejectItem(TRUE) - //////////////////////////////////////////////////////////////////////////////////////////////// - if(exp == SCANTYPE_HEAT) - visible_message("[src] raises [exp_on]'s temperature.") - if(prob(EFFECT_PROB_LOW) && criticalReaction) - visible_message("[src]'s emergency coolant system gives off a small ding!") - playsound(src, 'sound/machines/ding.ogg', 50, 1) - var/obj/item/reagent_containers/food/drinks/coffee/C = new /obj/item/reagent_containers/food/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.", INVESTIGATE_EXPERIMENTOR) - else 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("[src] dangerously overheats, launching a flaming fuel orb!") - investigate_log("Experimentor has launched a fireball at [M]!", INVESTIGATE_EXPERIMENTOR) - var/obj/item/projectile/magic/aoe/fireball/FB = new /obj/item/projectile/magic/aoe/fireball(start) - FB.preparePixelProjectile(MT, start) - FB.fire() - else if(prob(EFFECT_PROB_LOW-badThingCoeff)) - visible_message("[src] malfunctions, melting [exp_on] and releasing a burst of flame!") - explosion(loc, -1, 0, 0, 0, 0, flame_range = 2) - investigate_log("Experimentor started a fire.", INVESTIGATE_EXPERIMENTOR) - ejectItem(TRUE) - else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) - visible_message("[src] malfunctions, melting [exp_on] and leaking hot air!") - var/datum/gas_mixture/env = loc.return_air() - 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.temperature = min((removed.temperature*heat_capacity + 100000)/heat_capacity, 1000) - env.merge(removed) - air_update_turf() - investigate_log("Experimentor has released hot air.", INVESTIGATE_EXPERIMENTOR) - ejectItem(TRUE) - else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) - visible_message("[src] malfunctions, activating its emergency coolant systems!") - throwSmoke(loc) - for(var/mob/living/m in oview(1, src)) - m.apply_damage(5, BURN, pick(BODY_ZONE_HEAD,BODY_ZONE_CHEST,BODY_ZONE_PRECISE_GROIN)) - investigate_log("Experimentor has dealt minor burn damage to [key_name(m)]", INVESTIGATE_EXPERIMENTOR) - ejectItem() - //////////////////////////////////////////////////////////////////////////////////////////////// - if(exp == SCANTYPE_COLD) - visible_message("[src] lowers [exp_on]'s temperature.") - if(prob(EFFECT_PROB_LOW) && criticalReaction) - visible_message("[src]'s emergency coolant system gives off a small ding!") - var/obj/item/reagent_containers/food/drinks/coffee/C = new /obj/item/reagent_containers/food/drinks/coffee(get_turf(pick(oview(1,src)))) - playsound(src, '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.", INVESTIGATE_EXPERIMENTOR) - else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) - visible_message("[src] malfunctions, shattering [exp_on] and releasing a dangerous cloud of coolant!") - var/datum/reagents/R = new/datum/reagents(50) - R.my_atom = src - R.add_reagent(/datum/reagent/consumable/frostoil, 50) - investigate_log("Experimentor has released frostoil gas.", INVESTIGATE_EXPERIMENTOR) - var/datum/effect_system/smoke_spread/chem/smoke = new - smoke.set_up(R, 0, src, silent = TRUE) - playsound(src, 'sound/effects/smoke.ogg', 50, 1, -3) - smoke.start() - qdel(R) - ejectItem(TRUE) - else if(prob(EFFECT_PROB_LOW-badThingCoeff)) - visible_message("[src] malfunctions, shattering [exp_on] and leaking cold air!") - var/datum/gas_mixture/env = loc.return_air() - 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.temperature = (removed.temperature*heat_capacity - 75000)/heat_capacity - env.merge(removed) - air_update_turf() - investigate_log("Experimentor has released cold air.", INVESTIGATE_EXPERIMENTOR) - ejectItem(TRUE) - else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) - visible_message("[src] malfunctions, releasing a flurry of chilly air as [exp_on] pops out!") - var/datum/effect_system/smoke_spread/smoke = new - smoke.set_up(0, loc) - smoke.start() - ejectItem() - //////////////////////////////////////////////////////////////////////////////////////////////// - if(exp == SCANTYPE_OBLITERATE) - visible_message("[exp_on] activates the crushing mechanism, [exp_on] is destroyed!") - 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_LOW) && criticalReaction) - visible_message("[src]'s crushing mechanism slowly and smoothly descends, flattening the [exp_on]!") - new /obj/item/stack/sheet/plasteel(get_turf(pick(oview(1,src)))) - else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff)) - visible_message("[src]'s crusher goes way too many levels too high, crushing right through space-time!") - playsound(src, 'sound/effects/supermatter.ogg', 50, 1, -3) - investigate_log("Experimentor has triggered the 'throw things' reaction.", INVESTIGATE_EXPERIMENTOR) - for(var/atom/movable/AM in oview(7,src)) - if(!AM.anchored) - AM.throw_at(src,10,1) - else if(prob(EFFECT_PROB_LOW-badThingCoeff)) - visible_message("[src]'s crusher goes one level too high, crushing right into space-time!") - playsound(src, 'sound/effects/supermatter.ogg', 50, 1, -3) - investigate_log("Experimentor has triggered the 'minor throw things' reaction.", INVESTIGATE_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 < throwAt.len, ++counter) - var/atom/movable/cast = throwAt[counter] - 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("[exp_on] [a], and [b], the experiment was a failure.") - - if(exp == SCANTYPE_DISCOVER) - visible_message("[src] scans the [exp_on], revealing its true nature!") - playsound(src, 'sound/effects/supermatter.ogg', 50, 3, -1) - var/obj/item/relic/R = loaded_item - R.reveal() - investigate_log("Experimentor has revealed a relic with [R.realProc] effect.", INVESTIGATE_EXPERIMENTOR) - ejectItem() - - var/badThingCoeffIfSuccess = (exp == FAIL) ? 0 : badThingCoeff - - //Global reactions - if(prob(EFFECT_PROB_VERYLOW-badThingCoeffIfSuccess) && prob(14) && loaded_item) - visible_message("[src]'s onboard detection system has malfunctioned!") - item_reactions["[exp_on.type]"] = pick(SCANTYPE_POKE,SCANTYPE_IRRADIATE,SCANTYPE_GAS,SCANTYPE_HEAT,SCANTYPE_COLD,SCANTYPE_OBLITERATE) - ejectItem() - if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(19) && loaded_item) - visible_message("[src] melts [exp_on], ian-izing the air around it!") - throwSmoke(loc) - if(trackedIan) - throwSmoke(trackedIan.loc) - trackedIan.forceMove(loc) - investigate_log("Experimentor has stolen Ian!", INVESTIGATE_EXPERIMENTOR) //...if anyone ever fixes it... - else - new /mob/living/simple_animal/pet/dog/corgi(loc) - investigate_log("Experimentor has spawned a new corgi.", INVESTIGATE_EXPERIMENTOR) - ejectItem(TRUE) - if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(14) && loaded_item) - visible_message("Experimentor draws the life essence of those nearby!") - for(var/mob/living/m in view(4,src)) - to_chat(m, "You feel your flesh being torn from you, mists of blood drifting to [src]!") - m.apply_damage(50, BRUTE, BODY_ZONE_CHEST) - investigate_log("Experimentor has taken 50 brute a blood sacrifice from [m]", INVESTIGATE_EXPERIMENTOR) - if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(23) && loaded_item) - visible_message("[src] encounters a run-time error!") - throwSmoke(loc) - if(trackedRuntime) - throwSmoke(trackedRuntime.loc) - trackedRuntime.forceMove(drop_location()) - investigate_log("Experimentor has stolen Runtime!", INVESTIGATE_EXPERIMENTOR) - else - new /mob/living/simple_animal/pet/cat(loc) - investigate_log("Experimentor failed to steal runtime, and instead spawned a new cat.", INVESTIGATE_EXPERIMENTOR) - ejectItem(TRUE) - if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(23) && loaded_item) - visible_message("[src] begins to smoke and hiss, shaking violently!") - use_power(500000) - investigate_log("Experimentor has drained power from its APC", INVESTIGATE_EXPERIMENTOR) - - addtimer(CALLBACK(src, .proc/reset_exp), resetTime) - -#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