mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 19:22:56 +00:00
Merge pull request #3839 from caelaislinn/xenoarchaeology
Xenoarchaeology updates
This commit is contained in:
@@ -145,14 +145,14 @@ datum/fusion_reaction/pergium_tritium
|
||||
energy_production = 0
|
||||
radiation = 5
|
||||
|
||||
datum/fusion_reaction/pergium_deuterium
|
||||
datum/fusion_reaction/pergium_obdurium
|
||||
primary_reactant = "Pergium"
|
||||
secondary_reactant = "Obdurium"
|
||||
energy_consumption = 5
|
||||
energy_production = 0
|
||||
radiation = 5
|
||||
|
||||
datum/fusion_reaction/pergium_tritium
|
||||
datum/fusion_reaction/pergium_solonium
|
||||
primary_reactant = "Pergium"
|
||||
secondary_reactant = "Solonium"
|
||||
energy_consumption = 5
|
||||
|
||||
@@ -456,6 +456,14 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
containername = "fuel tank crate"
|
||||
group = "Engineering"
|
||||
|
||||
/datum/supply_packs/coolanttank
|
||||
name = "Coolant tank crate"
|
||||
contains = list(/obj/structure/reagent_dispensers/coolanttank)
|
||||
cost = 16
|
||||
containertype = /obj/structure/largecrate
|
||||
containername = "coolant tank crate"
|
||||
group = "Medical / Science"
|
||||
|
||||
/datum/supply_packs/solar
|
||||
name = "Solar Pack crate"
|
||||
contains = list(/obj/item/solar_assembly,
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
carddesc += "<input type='hidden' name='src' value='\ref[src]'>"
|
||||
carddesc += "<input type='hidden' name='choice' value='account'>"
|
||||
carddesc += "<b>Stored account number:</b> <input type='text' id='accountfield' name='account' value='[modify.associated_account_number]' style='width:250px; background-color:white;' onchange='markAccountRed()'>"
|
||||
carddesc += "<input type='submit' value='Rename' onclick='markAccountGreen()'>"
|
||||
carddesc += "<input type='submit' value='Modify' onclick='markAccountGreen()'>"
|
||||
carddesc += "</form>"
|
||||
|
||||
carddesc += "<b>Assignment:</b> "
|
||||
|
||||
@@ -99,6 +99,16 @@ obj/structure/ex_act(severity)
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/Bumped(mob/AM as mob|obj)
|
||||
var/obj/structure/transit_tube/T = locate() in AM.loc
|
||||
if(T)
|
||||
AM << "<span class='warning'>The tube's support pylons block your way.</span>"
|
||||
return ..()
|
||||
else
|
||||
AM.loc = src.loc
|
||||
AM << "<span class='info'>You slip under the tube.</span>"
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/New(loc)
|
||||
..(loc)
|
||||
|
||||
|
||||
@@ -251,6 +251,7 @@
|
||||
'nano/css/icons.css',
|
||||
'nano/templates/chem_dispenser.tmpl',
|
||||
'nano/templates/cryo.tmpl',
|
||||
'nano/templates/geoscanner.tmpl',
|
||||
'nano/templates/dna_modifier.tmpl',
|
||||
'nano/images/uiBackground.png',
|
||||
'nano/images/uiIcons16.png',
|
||||
@@ -298,9 +299,5 @@
|
||||
'icons/spideros_icons/sos_11.png',
|
||||
'icons/spideros_icons/sos_12.png',
|
||||
'icons/spideros_icons/sos_13.png',
|
||||
'icons/spideros_icons/sos_14.png',
|
||||
'icons/xenoarch_icons/chart1.jpg',
|
||||
'icons/xenoarch_icons/chart2.jpg',
|
||||
'icons/xenoarch_icons/chart3.jpg',
|
||||
'icons/xenoarch_icons/chart4.jpg'
|
||||
'icons/spideros_icons/sos_14.png'
|
||||
)
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#define XENOARCH_SPREAD_CHANCE 15
|
||||
#define ARTIFACT_SPAWN_CHANCE 20
|
||||
|
||||
var/list/artifact_spawning_turfs = list()
|
||||
|
||||
/turf/simulated/mineral //wall piece
|
||||
name = "Rock"
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
@@ -369,29 +371,25 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
//just pull the surrounding rock out
|
||||
excavate_find(0, F)
|
||||
|
||||
if( src.excavation_level + P.excavation_amount >= 100 || (!finds.len && !excavation_minerals.len) )
|
||||
//if players have been excavating this turf, have a chance to leave some rocky debris behind
|
||||
var/boulder_prob = 0
|
||||
if( src.excavation_level + P.excavation_amount >= 100 )
|
||||
//if players have been excavating this turf, leave some rocky debris behind
|
||||
var/obj/structure/boulder/B
|
||||
|
||||
if(src.excavation_level > 15)
|
||||
boulder_prob = 10
|
||||
if(artifact_find)
|
||||
boulder_prob += 25
|
||||
if(src.excavation_level >= 100)
|
||||
boulder_prob += 40
|
||||
else if(src.excavation_level > 95)
|
||||
boulder_prob += 25
|
||||
else if(src.excavation_level > 90)
|
||||
boulder_prob += 10
|
||||
if(prob(boulder_prob))
|
||||
if( src.excavation_level > 0 || prob(15) )
|
||||
//boulder with an artifact inside
|
||||
B = new(src)
|
||||
if(artifact_find)
|
||||
B.artifact_find = artifact_find
|
||||
else
|
||||
artifact_debris(1)
|
||||
else if(prob(15))
|
||||
//empty boulder
|
||||
B = new(src)
|
||||
if(artifact_find)
|
||||
B.artifact_find = artifact_find
|
||||
else if(artifact_find && src.excavation_level + P.excavation_amount >= 100)
|
||||
artifact_debris(1)
|
||||
|
||||
gets_drilled(B ? 0 : 1)
|
||||
if(B)
|
||||
gets_drilled(0)
|
||||
else
|
||||
gets_drilled(1)
|
||||
return
|
||||
else
|
||||
src.excavation_level += P.excavation_amount
|
||||
@@ -475,7 +473,7 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
if(prob(50))
|
||||
pain = 1
|
||||
for(var/mob/living/M in range(src, 200))
|
||||
M << "<font color='red'><b>[pick("A high pitched [pick("keening","wailing","whistle")]","A rumbling noise like [pick("thunder","heavy machinery")]")] somehow penetrates your mind before fadaing away!</b></font>"
|
||||
M << "<font color='red'><b>[pick("A high pitched [pick("keening","wailing","whistle")]","A rumbling noise like [pick("thunder","heavy machinery")]")] somehow penetrates your mind before fading away!</b></font>"
|
||||
if(pain)
|
||||
flick("pain",M.pain)
|
||||
if(prob(50))
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
var/list/dispensable_reagents = list("hydrogen","lithium","carbon","nitrogen","oxygen","fluorine",
|
||||
"sodium","aluminum","silicon","phosphorus","sulfur","chlorine","potassium","iron",
|
||||
"copper","mercury","radium","water","ethanol","sugar","sacid","tungsten")
|
||||
var/list/broken_requirements = list()
|
||||
var/broken_on_spawn = 0
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/recharge()
|
||||
if(stat & (BROKEN|NOPOWER)) return
|
||||
@@ -50,6 +52,28 @@
|
||||
recharge()
|
||||
dispensable_reagents = sortList(dispensable_reagents)
|
||||
|
||||
if(broken_on_spawn)
|
||||
var/amount = pick(1,2,2,3,4)
|
||||
var/list/options = list()
|
||||
options[/obj/item/weapon/stock_parts/capacitor/adv] = "Add an advanced capacitor to fix it."
|
||||
options[/obj/item/weapon/stock_parts/console_screen] = "Replace the console screen to fix it."
|
||||
options[/obj/item/weapon/stock_parts/manipulator/pico] = "Upgrade to a pico manipulator to fix it."
|
||||
options[/obj/item/weapon/stock_parts/matter_bin/adv] = "Give it an advanced matter bin to fix it."
|
||||
options[/obj/item/stack/sheet/mineral/diamond] = "Line up a cut diamond with the nozzle to fix it."
|
||||
options[/obj/item/stack/sheet/mineral/uranium] = "Position a uranium sheet inside to fix it."
|
||||
options[/obj/item/stack/sheet/mineral/plasma] = "Enter a block of plasma to fix it."
|
||||
options[/obj/item/stack/sheet/mineral/silver] = "Cover the internals with a silver lining to fix it."
|
||||
options[/obj/item/stack/sheet/mineral/gold] = "Wire a golden filament to fix it."
|
||||
options[/obj/item/stack/sheet/plasteel] = "Surround the outside with a plasteel cover to fix it."
|
||||
options[/obj/item/stack/sheet/rglass] = "Insert a pane of reinforced glass to fix it."
|
||||
|
||||
while(amount > 0)
|
||||
amount -= 1
|
||||
|
||||
var/index = pick(options)
|
||||
broken_requirements[index] = options[index]
|
||||
options -= index
|
||||
|
||||
/obj/machinery/chem_dispenser/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
@@ -82,6 +106,10 @@
|
||||
if(stat & (BROKEN|NOPOWER)) return
|
||||
if(user.stat || user.restrained()) return
|
||||
|
||||
if(broken_requirements.len)
|
||||
user << "<span class='warning'>[src] is broken. [broken_requirements[broken_requirements[1]]]</span>"
|
||||
return
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
var/data[0]
|
||||
data["amount"] = amount
|
||||
@@ -156,6 +184,19 @@
|
||||
if(isrobot(user))
|
||||
return
|
||||
|
||||
if(broken_requirements.len && B.type == broken_requirements[1])
|
||||
broken_requirements -= broken_requirements[1]
|
||||
user << "<span class='notice'>You fix [src].</span>"
|
||||
if(istype(B,/obj/item/stack))
|
||||
var/obj/item/stack/S = B
|
||||
S.use(1)
|
||||
else
|
||||
user.drop_item()
|
||||
del(B)
|
||||
return
|
||||
|
||||
if(!istype(B, /obj/item/weapon/reagent_containers/glass))
|
||||
return
|
||||
if(src.beaker)
|
||||
user << "Something is already loaded into the machine."
|
||||
return
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
else if(istype(target, /obj/machinery/bunsen_burner))
|
||||
return
|
||||
|
||||
else if(istype(target, /obj/machinery/anomaly))
|
||||
else if(istype(target, /obj/machinery/radiocarbon_spectrometer))
|
||||
return
|
||||
|
||||
else if(reagents.total_volume)
|
||||
@@ -223,6 +223,7 @@
|
||||
possible_transfer_amounts = list(5,10,15,25,30,50,100,300)
|
||||
flags = FPRINT | TABLEPASS | OPENCONTAINER
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial
|
||||
name = "vial"
|
||||
desc = "A small glass vial. Can hold up to 25 units."
|
||||
|
||||
@@ -211,6 +211,10 @@
|
||||
|
||||
// attack with hand, switch position
|
||||
/obj/machinery/conveyor_switch/attack_hand(mob/user)
|
||||
if(!allowed(user))
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return
|
||||
|
||||
if(position == 0)
|
||||
if(last_pos < 0)
|
||||
position = 1
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
icon_state = "boulder1"
|
||||
density = 1
|
||||
opacity = 1
|
||||
anchored = 1
|
||||
var/excavation_level = 0
|
||||
var/datum/geosample/geological_data
|
||||
var/datum/artifact_find/artifact_find
|
||||
@@ -75,17 +76,14 @@
|
||||
user << "\blue You finish [P.drill_verb] [src]."
|
||||
excavation_level += P.excavation_amount
|
||||
|
||||
var/reveal_prob = 1
|
||||
if(excavation_level >= 95)
|
||||
reveal_prob = 50 + (excavation_level - 90) * (excavation_level - 90)
|
||||
else if(excavation_level >= 90)
|
||||
reveal_prob = 5
|
||||
if(excavation_level >= 100)
|
||||
if(excavation_level > 100)
|
||||
//failure
|
||||
user.visible_message("<font color='red'><b>[src] suddenly crumbles away.</b></font>",\
|
||||
"\red [src] has disintegrated under your onslaught, any secrets it was holding long gone.")
|
||||
"\red [src] has disintegrated under your onslaught, any secrets it was holding are long gone.")
|
||||
del(src)
|
||||
else if(prob(reveal_prob))
|
||||
return
|
||||
|
||||
if(prob(excavation_level))
|
||||
//success
|
||||
if(artifact_find)
|
||||
var/spawn_type = artifact_find.artifact_find_type
|
||||
|
||||
@@ -1,242 +0,0 @@
|
||||
//Part of ISaidNo's public release around July 2011(ish), multiple changes
|
||||
//many thanks
|
||||
|
||||
#define PLASMA_SPAWN 1
|
||||
#define N2_SPAWN 2
|
||||
#define CO2_SPAWN 3
|
||||
#define RADIATE 4
|
||||
#define VIRUS 5
|
||||
#define HEAT 6
|
||||
#define COLD 7
|
||||
|
||||
/obj/machinery/artifact
|
||||
name = "alien artifact"
|
||||
desc = "A large alien device."
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "ano00"
|
||||
var/icon_num = 0
|
||||
anchored = 0
|
||||
density = 1
|
||||
var/origin = null // Used in the randomisation/research of the artifact.
|
||||
var/activated = 0 // Whether or not the artifact has been unlocked.
|
||||
var/charged = 1 // Whether the artifact is ready to have it's effect.
|
||||
var/chargetime = 0 // How much time until the artifact is charged.
|
||||
var/recharge = 5 // How long does it take this artifact to recharge?
|
||||
var/display_id = "" // Artifact ID to display once successfully scanned
|
||||
var/datum/artifact_effect/my_effect = null
|
||||
var/being_used = 0
|
||||
|
||||
/obj/machinery/artifact/New()
|
||||
..()
|
||||
// Origin and appearance randomisation
|
||||
|
||||
my_effect = new()
|
||||
|
||||
|
||||
icon_num = rand(0,5)
|
||||
icon_state = "ano[icon_num]0"
|
||||
|
||||
// Power randomisation
|
||||
my_effect.trigger = pick("force","energy","chemical","heat","touch","presence")
|
||||
if (my_effect.trigger == "chemical")
|
||||
my_effect.triggerX = pick("hydrogen","corrosive","volatile","toxic")
|
||||
|
||||
my_effect.effecttype = pick("healing","injure","stun","roboheal","robohurt","cellcharge","celldrain","planthelper","forcefield","teleport","dnaswitch","emp","sleepy")
|
||||
|
||||
// Select range based on the power
|
||||
var/canworldpulse = 1
|
||||
switch(my_effect.effecttype)
|
||||
if("healing")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("injure")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("stun")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("roboheal")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("robohurt")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("sleepy")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("cellcharge")
|
||||
my_effect.effectmode = pick("aura","pulse")
|
||||
if("celldrain")
|
||||
my_effect.effectmode = pick("aura","pulse")
|
||||
if("planthelper")
|
||||
my_effect.effectmode = pick("aura","pulse")
|
||||
canworldpulse = 0
|
||||
if("forcefield")
|
||||
my_effect.effectmode = "contact"
|
||||
canworldpulse = 0
|
||||
if("teleport")
|
||||
my_effect.effectmode = pick("pulse","contact")
|
||||
if("genderswitch")
|
||||
my_effect.effectmode = pick("pulse","contact")
|
||||
if("emp")
|
||||
my_effect.effectmode = pick("pulse","contact")
|
||||
|
||||
// Recharge timer & range setup
|
||||
if (my_effect.effectmode == "aura")
|
||||
my_effect.aurarange = rand(1,4)
|
||||
if (my_effect.effectmode == "contact")
|
||||
src.recharge = rand(5,15)
|
||||
if (my_effect.effectmode == "pulse")
|
||||
my_effect.aurarange = rand(2,14)
|
||||
src.recharge = rand(5,20)
|
||||
if (canworldpulse == 1 && prob(1))
|
||||
my_effect.effectmode = "worldpulse"
|
||||
src.recharge = rand(40,120)
|
||||
|
||||
/*
|
||||
display_id += pick("kappa","sigma","antaeres","beta","lorard","omicron","iota","upsilon","omega","gamma","delta")
|
||||
display_id += "-"
|
||||
display_id += num2text(rand(100,999))
|
||||
*/
|
||||
|
||||
/obj/machinery/artifact/Del()
|
||||
..()
|
||||
my_effect.HaltEffect()
|
||||
|
||||
/obj/machinery/artifact/attack_hand(var/mob/user as mob)
|
||||
if (istype(user, /mob/living/silicon/ai) || istype(user, /mob/dead/)) return
|
||||
if (istype(user, /mob/living/silicon/robot))
|
||||
if (get_dist(user, src) > 1)
|
||||
user << "\red You can't reach [src] from here."
|
||||
return
|
||||
if(ishuman(user) && istype(user:gloves,/obj/item/clothing/gloves))
|
||||
return ..()
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message(text("<b>[]</b> touches [].", user, src), 1)
|
||||
src.add_fingerprint(user)
|
||||
src.Artifact_Contact(user)
|
||||
|
||||
/obj/machinery/artifact/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
/*if (istype(W, /obj/item/weapon/cargotele))
|
||||
W:cargoteleport(src, user)
|
||||
return*/
|
||||
if (my_effect.trigger == "chemical" && istype(W, /obj/item/weapon/reagent_containers/))
|
||||
switch(my_effect.triggerX)
|
||||
if("hydrogen")
|
||||
if (W.reagents.has_reagent("hydrogen", 1) || W.reagents.has_reagent("water", 1))
|
||||
src.Artifact_Activate()
|
||||
return
|
||||
if("corrosive")
|
||||
if (W.reagents.has_reagent("acid", 1) || W.reagents.has_reagent("pacid", 1) || W.reagents.has_reagent("diethylamine", 1))
|
||||
src.Artifact_Activate()
|
||||
return
|
||||
if("volatile")
|
||||
if (W.reagents.has_reagent("plasma", 1) || W.reagents.has_reagent("thermite", 1))
|
||||
src.Artifact_Activate()
|
||||
return
|
||||
if("toxic")
|
||||
if (W.reagents.has_reagent("toxin", 1) || W.reagents.has_reagent("cyanide", 1) || W.reagents.has_reagent("amanitin", 1) || W.reagents.has_reagent("neurotoxin", 1))
|
||||
src.Artifact_Activate()
|
||||
return
|
||||
..()
|
||||
if (my_effect.trigger == "force" && W.force >= 10 && !src.activated) src.Artifact_Activate()
|
||||
if (my_effect.trigger == "energy")
|
||||
if (istype(W,/obj/item/weapon/melee/baton) && W:status) src.Artifact_Activate()
|
||||
if (istype(W,/obj/item/weapon/melee/energy)) src.Artifact_Activate()
|
||||
if (istype(W,/obj/item/weapon/melee/cultblade)) src.Artifact_Activate()
|
||||
if (istype(W,/obj/item/weapon/gun/energy/)) src.Artifact_Activate()
|
||||
if (istype(W,/obj/item/device/multitool)) src.Artifact_Activate()
|
||||
if (istype(W,/obj/item/weapon/card/emag)) src.Artifact_Activate()
|
||||
if (my_effect.trigger == "heat")
|
||||
if (istype(W,/obj/item/weapon/match) && W:lit) src.Artifact_Activate()
|
||||
if (istype(W, /obj/item/weapon/weldingtool) && W:welding) src.Artifact_Activate()
|
||||
if (istype(W, /obj/item/weapon/lighter) && W:lit) src.Artifact_Activate()
|
||||
|
||||
//Bump(atom/A)
|
||||
|
||||
/obj/machinery/artifact/Bumped(M as mob|obj)
|
||||
if (istype(M,/obj/item/weapon/) && my_effect.trigger == "force" && M:throwforce >= 10) src.Artifact_Activate()
|
||||
|
||||
/obj/machinery/artifact/bullet_act(var/obj/item/projectile/P)
|
||||
if (my_effect.trigger == "force")
|
||||
if(istype(P,/obj/item/projectile/bullet)) src.Artifact_Activate()
|
||||
else if(istype(P,/obj/item/projectile/hivebotbullet)) src.Artifact_Activate()
|
||||
if (my_effect.trigger == "energy")
|
||||
if(istype(P,/obj/item/projectile/beam)) src.Artifact_Activate()
|
||||
else if(istype(P,/obj/item/projectile/ion)) src.Artifact_Activate()
|
||||
else if(istype(P,/obj/item/projectile/energy)) src.Artifact_Activate()
|
||||
if (my_effect.trigger == "heat")
|
||||
if(istype(P,/obj/item/projectile/temp)) src.Artifact_Activate()
|
||||
|
||||
/obj/machinery/artifact/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0) del src
|
||||
if(2.0)
|
||||
if (prob(50)) del src
|
||||
if (my_effect.trigger == "force") src.Artifact_Activate()
|
||||
if (my_effect.trigger == "heat") src.Artifact_Activate()
|
||||
if(3.0)
|
||||
if (my_effect.trigger == "force") src.Artifact_Activate()
|
||||
if (my_effect.trigger == "heat") src.Artifact_Activate()
|
||||
return
|
||||
|
||||
/obj/machinery/artifact/temperature_expose(null, temp, volume)
|
||||
if (my_effect.trigger == "heat") src.Artifact_Activate()
|
||||
|
||||
/obj/machinery/artifact/process()
|
||||
if (!src.activated)
|
||||
return
|
||||
if (chargetime > 0)
|
||||
chargetime -= 1
|
||||
else
|
||||
src.charged = 1
|
||||
|
||||
my_effect.UpdateEffect(src.loc)
|
||||
|
||||
//activate
|
||||
if( (my_effect.effectmode == "pulse" || my_effect.effecttype == "worldpulse") && activated)
|
||||
if(src.charged && my_effect.DoEffect(src))
|
||||
src.charged = 0
|
||||
src.chargetime = src.recharge
|
||||
|
||||
/obj/machinery/artifact/proc/Artifact_Activate()
|
||||
src.activated = !src.activated
|
||||
var/display_msg = ""
|
||||
if(activated)
|
||||
if(prob(30))
|
||||
switch(rand(4))
|
||||
if(0)
|
||||
display_msg = "momentarily glows brightly!"
|
||||
if(1)
|
||||
display_msg = "distorts slightly for a moment!"
|
||||
if(2)
|
||||
display_msg = "makes a slightly clicking noise!"
|
||||
if(3)
|
||||
display_msg = "flickers slightly!"
|
||||
if(4)
|
||||
display_msg = "vibrates!"
|
||||
else
|
||||
my_effect.HaltEffect()
|
||||
if(prob(30))
|
||||
switch(rand(2))
|
||||
if(0)
|
||||
display_msg = "grows dull!"
|
||||
if(1)
|
||||
display_msg = "fades in intensity!"
|
||||
if(2)
|
||||
display_msg = "suddenly becomes very quiet!"
|
||||
|
||||
icon_state = "ano[icon_num][activated]"
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message(text("<b>[]</b> [display_msg]", src), 1)
|
||||
|
||||
/obj/machinery/artifact/proc/Artifact_Contact(var/mob/user as mob)
|
||||
// Trigger Code
|
||||
if (istype (user,/mob/living/carbon/) && my_effect.trigger == "touch" && !src.activated) src.Artifact_Activate()
|
||||
else if (my_effect.trigger != "touch" && !src.activated) user << "Nothing happens."
|
||||
|
||||
if (my_effect.effectmode == "contact" && src.activated && src.charged)
|
||||
my_effect.DoEffect(user)
|
||||
src.charged = 0
|
||||
src.chargetime = src.recharge
|
||||
|
||||
// this was used in QM for a time but it fell into disuse and wasn't removed, the purpose being to check if an artifact
|
||||
// was benevolent or malicious, to determine whether QMs would be paid or punished for shipping it
|
||||
|
||||
/obj/machinery/artifact/Move()
|
||||
..()
|
||||
my_effect.update_move(src, src.loc)
|
||||
@@ -1,542 +0,0 @@
|
||||
//
|
||||
|
||||
/datum/artifact_effect
|
||||
var/artifact_id = "" // Display ID of the spawning artifact
|
||||
var/trigger = "touch" // What activates it?
|
||||
var/triggerX = "none" // Used for more varied triggers
|
||||
var/effecttype = "healing" // What does it do?
|
||||
var/effectmode = "aura" // How does it carry out the effect?
|
||||
var/aurarange = 4 // How far the artifact will extend an aura effect.
|
||||
var/list/created_field
|
||||
var/archived_loc
|
||||
|
||||
/datum/artifact_effect/New()
|
||||
//
|
||||
created_field = new()
|
||||
|
||||
/datum/artifact_effect/proc/GetOriginString(var/origin)
|
||||
|
||||
/datum/artifact_effect/proc/GetEffectString(var/effect)
|
||||
|
||||
/datum/artifact_effect/proc/GetTriggerString(var/trigger)
|
||||
|
||||
/datum/artifact_effect/proc/GetRangeString(var/range)
|
||||
switch(effectmode)
|
||||
if("aura") return "Constant Short-Range Energy Field"
|
||||
if("pulse")
|
||||
if(aurarange > 7) return "Long Range Energy Pulses"
|
||||
else return "Medium Range Energy Pulses"
|
||||
if("worldpulse") return "Extreme Range Energy Pulses"
|
||||
if("contact") return "Requires contact with subject"
|
||||
else return "Unknown Range"
|
||||
|
||||
/datum/artifact_effect/proc/HaltEffect()
|
||||
for(var/obj/effect/energy_field/F in created_field)
|
||||
created_field.Remove(F)
|
||||
del F
|
||||
|
||||
/datum/artifact_effect/proc/UpdateEffect(var/atom/originator)
|
||||
/*for(var/obj/effect/energy_field/F in created_field)
|
||||
created_field.Remove(F)
|
||||
del F*/
|
||||
if(originator.loc != archived_loc)
|
||||
archived_loc = originator.loc
|
||||
update_move(originator)
|
||||
|
||||
for(var/obj/effect/energy_field/E in created_field)
|
||||
if(E.strength < 5)
|
||||
E.Strengthen(0.2)
|
||||
|
||||
/datum/artifact_effect/proc/DoEffect(var/atom/originator)
|
||||
archived_loc = originator.loc
|
||||
if (src.effectmode == "contact")
|
||||
var/mob/living/user = originator
|
||||
if(!user)
|
||||
return
|
||||
switch(src.effecttype)
|
||||
if("healing")
|
||||
//caeltodo
|
||||
if (istype(user, /mob/living/carbon/human/))
|
||||
user << "\blue You feel a soothing energy invigorate you."
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
for(var/datum/organ/external/affecting in H.organs)
|
||||
if(!affecting) continue
|
||||
if(!istype(affecting, /datum/organ/external)) continue
|
||||
affecting.heal_damage(25, 25) //fixes getting hit after ingestion, killing you when game updates organ health
|
||||
//user:heal_organ_damage(25, 25)
|
||||
//
|
||||
user.adjustOxyLoss(-25)
|
||||
user.adjustToxLoss(-25)
|
||||
user.adjustBruteLoss(-25)
|
||||
user.adjustFireLoss(-25)
|
||||
user.adjustBrainLoss(-25)
|
||||
user.radiation -= min(user.radiation, 25)
|
||||
user.nutrition += 50
|
||||
H.bodytemperature = initial(H.bodytemperature)
|
||||
//
|
||||
H.vessel.add_reagent("blood",50)
|
||||
spawn(1)
|
||||
H.fixblood()
|
||||
H.regenerate_icons()
|
||||
return 1
|
||||
//
|
||||
if (istype(user, /mob/living/carbon/monkey/))
|
||||
user << "\blue You feel a soothing energy invigorate you."
|
||||
user.adjustOxyLoss(-25)
|
||||
user.adjustToxLoss(-25)
|
||||
user.adjustBruteLoss(-25)
|
||||
user.adjustFireLoss(-25)
|
||||
user.adjustBrainLoss(-25)
|
||||
return 1
|
||||
else user << "Nothing happens."
|
||||
if("injure")
|
||||
if (istype(user, /mob/living/carbon/))
|
||||
user << "\red A painful discharge of energy strikes you!"
|
||||
user.adjustOxyLoss(rand(5,25))
|
||||
user.adjustToxLoss(rand(5,25))
|
||||
user.adjustBruteLoss(rand(5,25))
|
||||
user.adjustFireLoss(rand(5,25))
|
||||
user.adjustBrainLoss(rand(5,25))
|
||||
user.radiation += 25
|
||||
user.nutrition -= min(50, user.nutrition)
|
||||
user.make_dizzy(6)
|
||||
user.weakened += 6
|
||||
return 1
|
||||
else user << "Nothing happens."
|
||||
if("stun")
|
||||
if (istype(user, /mob/living/carbon/))
|
||||
user << "\red A powerful force overwhelms your consciousness."
|
||||
user.weakened += 45
|
||||
user.stuttering += 45
|
||||
if(prob(50))
|
||||
user.stunned += rand(1,10)
|
||||
return 1
|
||||
else user << "Nothing happens."
|
||||
if("roboheal")
|
||||
if (istype(user, /mob/living/silicon/robot))
|
||||
user << "\blue Your systems report damaged components mending by themselves!"
|
||||
user.adjustBruteLoss(rand(-10,-30))
|
||||
user.adjustFireLoss(rand(-10,-30))
|
||||
return 1
|
||||
else user << "Nothing happens."
|
||||
if("robohurt")
|
||||
if (istype(user, /mob/living/silicon/robot))
|
||||
user << "\red Your systems report severe damage has been inflicted!"
|
||||
user.adjustBruteLoss(rand(10,50))
|
||||
user.adjustFireLoss(rand(10,50))
|
||||
return 1
|
||||
else user << "Nothing happens."
|
||||
if("forcefield")
|
||||
while(created_field.len < 16)
|
||||
var/obj/effect/energy_field/E = new (locate(user.x,user.y,user.z))
|
||||
created_field.Add(E)
|
||||
E.strength = 1
|
||||
E.density = 1
|
||||
E.anchored = 1
|
||||
E.invisibility = 0
|
||||
return 1
|
||||
if("teleport")
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/T in orange(user, 50))
|
||||
if(!istype(T, /turf/simulated/floor) || T.density)
|
||||
continue
|
||||
randomturfs.Add(T)
|
||||
if(randomturfs.len > 0)
|
||||
user << "\red You are suddenly zapped away elsewhere!"
|
||||
if (user.buckled)
|
||||
user.buckled.unbuckle()
|
||||
user.loc = pick(randomturfs)
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(originator)) //no idea what the 0 is
|
||||
sparks.start()
|
||||
return 1
|
||||
if("sleepy")
|
||||
user << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
|
||||
user.drowsyness = min(user.drowsyness + rand(5,25), 50)
|
||||
user.eye_blurry = min(user.eye_blurry + rand(1,3), 50)
|
||||
return 1
|
||||
else if (src.effectmode == "aura")
|
||||
switch(src.effecttype)
|
||||
//caeltodo
|
||||
if("healing")
|
||||
for (var/mob/living/carbon/M in range(src.aurarange,originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
if(prob(10)) M << "\blue You feel a soothing energy radiating from something nearby."
|
||||
M.adjustBruteLoss(-1)
|
||||
M.adjustFireLoss(-1)
|
||||
M.adjustToxLoss(-1)
|
||||
M.adjustOxyLoss(-1)
|
||||
M.adjustBrainLoss(-1)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("injure")
|
||||
for (var/mob/living/carbon/M in range(src.aurarange,originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
if(prob(10)) M << "\red You feel a painful force radiating from something nearby."
|
||||
M.adjustBruteLoss(1)
|
||||
M.adjustFireLoss(1)
|
||||
M.adjustToxLoss(1)
|
||||
M.adjustOxyLoss(1)
|
||||
M.adjustBrainLoss(1)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("stun")
|
||||
for (var/mob/living/carbon/M in range(src.aurarange,originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
if(prob(10)) M << "\red Energy radiating from the [originator] is making you feel numb."
|
||||
if(prob(20))
|
||||
M << "\red Your body goes numb for a moment."
|
||||
M.stunned += 2
|
||||
M.weakened += 2
|
||||
M.stuttering += 2
|
||||
return 1
|
||||
if("roboheal")
|
||||
for (var/mob/living/silicon/robot/M in range(src.aurarange,originator))
|
||||
if(prob(10)) M << "\blue SYSTEM ALERT: Beneficial energy field detected!"
|
||||
M.adjustBruteLoss(-1)
|
||||
M.adjustFireLoss(-1)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("robohurt")
|
||||
for (var/mob/living/silicon/robot/M in range(src.aurarange,originator))
|
||||
if(prob(10)) M << "\red SYSTEM ALERT: Harmful energy field detected!"
|
||||
M.adjustBruteLoss(1)
|
||||
M.adjustFireLoss(1)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("cellcharge")
|
||||
for (var/obj/machinery/power/apc/C in range(src.aurarange,originator))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge += 10
|
||||
for (var/obj/machinery/power/smes/S in range (src.aurarange,originator)) S.charge += 20
|
||||
for (var/mob/living/silicon/robot/M in range(src.aurarange,originator))
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge += 10
|
||||
if(prob(10)) M << "\blue SYSTEM ALERT: Energy boosting field detected!"
|
||||
return 1
|
||||
if("celldrain")
|
||||
for (var/obj/machinery/power/apc/C in range(src.aurarange,originator))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge = max(B.charge-10,0)
|
||||
for (var/obj/machinery/power/smes/S in range (src.aurarange,originator))
|
||||
S.charge = max(S.charge-20,0)
|
||||
for (var/mob/living/silicon/robot/M in range(src.aurarange,originator))
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge = max(D.charge-10,0)
|
||||
if(prob(10)) M << "\red SYSTEM ALERT: Energy draining field detected!"
|
||||
return 1
|
||||
if("planthelper")
|
||||
for (var/obj/machinery/hydroponics/H in range(src.aurarange,originator))
|
||||
//makes weeds and shrooms and stuff more potent too
|
||||
if(H.planted)
|
||||
H.waterlevel += 2
|
||||
H.nutrilevel += 2
|
||||
if(H.toxic > 0)
|
||||
H.toxic -= 1
|
||||
H.health += 1
|
||||
if(H.pestlevel > 0)
|
||||
H.pestlevel -= 1
|
||||
if(H.weedlevel > 0)
|
||||
H.weedlevel -= 1
|
||||
H.lastcycle += 5
|
||||
return 1
|
||||
if("sleepy")
|
||||
for (var/mob/living/carbon/M in range(src.aurarange,originator))
|
||||
if(prob(10))
|
||||
M << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
|
||||
M.drowsyness = min(M.drowsyness + 1, 25)
|
||||
M.eye_blurry = min(M.eye_blurry + 1, 25)
|
||||
return 1
|
||||
else if (src.effectmode == "pulse")
|
||||
for(var/mob/O in viewers(originator, null))
|
||||
O.show_message(text("<b>[]</b> emits a pulse of energy!", originator), 1)
|
||||
switch(src.effecttype)
|
||||
//caeltodo
|
||||
if("healing")
|
||||
for (var/mob/living/carbon/M in range(src.aurarange,originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
M << "\blue A wave of energy invigorates you."
|
||||
M.adjustBruteLoss(-5)
|
||||
M.adjustFireLoss(-5)
|
||||
M.adjustToxLoss(-5)
|
||||
M.adjustOxyLoss(-5)
|
||||
M.adjustBrainLoss(-5)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("injure")
|
||||
for (var/mob/living/carbon/M in range(src.aurarange,originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
M << "\red A wave of energy causes you great pain!"
|
||||
M.adjustBruteLoss(5)
|
||||
M.adjustFireLoss(5)
|
||||
M.adjustToxLoss(5)
|
||||
M.adjustOxyLoss(5)
|
||||
M.adjustBrainLoss(5)
|
||||
M.make_dizzy(6)
|
||||
M.weakened += 3
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("stun")
|
||||
for (var/mob/living/carbon/M in range(src.aurarange,originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
M << "\red A wave of energy overwhelms your senses!"
|
||||
M.paralysis += 3
|
||||
M.weakened += 4
|
||||
M.stuttering += 4
|
||||
return 1
|
||||
if("roboheal")
|
||||
for (var/mob/living/silicon/robot/M in range(src.aurarange,originator))
|
||||
M << "\blue SYSTEM ALERT: Structural damage has been repaired by energy pulse!"
|
||||
M.adjustBruteLoss(-10)
|
||||
M.adjustFireLoss(-10)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("robohurt")
|
||||
for (var/mob/living/silicon/robot/M in range(src.aurarange,originator))
|
||||
M << "\red SYSTEM ALERT: Structural damage inflicted by energy pulse!"
|
||||
M.adjustBruteLoss(10)
|
||||
M.adjustFireLoss(10)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("cellcharge")
|
||||
for (var/obj/machinery/power/apc/C in range(src.aurarange,originator))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge += 250
|
||||
for (var/obj/machinery/power/smes/S in range (src.aurarange,originator)) S.charge += 400
|
||||
for (var/mob/living/silicon/robot/M in range(src.aurarange,originator))
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge += 250
|
||||
M << "\blue SYSTEM ALERT: Large energy boost detected!"
|
||||
return 1
|
||||
if("celldrain")
|
||||
for (var/obj/machinery/power/apc/C in range(src.aurarange,originator))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge = max(B.charge-500,0)
|
||||
for (var/obj/machinery/power/smes/S in range (src.aurarange,originator))
|
||||
S.charge = max(S.charge-400,0)
|
||||
for (var/mob/living/silicon/robot/M in range(src.aurarange,originator))
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge = max(D.charge-500,0)
|
||||
M << "\red SYSTEM ALERT: Severe energy drain detected!"
|
||||
return 1
|
||||
if("planthelper")
|
||||
//makes weeds and shrooms and stuff more potent too
|
||||
for (var/obj/machinery/hydroponics/H in range(src.aurarange,originator))
|
||||
if(H.planted)
|
||||
H.dead = 0
|
||||
H.waterlevel = 200
|
||||
H.nutrilevel = 200
|
||||
H.toxic = 0
|
||||
H.health = 100
|
||||
H.pestlevel = 0
|
||||
H.weedlevel = 0
|
||||
H.lastcycle = H.cycledelay
|
||||
return 1
|
||||
if("teleport")
|
||||
for (var/mob/living/M in range(src.aurarange,originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/T in orange(M, 30))
|
||||
if(!istype(T, /turf/simulated/floor) || T.density)
|
||||
continue
|
||||
randomturfs.Add(T)
|
||||
if(randomturfs.len > 0)
|
||||
M << "\red You are displaced by a strange force!"
|
||||
if(M.buckled)
|
||||
M.buckled.unbuckle()
|
||||
M.loc = pick(randomturfs)
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(originator)) //no idea what the 0 is
|
||||
sparks.start()
|
||||
return 1
|
||||
if("dnaswitch")
|
||||
for(var/mob/living/H in range(src.aurarange,originator))
|
||||
if(ishuman(H) && istype(H:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(H:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
|
||||
if(prob(30))
|
||||
H << pick("\green You feel a little different.","\green You feel strange.","\green You feel different.")
|
||||
//todo
|
||||
if (H.gender == FEMALE)
|
||||
H.gender = MALE
|
||||
else
|
||||
H.gender = FEMALE
|
||||
/*H.dna.ready_dna(H)
|
||||
H.update_body()
|
||||
H.update_face()*/
|
||||
return 1
|
||||
if("emp")
|
||||
empulse(get_turf(originator), aurarange/2, aurarange)
|
||||
return 1
|
||||
if("sleepy")
|
||||
for (var/mob/living/carbon/M in range(src.aurarange,originator))
|
||||
if(prob(30))
|
||||
M << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
|
||||
if(prob(50))
|
||||
M.drowsyness = min(M.drowsyness + rand(1,5), 25)
|
||||
if(prob(50))
|
||||
M.eye_blurry = min(M.eye_blurry + rand(1,5), 25)
|
||||
return 1
|
||||
else if (src.effectmode == "worldpulse")
|
||||
for(var/mob/O in viewers(originator, null))
|
||||
O.show_message(text("<b>[]</b> emits a powerful burst of energy!", originator), 1)
|
||||
switch(src.effecttype)
|
||||
if("healing")
|
||||
for (var/mob/living/carbon/M in range(200, originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
M << "\blue Waves of soothing energy wash over you."
|
||||
M.adjustBruteLoss(-3)
|
||||
M.adjustFireLoss(-3)
|
||||
M.adjustToxLoss(-3)
|
||||
M.adjustOxyLoss(-3)
|
||||
M.adjustBrainLoss(-3)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("injure")
|
||||
for (var/mob/living/carbon/human/M in range(200, originator))
|
||||
M << "\red A wave of painful energy strikes you!"
|
||||
M.adjustBruteLoss(3)
|
||||
M.adjustFireLoss(3)
|
||||
M.adjustToxLoss(3)
|
||||
M.adjustOxyLoss(3)
|
||||
M.adjustBrainLoss(3)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("stun")
|
||||
for (var/mob/living/carbon/M in range(200, originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
M << "\red A powerful force causes you to black out momentarily."
|
||||
M.paralysis += 5
|
||||
M.weakened += 8
|
||||
M.stuttering += 8
|
||||
return 1
|
||||
if("roboheal")
|
||||
for (var/mob/living/silicon/robot/M in range(200, originator))
|
||||
M << "\blue SYSTEM ALERT: Structural damage has been repaired by energy pulse!"
|
||||
M.adjustBruteLoss(-5)
|
||||
M.adjustFireLoss(-5)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("robohurt")
|
||||
for (var/mob/living/silicon/robot/M in range(200, originator))
|
||||
M << "\red SYSTEM ALERT: Structural damage inflicted by energy pulse!"
|
||||
M.adjustBruteLoss(5)
|
||||
M.adjustFireLoss(5)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
if("cellcharge")
|
||||
for (var/obj/machinery/power/apc/C in range(200, originator))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge += 100
|
||||
for (var/obj/machinery/power/smes/S in range (src.aurarange,src)) S.charge += 250
|
||||
for (var/mob/living/silicon/robot/M in world)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge += 100
|
||||
M << "\blue SYSTEM ALERT: Energy boost detected!"
|
||||
return 1
|
||||
if("celldrain")
|
||||
for (var/obj/machinery/power/apc/C in range(200, originator))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge = max(B.charge-250,0)
|
||||
for (var/obj/machinery/power/smes/S in range (src.aurarange,src))
|
||||
S.charge = max(S.charge-250,0)
|
||||
for (var/mob/living/silicon/robot/M in world)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge = max(D.charge-250,0)
|
||||
M << "\red SYSTEM ALERT: Energy drain detected!"
|
||||
return 1
|
||||
if("teleport")
|
||||
for (var/mob/living/M in range(200, originator))
|
||||
if(ishuman(M) && istype(M:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(M:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/T in orange(M, 15))
|
||||
if(!istype(T, /turf/simulated/floor) || T.density)
|
||||
continue
|
||||
randomturfs.Add(T)
|
||||
if(randomturfs.len > 0)
|
||||
M << "\red You are displaced by a strange force!"
|
||||
if(M.buckled)
|
||||
M.buckled.unbuckle()
|
||||
M.loc = pick(randomturfs)
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(originator)) //no idea what the 0 is
|
||||
sparks.start()
|
||||
return 1
|
||||
if("dnaswitch")
|
||||
for(var/mob/living/H in range(200, originator))
|
||||
if(ishuman(H) && istype(H:wear_suit,/obj/item/clothing/suit/bio_suit/anomaly) && istype(H:head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
continue
|
||||
|
||||
if(prob(30))
|
||||
H << pick("\green You feel a little different.","\green You feel strange.","\green You feel different.")
|
||||
//todo
|
||||
if (H.gender == FEMALE)
|
||||
H.gender = MALE
|
||||
else
|
||||
H.gender = FEMALE
|
||||
/*H.dna.ready_dna(H)
|
||||
H.update_body()
|
||||
H.update_face()*/
|
||||
return 1
|
||||
if("sleepy")
|
||||
for(var/mob/living/H in range(200, originator))
|
||||
H.drowsyness = min(H.drowsyness + rand(5,15), 50)
|
||||
H.eye_blurry = min(H.eye_blurry + rand(5,15), 50)
|
||||
return 1
|
||||
|
||||
//initially for the force field artifact
|
||||
/datum/artifact_effect/proc/update_move(var/atom/originator)
|
||||
switch(effecttype)
|
||||
if("forcefield")
|
||||
while(created_field.len < 16)
|
||||
//for now, just instantly respawn the fields when they get destroyed
|
||||
var/obj/effect/energy_field/E = new (locate(originator.x,originator.y,originator))
|
||||
created_field.Add(E)
|
||||
E.strength = 1
|
||||
E.density = 1
|
||||
E.anchored = 1
|
||||
E.invisibility = 0
|
||||
|
||||
var/obj/effect/energy_field/E = created_field[1]
|
||||
E.loc = locate(originator.x + 2,originator.y + 2,originator.z)
|
||||
E = created_field[2]
|
||||
E.loc = locate(originator.x + 2,originator.y + 1,originator.z)
|
||||
E = created_field[3]
|
||||
E.loc = locate(originator.x + 2,originator.y,originator.z)
|
||||
E = created_field[4]
|
||||
E.loc = locate(originator.x + 2,originator.y - 1,originator.z)
|
||||
E = created_field[5]
|
||||
E.loc = locate(originator.x + 2,originator.y - 2,originator.z)
|
||||
E = created_field[6]
|
||||
E.loc = locate(originator.x + 1,originator.y + 2,originator.z)
|
||||
E = created_field[7]
|
||||
E.loc = locate(originator.x + 1,originator.y - 2,originator.z)
|
||||
E = created_field[8]
|
||||
E.loc = locate(originator.x,originator.y + 2,originator.z)
|
||||
E = created_field[9]
|
||||
E.loc = locate(originator.x,originator.y - 2,originator.z)
|
||||
E = created_field[10]
|
||||
E.loc = locate(originator.x - 1,originator.y + 2,originator.z)
|
||||
E = created_field[11]
|
||||
E.loc = locate(originator.x - 1,originator.y - 2,originator.z)
|
||||
E = created_field[12]
|
||||
E.loc = locate(originator.x - 2,originator.y + 2,originator.z)
|
||||
E = created_field[13]
|
||||
E.loc = locate(originator.x - 2,originator.y + 1,originator.z)
|
||||
E = created_field[14]
|
||||
E.loc = locate(originator.x - 2,originator.y,originator.z)
|
||||
E = created_field[15]
|
||||
E.loc = locate(originator.x - 2,originator.y - 1,originator.z)
|
||||
E = created_field[16]
|
||||
E.loc = locate(originator.x - 2,originator.y - 2,originator.z)
|
||||
@@ -324,26 +324,27 @@
|
||||
if(26)
|
||||
//energy gun
|
||||
var/spawn_type = pick(\
|
||||
/obj/item/weapon/gun/energy/laser/practice;100,\
|
||||
/obj/item/weapon/gun/energy/laser;75,\
|
||||
/obj/item/weapon/gun/energy/xray;50,\
|
||||
/obj/item/weapon/gun/energy/laser/captain;25,\
|
||||
)
|
||||
var/obj/item/weapon/gun/energy/new_gun = new spawn_type(src.loc)
|
||||
new_item = new_gun
|
||||
new_item.icon_state = "egun[rand(1,6)]"
|
||||
/obj/item/weapon/gun/energy/laser/practice,\
|
||||
/obj/item/weapon/gun/energy/laser,\
|
||||
/obj/item/weapon/gun/energy/xray,\
|
||||
/obj/item/weapon/gun/energy/laser/captain)
|
||||
if(spawn_type)
|
||||
var/obj/item/weapon/gun/energy/new_gun = new spawn_type(src.loc)
|
||||
new_item = new_gun
|
||||
new_item.icon_state = "egun[rand(1,6)]"
|
||||
new_gun.desc = "This is an antique energy weapon, you're not sure if it will fire or not."
|
||||
|
||||
//5% chance to explode when first fired
|
||||
//10% chance to have an unchargeable cell
|
||||
//15% chance to gain a random amount of starting energy, otherwise start with an empty cell
|
||||
if(prob(5))
|
||||
new_gun.power_supply.rigged = 1
|
||||
if(prob(10))
|
||||
new_gun.power_supply.maxcharge = 0
|
||||
if(prob(15))
|
||||
new_gun.power_supply.charge = rand(0, new_gun.power_supply.maxcharge)
|
||||
else
|
||||
new_gun.power_supply.charge = 0
|
||||
//5% chance to explode when first fired
|
||||
//10% chance to have an unchargeable cell
|
||||
//15% chance to gain a random amount of starting energy, otherwise start with an empty cell
|
||||
if(prob(5))
|
||||
new_gun.power_supply.rigged = 1
|
||||
if(prob(10))
|
||||
new_gun.power_supply.maxcharge = 0
|
||||
if(prob(15))
|
||||
new_gun.power_supply.charge = rand(0, new_gun.power_supply.maxcharge)
|
||||
else
|
||||
new_gun.power_supply.charge = 0
|
||||
|
||||
item_type = "gun"
|
||||
if(27)
|
||||
|
||||
@@ -206,6 +206,28 @@
|
||||
)
|
||||
return find_type
|
||||
|
||||
var/list/responsive_carriers = list( \
|
||||
"carbon", \
|
||||
"potassium", \
|
||||
"hydrogen", \
|
||||
"nitrogen", \
|
||||
"mercury", \
|
||||
"iron", \
|
||||
"chlorine", \
|
||||
"phosphorus", \
|
||||
"plasma")
|
||||
|
||||
var/list/finds_as_strings = list( \
|
||||
"Trace organic cells", \
|
||||
"Long exposure particles", \
|
||||
"Trace water particles", \
|
||||
"Crystalline structures", \
|
||||
"Metallic derivative", \
|
||||
"Metallic composite", \
|
||||
"Metamorphic/igneous rock composite", \
|
||||
"Metamorphic/sedimentary rock composite", \
|
||||
"Anomalous material" )
|
||||
|
||||
#undef ARCHAEO_BOWL
|
||||
#undef ARCHAEO_URN
|
||||
#undef ARCHAEO_CUTLERY
|
||||
|
||||
@@ -29,30 +29,6 @@
|
||||
pixel_x = rand(0,16)-8
|
||||
pixel_y = rand(0,8)-8
|
||||
|
||||
var/list/responsive_carriers = list( \
|
||||
"carbon", \
|
||||
"potassium", \
|
||||
"hydrogen", \
|
||||
"nitrogen", \
|
||||
"mercury", \
|
||||
"iron", \
|
||||
"chlorine", \
|
||||
"phosphorus", \
|
||||
"plasma")
|
||||
|
||||
var/list/finds_as_strings = list( \
|
||||
"Trace organic cells", \
|
||||
"Long exposure particles", \
|
||||
"Trace water particles", \
|
||||
"Crystalline structures", \
|
||||
"Metallic derivative", \
|
||||
"Metallic composite", \
|
||||
"Metamorphic/igneous rock composite", \
|
||||
"Metamorphic/sedimentary rock composite", \
|
||||
"Anomalous material" )
|
||||
|
||||
var/list/artifact_spawning_turfs = list()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Geosample datum
|
||||
|
||||
@@ -64,7 +40,6 @@ var/list/artifact_spawning_turfs = list()
|
||||
var/artifact_id = "" //id of a nearby artifact, if there is one
|
||||
var/artifact_distance = -1 //proportional to distance
|
||||
var/source_mineral = "chlorine" //machines will pop up a warning telling players that the sample may be confused
|
||||
var/total_spread = 0
|
||||
//
|
||||
//var/source_mineral
|
||||
//all potential finds are initialised to null, so nullcheck before you access them
|
||||
@@ -76,11 +51,11 @@ var/list/artifact_spawning_turfs = list()
|
||||
|
||||
//this should only need to be called once
|
||||
/datum/geosample/proc/UpdateTurf(var/turf/simulated/mineral/container)
|
||||
set background = 1
|
||||
if(!container || !istype(container))
|
||||
return
|
||||
|
||||
age = rand(1,999)
|
||||
total_spread = 0
|
||||
|
||||
switch(container.mineralName)
|
||||
if("Uranium")
|
||||
@@ -132,8 +107,15 @@ var/list/artifact_spawning_turfs = list()
|
||||
var/responsive_reagent = get_responsive_reagent(F.find_type)
|
||||
find_presence[responsive_reagent] = F.dissonance_spread
|
||||
|
||||
for(var/entry in find_presence)
|
||||
total_spread += find_presence[entry]
|
||||
//loop over again to reset values to percentages
|
||||
var/total_presence = 0
|
||||
for(var/carrier in find_presence)
|
||||
total_presence += find_presence[carrier]
|
||||
for(var/carrier in find_presence)
|
||||
find_presence[carrier] = find_presence[carrier] / total_presence
|
||||
|
||||
/*for(var/entry in find_presence)
|
||||
total_spread += find_presence[entry]*/
|
||||
|
||||
//have this separate from UpdateTurf() so that we dont have a billion turfs being updated (redundantly) every time an artifact spawns
|
||||
/datum/geosample/proc/UpdateNearbyArtifactInfo(var/turf/simulated/mineral/container)
|
||||
@@ -146,7 +128,7 @@ var/list/artifact_spawning_turfs = list()
|
||||
else
|
||||
for(var/turf/simulated/mineral/holder in artifact_spawning_turfs)
|
||||
if(holder.artifact_find)
|
||||
var/dist = get_dist(container, holder)
|
||||
var/dist = get_dist(container, holder) * 2
|
||||
if(dist < holder.artifact_find.artifact_detect_range && dist < src.artifact_distance)
|
||||
src.artifact_distance = dist
|
||||
src.artifact_id = holder.artifact_find.artifact_id
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
// This machine shows the age for extremely old finds
|
||||
|
||||
obj/machinery/anomaly/accelerator
|
||||
name = "Accelerator spectrometer"
|
||||
|
||||
obj/machinery/anomaly/accelerator/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier_name
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier_name = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier_name)
|
||||
var/specifity = GetResultSpecifity(scanned_sample, carrier_name)
|
||||
results = "Kinetic acceleration of carrier ([carrier_name]) indicates age ([100 * specifity]% accuracy): <br><br>"
|
||||
|
||||
if(scanned_sample.age_billion)
|
||||
var/displayed_age_millions = scanned_sample.age_million + max(scanned_sample.age_million * ((1 - specifity) * (2 * rand() - 1)), 0)
|
||||
var/displayed_age_billions = scanned_sample.age_billion + max(scanned_sample.age_billion * ((1 - specifity) * (2 * rand() - 1)), 0)
|
||||
results += "[displayed_age_billions + displayed_age_millions / 1000] billion years.<br>"
|
||||
else if(scanned_sample.age_million)
|
||||
var/displayed_age_thousands = scanned_sample.age_thousand + max(scanned_sample.age_thousand * ((1 - specifity) * (4 * rand() - 2)), 0)
|
||||
var/displayed_age_millions = scanned_sample.age_million + max(scanned_sample.age_million * ((1 - specifity) * (2 * rand() - 1)), 0)
|
||||
results += "[displayed_age_millions + displayed_age_thousands / 1000] million years.<br>"
|
||||
else if(scanned_sample.age_thousand)
|
||||
var/displayed_age = scanned_sample.age + max(scanned_sample.age * ((1 - specifity) * (8 * rand() - 4)), 0)
|
||||
var/displayed_age_thousands = scanned_sample.age_thousand + max(scanned_sample.age * ((1 - specifity) * (4 * rand() - 2)), 0)
|
||||
results += "[displayed_age_thousands + displayed_age / 1000] thousand years.<br>"
|
||||
else
|
||||
var/displayed_age = scanned_sample.age + max(scanned_sample.age * ((1 - specifity) * (8 * rand() - 4)), 0)
|
||||
results += "[displayed_age] years.<br>"
|
||||
|
||||
results += "<br>Warning, results only valid for ages on the scale of billions of years."
|
||||
|
||||
return results
|
||||
@@ -1,203 +0,0 @@
|
||||
//Handles how much the temperature changes on power use. (Joules/Kelvin)
|
||||
//Equates to as much heat energy per kelvin as a quarter tile of air.
|
||||
#define XENOARCH_HEAT_CAPACITY 5000
|
||||
|
||||
//Handles heat transfer to the air. (In watts)
|
||||
//Can heat a single tile 2 degrees per tick.
|
||||
#define XENOARCH_MAX_ENERGY_TRANSFER 4000
|
||||
|
||||
//How many joules of electrical energy produce how many joules of heat energy?
|
||||
#define XENOARCH_HEAT_COEFFICIENT 3
|
||||
|
||||
|
||||
/obj/machinery/anomaly
|
||||
name = "Analysis machine"
|
||||
desc = "A specialised, complex analysis machine."
|
||||
anchored = 1
|
||||
density = 1
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
idle_power_usage = 20 //watts
|
||||
active_power_usage = 300 //Because I need to make up numbers~
|
||||
|
||||
var/obj/item/weapon/reagent_containers/glass/held_container
|
||||
var/obj/item/weapon/tank/fuel_container
|
||||
var/target_scan_ticks = 30
|
||||
var/report_num = 0
|
||||
var/scan_process = 0
|
||||
var/temperature = 273 //measured in kelvin, if this exceeds 1200, the machine is damaged and requires repairs
|
||||
//if this exceeds 600 and safety is enabled it will shutdown
|
||||
//temp greater than 600 also requires a safety prompt to initiate scanning
|
||||
var/max_temp = 450
|
||||
|
||||
/obj/machinery/anomaly/New()
|
||||
..()
|
||||
|
||||
//for analysis debugging
|
||||
/*var/obj/item/weapon/reagent_containers/glass/solution_tray/S = new(src.loc)
|
||||
var/turf/simulated/mineral/diamond/D
|
||||
for(var/turf/simulated/mineral/diamond/M in world)
|
||||
D = M
|
||||
break
|
||||
S.reagents.add_reagent("analysis_sample", 1, D.geological_data)
|
||||
S.reagents.add_reagent("chlorine", 1, null)*/
|
||||
|
||||
/obj/machinery/anomaly/process()
|
||||
//not sure if everything needs to heat up, or just the GLPC
|
||||
var/datum/gas_mixture/env = loc.return_air()
|
||||
var/environmental_temp = env.temperature
|
||||
if(scan_process)
|
||||
if(scan_process++ > target_scan_ticks)
|
||||
FinishScan()
|
||||
else if(temperature > 400)
|
||||
src.visible_message("\blue \icon[src] shuts down from the heat!", 2)
|
||||
scan_process = 0
|
||||
else if(temperature > 350 && prob(10))
|
||||
src.visible_message("\blue \icon[src] bleets plaintively.", 2)
|
||||
if(temperature > 400)
|
||||
scan_process = 0
|
||||
|
||||
//show we're busy
|
||||
if(prob(5))
|
||||
src.visible_message("\blue \icon[src] [pick("whirrs","chuffs","clicks")][pick(" quietly"," softly"," sadly"," excitedly"," energetically"," angrily"," plaintively")].", 2)
|
||||
|
||||
use_power = 2
|
||||
|
||||
else
|
||||
use_power = 1
|
||||
|
||||
auto_use_power()
|
||||
|
||||
//Add 3000 joules when active. This is about 0.6 degrees per tick.
|
||||
//May need adjustment
|
||||
if(use_power == 1)
|
||||
var/heat_added = active_power_usage *XENOARCH_HEAT_COEFFICIENT
|
||||
|
||||
if(temperature < max_temp)
|
||||
temperature += heat_added/XENOARCH_HEAT_CAPACITY
|
||||
|
||||
var/temperature_difference = abs(environmental_temp-temperature)
|
||||
var/datum/gas_mixture/removed = loc.remove_air(env.total_moles*0.25)
|
||||
var/heat_capacity = removed.heat_capacity()
|
||||
|
||||
heat_added = max(temperature_difference*heat_capacity, XENOARCH_MAX_ENERGY_TRANSFER)
|
||||
|
||||
if(temperature > environmental_temp)
|
||||
//cool down to match the air
|
||||
temperature = max(TCMB, temperature - heat_added/XENOARCH_HEAT_CAPACITY)
|
||||
removed.temperature = max(TCMB, removed.temperature + heat_added/heat_capacity)
|
||||
|
||||
if(temperature_difference > 10 && prob(5))
|
||||
src.visible_message("\blue \icon[src] hisses softly.", 2)
|
||||
|
||||
else
|
||||
//heat up to match the air
|
||||
temperature = max(TCMB, temperature + heat_added/XENOARCH_HEAT_CAPACITY)
|
||||
removed.temperature = max(TCMB, removed.temperature - heat_added/heat_capacity)
|
||||
|
||||
if(temperature_difference > 10 && prob(5))
|
||||
src.visible_message("\blue \icon[src] plinks quietly.", 2)
|
||||
|
||||
env.merge(removed)
|
||||
|
||||
|
||||
//this proc should be overriden by each individual machine
|
||||
/obj/machinery/anomaly/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>[src.name]</B><BR>"
|
||||
dat += "Module heat level: [temperature] kelvin<br>"
|
||||
dat += "Safeties set at 350k, shielding failure at 400k. Failure to maintain safe heat levels may result in equipment damage.<br>"
|
||||
dat += "<hr>"
|
||||
if(scan_process)
|
||||
dat += "Scan in progress<br><br><br>"
|
||||
else
|
||||
dat += "[held_container ? "<A href='?src=\ref[src];eject_beaker=1'>Eject beaker</a>" : "No beaker inserted."]<br>"
|
||||
//dat += "[fuel_container ? "<A href='?src=\ref[src];eject_fuel=1'>Eject fuel tank</a>" : "No fuel tank inserted."]<br>"
|
||||
dat += "[held_container ? "<A href='?src=\ref[src];begin=1'>Begin scanning</a>" : ""]"
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close</a><BR>"
|
||||
user << browse(dat, "window=anomaly;size=450x500")
|
||||
onclose(user, "anomaly")
|
||||
|
||||
obj/machinery/anomaly/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
if(istype(W, /obj/item/weapon/reagent_containers/glass))
|
||||
//var/obj/item/weapon/reagent_containers/glass/G = W
|
||||
if(held_container)
|
||||
user << "\red You must remove the [held_container] first."
|
||||
else
|
||||
user << "\blue You put the [W] into the [src]."
|
||||
user.drop_item(W)
|
||||
held_container = W
|
||||
held_container.loc = src
|
||||
updateDialog()
|
||||
|
||||
/*else if(istype(W, /obj/item/weapon/tank))
|
||||
//var/obj/item/weapon/reagent_containers/glass/G = W
|
||||
if(fuel_container)
|
||||
user << "\red You must remove the [fuel_container] first."
|
||||
else
|
||||
user << "\blue You put the [fuel_container] into the [src]."
|
||||
user.drop_item(W)
|
||||
fuel_container.loc = src
|
||||
fuel_container = W
|
||||
updateDialog()*/
|
||||
else
|
||||
return ..()
|
||||
|
||||
obj/machinery/anomaly/proc/ScanResults()
|
||||
//instantiate in children to produce unique scan behaviour
|
||||
return "\red Error initialising scanning components."
|
||||
|
||||
obj/machinery/anomaly/proc/FinishScan()
|
||||
scan_process = 0
|
||||
updateDialog()
|
||||
|
||||
//determine the results and print a report
|
||||
if(held_container)
|
||||
src.visible_message("\blue \icon[src] makes an insistent chime.", 2)
|
||||
var/obj/item/weapon/paper/P = new(src.loc)
|
||||
P.name = "[src] report #[++report_num]"
|
||||
P.info = "<b>[src] analysis report #[report_num]</b><br><br>" + ScanResults()
|
||||
P.stamped = list(/obj/item/weapon/stamp)
|
||||
P.overlays = list("paper_stamped")
|
||||
else
|
||||
src.visible_message("\blue \icon[src] makes a low buzzing noise.", 2)
|
||||
|
||||
obj/machinery/anomaly/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=anomaly")
|
||||
usr.machine = null
|
||||
if(href_list["eject_beaker"])
|
||||
held_container.loc = src.loc
|
||||
held_container = null
|
||||
if(href_list["eject_fuel"])
|
||||
fuel_container.loc = src.loc
|
||||
fuel_container = null
|
||||
if(href_list["begin"])
|
||||
if(temperature >= 350)
|
||||
var/proceed = input("Unsafe internal temperature detected, enter YES below to continue.","Warning")
|
||||
if(proceed == "YES" && get_dist(src, usr) <= 1)
|
||||
scan_process = 1
|
||||
else
|
||||
scan_process = 1
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
//whether the carrier sample matches the possible finds
|
||||
//results greater than a threshold of 0.6 means a positive result
|
||||
obj/machinery/anomaly/proc/GetResultSpecifity(var/datum/geosample/scanned_sample, var/carrier_name)
|
||||
var/specifity = 0
|
||||
if(scanned_sample && carrier_name)
|
||||
|
||||
if(scanned_sample.find_presence.Find(carrier_name))
|
||||
specifity = 0.75 * (scanned_sample.find_presence[carrier_name] / scanned_sample.total_spread) + 0.25
|
||||
else
|
||||
specifity = rand(0, 0.5)
|
||||
|
||||
return specifity
|
||||
@@ -1,34 +0,0 @@
|
||||
|
||||
// This machine tells the distance to a nearby artifact, if there is one
|
||||
|
||||
obj/machinery/anomaly/fourier_transform
|
||||
name = "Fourier Transform spectroscope"
|
||||
|
||||
obj/machinery/anomaly/fourier_transform/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier)
|
||||
//all necessary components are present
|
||||
var/specifity = GetResultSpecifity(scanned_sample, carrier)
|
||||
var/distance = scanned_sample.artifact_distance
|
||||
if(distance > 0)
|
||||
distance += (2 * rand() - 1) * distance * 0.05
|
||||
results = "Fourier transform analysis on anomalous energy absorption through carrier ([carrier]) indicates source located inside emission radius ([95 * specifity]% accuracy): [distance]."
|
||||
else
|
||||
results = "Energy dispersion detected throughout sample consistent with background readings.<br>"
|
||||
if(carrier == scanned_sample.source_mineral)
|
||||
results += "Warning, analysis may be contaminated by high quantities of molecular carrier present throughout sample."
|
||||
|
||||
return results
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
// This machine shows the materials that are present
|
||||
|
||||
obj/machinery/anomaly/gas_chromatography
|
||||
name = "Gas Chromatography spectrometer"
|
||||
|
||||
obj/machinery/anomaly/gas_chromatography/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample)
|
||||
var/specifity = GetResultSpecifity(scanned_sample, carrier)
|
||||
results = "Chromatography partitioning analysis over carrier ([carrier]) indicates the following elements present ([100 * specifity]% accuracy):<br><br>"
|
||||
|
||||
var/num_found = 0
|
||||
for(var/index=1,index <= scanned_sample.find_presence.len, index++)
|
||||
var/find = scanned_sample.find_presence[index]
|
||||
if(find && prob(100 * specifity))
|
||||
results += " - " + finds_as_strings[index] + "<br>"
|
||||
num_found++
|
||||
|
||||
if(!num_found)
|
||||
results = "Chromatography partitioning results over carrier ([carrier]) to determine elemental makeup were inconclusive.<br>"
|
||||
|
||||
if(!carrier)
|
||||
results += "<br>No carrier detected, scan accuracy affected.<br>"
|
||||
|
||||
return results
|
||||
@@ -1,55 +0,0 @@
|
||||
|
||||
obj/machinery/anomaly/hyperspectral
|
||||
name = "Hyperspectral Imager"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "scanner"
|
||||
|
||||
obj/machinery/anomaly/hyperspectral/process()
|
||||
..()
|
||||
if(scan_process)
|
||||
icon_state = "scanner_active"
|
||||
else if(prob(10))
|
||||
icon_state = "scanner"
|
||||
flick(src, "scanner_active")
|
||||
|
||||
obj/machinery/anomaly/hyperspectral/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier)
|
||||
//all necessary components are present
|
||||
var/specifity = GetResultSpecifity(scanned_sample, carrier)
|
||||
results = "Spectral signature over carrier ([carrier]):<br>"
|
||||
if(specifity <= 0.25)
|
||||
//results += "<img src=\"http://i.imgur.com/TAQHn.jpg\"></img><br>"
|
||||
results += "<img src=chart1.jpg>"
|
||||
else if(specifity <= 0.5)
|
||||
//results += "<img src=\"http://i.imgur.com/EwOZ7.jpg\"></img><br>"
|
||||
results += "<img src=chart2.jpg>"
|
||||
else if(specifity <= 0.75)
|
||||
//results += "<img src=\"http://i.imgur.com/1qCae.jpg\"></img><br>"
|
||||
results += "<img src=chart3.jpg>"
|
||||
else
|
||||
//results += "<img src=\"http://i.imgur.com/9T9nc.jpg\"></img><br>"
|
||||
results += "<img src=chart4.jpg>"
|
||||
|
||||
results += "<br>"
|
||||
if(scanned_sample.artifact_id)
|
||||
results += "Detected energy signatures [100 * (1 - specifity)]% consistent with standard background readings.<br>"
|
||||
if(prob( (specifity + 0.5 * (1 - specifity)) * 100))
|
||||
results += "Anomalous exotic energy signature isolated: <font color='red'><b>[scanned_sample.artifact_id].</b></font>"
|
||||
else
|
||||
results += "Detected energy signatures [95 + 5 * (2 * rand() - 1) * (1 - specifity)]% consistent with standard background readings."
|
||||
|
||||
return results
|
||||
@@ -1,47 +0,0 @@
|
||||
|
||||
// This machine shows the amount of a certain material that is present
|
||||
|
||||
obj/machinery/anomaly/ion_mobility
|
||||
name = "Ion Mobility Spectrometer"
|
||||
desc = "A specialised, complex analysis machine."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
obj/machinery/anomaly/ion_mobility/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier)
|
||||
//all necessary components are present
|
||||
results = "Kinetic analysis on sample's ionic residue in carrier ([carrier]) indicates the dissonance spread:<br><br>"
|
||||
var/found = 0
|
||||
if(scanned_sample.find_presence.Find(carrier))
|
||||
var/dis_ratio = scanned_sample.find_presence[carrier]
|
||||
var/desc_index = responsive_carriers.Find(carrier)
|
||||
results += " - [finds_as_strings[desc_index]]: [dis_ratio]<br>"
|
||||
found++
|
||||
/*
|
||||
for(var/index=1,index <= scanned_sample.find_presence.len, index++)
|
||||
var/find = scanned_sample.find_presence[index]
|
||||
//world << "index: [index], find: [find], response: [responsive_carriers[index]], carrier: [carrier]"
|
||||
if(find && responsive_carriers[index] == carrier)
|
||||
results += " - [finds_as_strings[index]] [find * 100]%<br>"
|
||||
found++
|
||||
*/
|
||||
if(!found)
|
||||
results = "Kinetic analysis on sample's ionic residue in carrier ([carrier]) to determine composition were inconclusive.<br>"
|
||||
if(carrier == scanned_sample.source_mineral)
|
||||
results += "Warning, analysis may be contaminated by high quantities of molecular carrier present throughout sample."
|
||||
|
||||
return results
|
||||
@@ -1,51 +0,0 @@
|
||||
|
||||
// This machine shows the age for newer finds
|
||||
|
||||
obj/machinery/anomaly/isotope_ratio
|
||||
name = "Isotope ratio spectrometer"
|
||||
desc = "A specialised, complex analysis machine."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
obj/machinery/anomaly/isotope_ratio/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier_name
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier_name = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier_name)
|
||||
var/accuracy = GetResultSpecifity(scanned_sample, carrier_name)
|
||||
accuracy += 0.5 * (1 - accuracy) / scanned_sample.total_spread
|
||||
if(!accuracy)
|
||||
accuracy = rand(0.01, 0.5)
|
||||
results = "Isotope decay analysis in carrier ([carrier_name]) indicates age ([100 * accuracy]% accuracy): <br><br>"
|
||||
|
||||
if(scanned_sample.age_billion)
|
||||
//scramble the results
|
||||
var/displayed_age_thousands = rand(0, 999)
|
||||
var/displayed_age_millions = rand(0, 999)
|
||||
results += "[displayed_age_millions + displayed_age_thousands / 1000] million years.<br>"
|
||||
else if(scanned_sample.age_million)
|
||||
var/displayed_age_thousands = scanned_sample.age_thousand + max(scanned_sample.age_thousand * ((1 - accuracy) * (2 * rand() - 1)), 0)
|
||||
var/displayed_age_millions = scanned_sample.age_million + max(scanned_sample.age_million * ((1 - accuracy) * (4 * rand() - 2)), 0)
|
||||
results += "[displayed_age_millions + displayed_age_thousands / 1000] million years.<br>"
|
||||
else if(scanned_sample.age_thousand)
|
||||
var/displayed_age = scanned_sample.age + scanned_sample.age * ((1 - accuracy) * (2 * rand() - 1))
|
||||
var/displayed_age_thousands = scanned_sample.age_thousand + max(scanned_sample.age_thousand * ((1 - accuracy) * (2 * rand() - 1)), 0)
|
||||
results += "[displayed_age_thousands + displayed_age / 1000] thousand years.<br>"
|
||||
else
|
||||
var/displayed_age = scanned_sample.age + max(scanned_sample.age * ((1 - accuracy) * (2 * rand() - 1)), 0)
|
||||
results += "[displayed_age] years.<br>"
|
||||
|
||||
results += "<br>Warning, results only valid up to ages of one billion years."
|
||||
|
||||
return results
|
||||
@@ -1,318 +0,0 @@
|
||||
|
||||
//cael - some changes here. the analysis pad is entirely new
|
||||
|
||||
/obj/machinery/artifact_analyser
|
||||
name = "Artifact Analyser"
|
||||
desc = "Studies the structure of artifacts to discover their uses."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "analyser"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/working = 0
|
||||
var/accuO = 0
|
||||
var/accuT = 0
|
||||
var/accuE1 = 0
|
||||
var/accuE2 = 0
|
||||
var/aorigin = "None"
|
||||
var/atrigger = "None"
|
||||
var/aeffect1 = "None"
|
||||
var/aeffect2 = "None"
|
||||
var/list/origin_bonuses
|
||||
var/list/trigger_bonuses
|
||||
var/list/function_bonuses
|
||||
var/list/range_bonuses
|
||||
var/cur_id = ""
|
||||
var/scan_num = 0
|
||||
var/obj/machinery/artifact/cur_artifact = null
|
||||
var/obj/machinery/analyser_pad/owned_pad = null
|
||||
var/list/allorigins = list("Ancient Robots","Martian","Wizard Federation","Extradimensional","Precursor")
|
||||
var/list/alltriggers = list("Contact with Living Organism","Heavy Impact","Contact with Energy Source","Contact with Hydrogen","Contact with Corrosive Substance","Contact with Volatile Substance","Contact with Toxins","Exposure to Heat")
|
||||
var/list/alleffects = list("Healing Device","Anti-biological Weapon","Non-lethal Stunning Trap","Mechanoid Repair Module","Mechanoid Deconstruction Device","Power Generator","Power Drain","Stellar Mineral Attractor","Agriculture Regulator","Shield Generator","Space-Time Displacer")
|
||||
var/list/allranges = list("Constant Short-Range Energy Field","Medium Range Energy Pulses","Long Range Energy Pulses","Extreme Range Energy Pulses","Requires contact with subject")
|
||||
|
||||
/obj/machinery/artifact_analyser/New()
|
||||
..()
|
||||
origin_bonuses = new/list()
|
||||
origin_bonuses["ancient"] = 0
|
||||
origin_bonuses["martian"] = 0
|
||||
origin_bonuses["wizard"] = 0
|
||||
origin_bonuses["eldritch"] = 0
|
||||
origin_bonuses["precursor"] = 0
|
||||
trigger_bonuses = new/list()
|
||||
trigger_bonuses["ancient"] = 0
|
||||
trigger_bonuses["martian"] = 0
|
||||
trigger_bonuses["wizard"] = 0
|
||||
trigger_bonuses["eldritch"] = 0
|
||||
trigger_bonuses["precursor"] = 0
|
||||
function_bonuses = new/list()
|
||||
function_bonuses["ancient"] = 0
|
||||
function_bonuses["martian"] = 0
|
||||
function_bonuses["wizard"] = 0
|
||||
function_bonuses["eldritch"] = 0
|
||||
function_bonuses["precursor"] = 0
|
||||
range_bonuses = new/list()
|
||||
range_bonuses["ancient"] = 0
|
||||
range_bonuses["martian"] = 0
|
||||
range_bonuses["wizard"] = 0
|
||||
range_bonuses["eldritch"] = 0
|
||||
range_bonuses["precursor"] = 0
|
||||
//
|
||||
spawn(10)
|
||||
owned_pad = locate() in orange(1, src)
|
||||
|
||||
/obj/machinery/artifact_analyser/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>Artifact Analyser</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
if(!owned_pad)
|
||||
dat += "<B><font color=red>Unable to locate analysis pad.</font><BR></b>"
|
||||
dat += "<HR><BR>"
|
||||
else if (!src.working)
|
||||
dat += "<B>Artifact ID:</B> [cur_id]<BR>"
|
||||
dat += "<B>Artifact Origin:</B> [aorigin] ([accuO]%)<BR>"
|
||||
dat += "<B>Activation Trigger:</B> [atrigger] ([accuT]%)<BR>"
|
||||
dat += "<B>Artifact Function:</B> [aeffect1] ([accuE1]%)<BR>"
|
||||
dat += "<B>Artifact Range:</B> [aeffect2] ([accuE2]%)<BR><BR>"
|
||||
dat += "<HR><BR>"
|
||||
dat += "Artifact ID is determined from unique energy emission signatures.<br>"
|
||||
dat += "<A href='?src=\ref[src];analyse=1'>Analyse Artifact (Scan number #[scan_num+1])</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];upload=1'>Upload/update artifact scan</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];print=1'>Print Page</a><BR>"
|
||||
else
|
||||
dat += "<B>Please wait. Analysis in progress.</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
//
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
onclose(user, "artanalyser")
|
||||
|
||||
/obj/machinery/artifact_analyser/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
use_power(350)
|
||||
//
|
||||
if(!owned_pad)
|
||||
for(var/obj/machinery/analyser_pad/pad in range(1))
|
||||
owned_pad = pad
|
||||
break
|
||||
|
||||
/obj/machinery/artifact_analyser/proc/AA_FailedAnalysis(var/failtype)
|
||||
switch(failtype)
|
||||
if(1)
|
||||
src.aorigin = "Failed to Identify"
|
||||
if (prob(20)) src.aorigin = pick(src.allorigins)
|
||||
if(2)
|
||||
src.atrigger = "Failed to Identify"
|
||||
if (prob(20)) src.atrigger = pick(src.alltriggers)
|
||||
if(3)
|
||||
src.aeffect1 = "Failed to Identify"
|
||||
if (prob(20)) src.aeffect1 = pick(src.alleffects)
|
||||
if(4)
|
||||
src.aeffect2 = "Failed to Identify"
|
||||
if (prob(20)) src.aeffect2 = pick(src.allranges)
|
||||
|
||||
/obj/machinery/artifact_analyser/proc/AA_Analyse()
|
||||
if(!cur_artifact)
|
||||
return
|
||||
src.accuO = 5 + rand(0,10) + origin_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
src.accuT = 5 + rand(0,10) + trigger_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
src.accuE1 = 5 + rand(0,10) + function_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
src.accuE2 = 5 + rand(0,10) + range_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
|
||||
//keep any correctly determined properties the same
|
||||
var/origin_correct = 0
|
||||
var/trigger_correct = 0
|
||||
var/function_correct = 0
|
||||
var/range_correct = 0
|
||||
if(cur_id == cur_artifact.display_id)
|
||||
if(src.aorigin == cur_artifact.origin)
|
||||
origin_correct = 1
|
||||
|
||||
if(src.atrigger == cur_artifact.my_effect.trigger)
|
||||
trigger_correct = 1
|
||||
else if(src.atrigger == cur_artifact.my_effect.triggerX)
|
||||
trigger_correct = 1
|
||||
|
||||
if(src.aeffect1 == cur_artifact.my_effect.effecttype)
|
||||
function_correct = 1
|
||||
|
||||
if(src.aeffect2 == cur_artifact.my_effect.effectmode)
|
||||
range_correct = 1
|
||||
|
||||
if (src.accuO > 100) src.accuO = 100
|
||||
if (src.accuT > 100) src.accuT = 100
|
||||
if (src.accuE1 > 100) src.accuE1 = 100
|
||||
if (src.accuE2 > 100) src.accuE2 = 100
|
||||
// Roll to generate report
|
||||
if (prob(accuO) || origin_correct)
|
||||
switch(cur_artifact.origin)
|
||||
if("ancient") src.aorigin = "Ancient Robots"
|
||||
if("martian") src.aorigin = "Martian"
|
||||
if("wizard") src.aorigin = "Wizard Federation"
|
||||
if("eldritch") src.aorigin = "Extradimensional"
|
||||
if("precursor") src.aorigin = "Precursor"
|
||||
else src.aorigin = "Unknown Origin"
|
||||
origin_bonuses[cur_artifact.origin] += 10
|
||||
else
|
||||
AA_FailedAnalysis(1)
|
||||
origin_bonuses[cur_artifact.origin] += 5
|
||||
if (prob(accuT) || trigger_correct)
|
||||
switch(cur_artifact.my_effect.trigger)
|
||||
if("touch") src.atrigger = "Contact with Living Organism"
|
||||
if("force") src.atrigger = "Heavy Impact"
|
||||
if("energy") src.atrigger = "Contact with Energy Source"
|
||||
if("chemical")
|
||||
switch(cur_artifact.my_effect.triggerX)
|
||||
if("hydrogen") src.atrigger = "Contact with Hydrogen"
|
||||
if("corrosive") src.atrigger = "Contact with Corrosive Substance"
|
||||
if("volatile") src.atrigger = "Contact with Volatile Substance"
|
||||
if("toxin") src.atrigger = "Contact with Toxins"
|
||||
if("heat") src.atrigger = "Exposure to Heat"
|
||||
else src.atrigger = "Unknown Trigger"
|
||||
trigger_bonuses[cur_artifact.origin] += 5
|
||||
else
|
||||
AA_FailedAnalysis(2)
|
||||
trigger_bonuses[cur_artifact.origin] += 1
|
||||
if (prob(accuE1) || function_correct)
|
||||
switch(cur_artifact.my_effect.effecttype)
|
||||
if("healing") src.aeffect1 = "Healing Device"
|
||||
if("injure") src.aeffect1 = "Anti-biological Weapon"
|
||||
// if("stun") src.aeffect1 = "Non-lethal Stunning Trap"
|
||||
if("roboheal") src.aeffect1 = "Mechanoid Repair Module"
|
||||
if("robohurt") src.aeffect1 = "Mechanoid Deconstruction Device"
|
||||
if("cellcharge") src.aeffect1 = "Power Generator"
|
||||
if("celldrain") src.aeffect1 = "Power Drain"
|
||||
if("planthelper") src.aeffect1 = "Agriculture Regulator"
|
||||
if("forcefield") src.aeffect1 = "Shield Generator"
|
||||
if("teleport") src.aeffect1 = "Space-Time Displacer"
|
||||
else src.aeffect1 = "Unknown Effect"
|
||||
function_bonuses[cur_artifact.origin] += 5
|
||||
else
|
||||
AA_FailedAnalysis(3)
|
||||
function_bonuses[cur_artifact.origin] += 1
|
||||
if (prob(accuE2) || range_correct)
|
||||
switch(cur_artifact.my_effect.effectmode)
|
||||
if("aura") src.aeffect2 = "Constant Short-Range Energy Field"
|
||||
if("pulse")
|
||||
if(cur_artifact.my_effect.aurarange > 7) src.aeffect2 = "Long Range Energy Pulses"
|
||||
else src.aeffect2 = "Medium Range Energy Pulses"
|
||||
if("worldpulse") src.aeffect2 = "Extreme Range Energy Pulses"
|
||||
if("contact") src.aeffect2 = "Requires contact with subject"
|
||||
else src.aeffect2 = "Unknown Range"
|
||||
range_bonuses[cur_artifact.origin] += 5
|
||||
else
|
||||
AA_FailedAnalysis(4)
|
||||
range_bonuses[cur_artifact.origin] += 1
|
||||
|
||||
cur_artifact.name = "alien artifact ([cur_artifact.display_id])"
|
||||
cur_artifact.desc = "A large alien device. It has a small tag near the bottom that reads \"[cur_artifact.display_id]\"."
|
||||
cur_id = cur_artifact.display_id
|
||||
cur_artifact.my_effect.artifact_id = cur_artifact.display_id
|
||||
|
||||
/obj/machinery/artifact_analyser/Topic(href, href_list)
|
||||
|
||||
if(href_list["analyse"])
|
||||
if(owned_pad)
|
||||
var/turf/pad_turf = get_turf(owned_pad)
|
||||
var/findarti = 0
|
||||
for(var/obj/machinery/artifact/A in pad_turf.contents)
|
||||
findarti++
|
||||
cur_artifact = A
|
||||
if (findarti == 1)
|
||||
if(cur_artifact && cur_artifact.being_used)
|
||||
var/message = "<b>[src]</b> states, \"Cannot analyse. Excess energy drain is disrupting signal.\""
|
||||
src.visible_message(message, message)
|
||||
else
|
||||
cur_artifact.anchored = 1
|
||||
cur_artifact.being_used = 1
|
||||
src.working = 1
|
||||
src.icon_state = "analyser_processing"
|
||||
var/time = rand(30,50) + max(0, 300 - scan_num * 10)
|
||||
/*for(var/i = artifact_research.starting_tier, i <= artifact_research.max_tiers, i++)
|
||||
for(var/datum/artiresearch/R in artifact_research.researched_items[i])
|
||||
if (R.bonustype == "analyser") time -= R.bonusTime*/
|
||||
time *= 10
|
||||
var/message = "<b>[src]</b> states, \"Commencing analysis.\""
|
||||
src.visible_message(message, message)
|
||||
use_power(500)
|
||||
spawn(time)
|
||||
src.working = 0
|
||||
icon_state = "analyser"
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
if(cur_artifact.loc == pad_turf)
|
||||
AA_Analyse()
|
||||
scan_num++
|
||||
message = "<b>[src]</b> states, \"Analysis complete.\""
|
||||
src.visible_message(message, message)
|
||||
use_power(500)
|
||||
else if (findarti > 1)
|
||||
var/message = "<b>[src]</b> states, \"Cannot analyse. Error isolating energy signature.\""
|
||||
src.visible_message(message, message)
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot analyse. No noteworthy energy signature isolated.\""
|
||||
src.visible_message(message, message)
|
||||
|
||||
if(href_list["upload"] && cur_id != "")
|
||||
//add new datum to every DB in the world
|
||||
for(var/obj/machinery/computer/artifact_database/DB in world)
|
||||
var/update = 0
|
||||
for(var/datum/catalogued_artifact/CA in DB.catalogued_artifacts)
|
||||
if(CA.display_id == cur_id)
|
||||
//already there, so update it
|
||||
update = 1
|
||||
CA.origin = aorigin + " ([accuO]%)"
|
||||
CA.trigger = atrigger + " ([accuT]%)"
|
||||
CA.effecttype = aeffect1 + " ([accuE1]%)"
|
||||
CA.effectmode = aeffect2 + " ([accuE2]%)"
|
||||
if(!update)
|
||||
//not there, so add it
|
||||
var/datum/catalogued_artifact/CA = new()
|
||||
CA.display_id = cur_id
|
||||
CA.origin = aorigin + " ([accuO]%)"
|
||||
CA.trigger = atrigger + " ([accuT]%)"
|
||||
CA.effecttype = aeffect1 + " ([accuE1]%)"
|
||||
CA.effectmode = aeffect2 + " ([accuE2]%)"
|
||||
DB.catalogued_artifacts.Add(CA)
|
||||
use_power(100)
|
||||
|
||||
if(href_list["print"])
|
||||
var/r = "Artifact Analysis Report (Scan #[scan_num])<hr>"
|
||||
r += "<B>Artifact ID:</B> [cur_id] (determined from unique energy emission signatures)<BR>"
|
||||
r += "<B>Artifact Origin:</B> [aorigin] ([accuO]%)<BR>"
|
||||
r += "<B>Activation Trigger:</B> [atrigger] ([accuT]%)<BR>"
|
||||
r += "<B>Artifact Function:</B> [aeffect1] ([accuE1]%)<BR>"
|
||||
r += "<B>Artifact Range:</B> [aeffect2] ([accuE2]%)<BR><BR>"
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(src.loc)
|
||||
P.name = "Artifact Analysis Report #[scan_num]"
|
||||
P.info = r
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("\icon[src] \blue The [src.name] prints a sheet of paper", 3)
|
||||
use_power(10)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artanalyser")
|
||||
usr.machine = null
|
||||
|
||||
src.updateDialog()
|
||||
|
||||
//stick artifacts onto this then switch the analyser on
|
||||
/obj/machinery/analyser_pad
|
||||
name = "artifact analysis pad"
|
||||
desc = "Studies the structure of artifacts to discover their uses."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "tele0"
|
||||
anchored = 1
|
||||
density = 0
|
||||
|
||||
/obj/machinery/analyser_pad/New()
|
||||
..()
|
||||
/*spawn(10)
|
||||
for(var/obj/machinery/artifact_analyser/analyser in orange(1))
|
||||
world << "pad found analyser"
|
||||
if(!analyser.owned_pad)
|
||||
analyser.owned_pad = src
|
||||
world << "pad set analyser to self"
|
||||
break*/
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
/datum/catalogued_artifact
|
||||
var/trigger = "touch" // What activates it?
|
||||
var/effecttype = "healing" // What does it do?
|
||||
var/effectmode = "aura" // How does it carry out the effect?
|
||||
var/display_id = "" // Artifact ID to display once successfully scanned
|
||||
var/origin = ""
|
||||
|
||||
/obj/machinery/computer/artifact_database
|
||||
name = "Artifact Database"
|
||||
icon_state = "rdcomp"
|
||||
var/list/catalogued_artifacts
|
||||
|
||||
/obj/machinery/computer/artifact_database/New()
|
||||
..()
|
||||
catalogued_artifacts = new/list
|
||||
|
||||
/obj/machinery/computer/artifact_database/Topic(href, href_list)
|
||||
..()
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=artifact_db")
|
||||
usr.machine = null
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/computer/artifact_database/process()
|
||||
..()
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/computer/artifact_database/interact(mob/user)
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.machine = null
|
||||
user << browse(null, "window=artifact_db")
|
||||
return
|
||||
var/t = "<B>Artifact Database</B><BR>"
|
||||
t += "<hr>"
|
||||
for(var/datum/catalogued_artifact/CA in catalogued_artifacts)
|
||||
t += "<B>Artifact ID:</B> [CA.display_id] (determined from unique energy emission signatures)<BR>"
|
||||
t += "<B>Artifact Origin:</B> [CA.origin]<BR>"
|
||||
t += "<B>Activation Trigger:</B> [CA.trigger]<BR>"
|
||||
t += "<B>Artifact Function:</B> [CA.effecttype]<BR>"
|
||||
t += "<B>Artifact Range:</B> [CA.effectmode]<BR><BR>"
|
||||
t += "<hr>"
|
||||
t += "<A href='?src=\ref[src];refresh=1'>Refresh</A> <A href='?src=\ref[src];close=1'>Close</A><BR>"
|
||||
user << browse(t, "window=artifact_db;size=500x800")
|
||||
user.machine = src
|
||||
|
||||
/*
|
||||
/datum/artifact_effect
|
||||
var/origin = null // Used in the randomisation/research of the artifact.
|
||||
var/trigger = "touch" // What activates it?
|
||||
var/triggerX = "none" // Used for more varied triggers
|
||||
var/effecttype = "healing" // What does it do?
|
||||
var/effectmode = "aura" // How does it carry out the effect?
|
||||
var/aurarange = 4 // How far the artifact will extend an aura effect.
|
||||
var/display_id = "" // Artifact ID to display once successfully scanned
|
||||
var/list/created_field
|
||||
*/
|
||||
59
code/modules/research/xenoarchaeology/machinery/coolant.dm
Normal file
59
code/modules/research/xenoarchaeology/machinery/coolant.dm
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
datum/reagent/coolant
|
||||
name = "Coolant"
|
||||
id = "coolant"
|
||||
description = "Industrial cooling substance."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC" // rgb: 200, 165, 220
|
||||
|
||||
datum/chemical_reaction/coolant
|
||||
name = "Coolant"
|
||||
id = "coolant"
|
||||
result = "coolant"
|
||||
required_reagents = list("tungsten" = 1, "oxygen" = 1, "water" = 1)
|
||||
result_amount = 3
|
||||
|
||||
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank
|
||||
name = "coolant tank"
|
||||
desc = "A tank of industrial coolant"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "coolanttank"
|
||||
amount_per_transfer_from_this = 10
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("coolant",1000)
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if(!istype(Proj ,/obj/item/projectile/beam/lastertag) && !istype(Proj ,/obj/item/projectile/beam/practice) )
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank/blob_act()
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank/ex_act()
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank/proc/explode()
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/S = new /datum/effect/effect/system/harmless_smoke_spread
|
||||
//S.attach(src)
|
||||
S.set_up(5, 0, src.loc)
|
||||
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
spawn(0)
|
||||
S.start()
|
||||
|
||||
var/datum/gas_mixture/env = src.loc.return_air()
|
||||
if(env)
|
||||
if (reagents.total_volume > 750)
|
||||
env.temperature = 0
|
||||
else if (reagents.total_volume > 500)
|
||||
env.temperature -= 100
|
||||
else
|
||||
env.temperature -= 50
|
||||
|
||||
sleep(10)
|
||||
if(src)
|
||||
del(src)
|
||||
@@ -0,0 +1,355 @@
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer
|
||||
name = "Radiocarbon spectrometer"
|
||||
desc = "A specialised, complex scanner for gleaning information on all manner of small things."
|
||||
anchored = 1
|
||||
density = 1
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
use_power = 1 //1 = idle, 2 = active
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 300
|
||||
|
||||
//var/obj/item/weapon/reagent_containers/glass/coolant_container
|
||||
var/scanning = 0
|
||||
var/report_num = 0
|
||||
//
|
||||
var/obj/item/scanned_item
|
||||
var/last_scan_data = "No scans on record."
|
||||
//
|
||||
var/last_process_worldtime = 0
|
||||
//
|
||||
var/scanner_progress = 0
|
||||
var/scanner_rate = 1.25 //80 seconds per scan
|
||||
var/scanner_rpm = 0
|
||||
var/scanner_rpm_dir = 1
|
||||
var/scanner_temperature = 0
|
||||
var/scanner_seal_integrity = 100
|
||||
//
|
||||
var/coolant_usage_rate = 0 //measured in u/microsec
|
||||
var/fresh_coolant = 0
|
||||
var/coolant_purity = 0
|
||||
var/datum/reagents/coolant_reagents
|
||||
var/used_coolant = 0
|
||||
var/list/coolant_reagents_purity = list()
|
||||
//
|
||||
var/maser_wavelength = 0
|
||||
var/optimal_wavelength = 0
|
||||
var/optimal_wavelength_target = 0
|
||||
var/tleft_retarget_optimal_wavelength = 0
|
||||
var/maser_efficiency = 0
|
||||
//
|
||||
var/radiation = 0 //0-100 mSv
|
||||
var/t_left_radspike = 0
|
||||
var/rad_shield = 0
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/New()
|
||||
..()
|
||||
create_reagents(500)
|
||||
coolant_reagents_purity["water"] = 0.5
|
||||
coolant_reagents_purity["icecoffee"] = 0.6
|
||||
coolant_reagents_purity["icetea"] = 0.6
|
||||
coolant_reagents_purity["milkshake"] = 0.6
|
||||
coolant_reagents_purity["leporazine"] = 0.7
|
||||
coolant_reagents_purity["kelotane"] = 0.7
|
||||
coolant_reagents_purity["sterilizine"] = 0.7
|
||||
coolant_reagents_purity["dermaline"] = 0.7
|
||||
coolant_reagents_purity["hyperzine"] = 0.8
|
||||
coolant_reagents_purity["cryoxadone"] = 0.9
|
||||
coolant_reagents_purity["coolant"] = 1
|
||||
coolant_reagents_purity["adminordrazine"] = 2
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/attack_hand(var/mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(scanning)
|
||||
user << "<span class='warning'>You can't do that while [src] is scanning!</span>"
|
||||
else
|
||||
if(istype(I, /obj/item/stack/nanopaste))
|
||||
var/choice = alert("What do you want to do with the nanopaste?","Radiometric Scanner","Add nanopaste","Fix seal integrity")
|
||||
if(choice == "Fix seal integrity")
|
||||
var/obj/item/stack/nanopaste/N = I
|
||||
var/amount_used = min(N.amount, 10 - scanner_seal_integrity / 10)
|
||||
N.use(amount_used)
|
||||
scanner_seal_integrity = round(scanner_seal_integrity + amount_used * 10)
|
||||
return
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
var/choice = alert("What do you want to do with the container?","Radiometric Scanner","Add coolant","Empty coolant","Scan container")
|
||||
if(choice == "Add coolant")
|
||||
var/obj/item/weapon/reagent_containers/glass/G = I
|
||||
G.reagents.trans_to(src, min(src.reagents.maximum_volume - src.reagents.total_volume, G.reagents.total_volume))
|
||||
update_coolant()
|
||||
return
|
||||
else if(choice == "Empty coolant")
|
||||
var/obj/item/weapon/reagent_containers/glass/G = I
|
||||
src.reagents.trans_to(G, min(G.reagents.maximum_volume - G.reagents.total_volume, src.reagents.total_volume))
|
||||
update_coolant()
|
||||
return
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
scanned_item = I
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/proc/update_coolant()
|
||||
var/total_purity = 0
|
||||
fresh_coolant = 0
|
||||
coolant_purity = 0
|
||||
for (var/datum/reagent/current_reagent in src.reagents.reagent_list)
|
||||
if (!current_reagent)
|
||||
continue
|
||||
var/cur_purity = coolant_reagents_purity[current_reagent.id]
|
||||
if(!cur_purity)
|
||||
cur_purity = 0.1
|
||||
total_purity += cur_purity
|
||||
fresh_coolant += current_reagent.volume
|
||||
if(total_purity && fresh_coolant)
|
||||
coolant_purity = total_purity / fresh_coolant
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/ui_interact(mob/user, ui_key = "radio_spectro")
|
||||
|
||||
if(user.stat)
|
||||
return
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
var/data[0]
|
||||
data["scanned_item"] = (scanned_item ? scanned_item.name : "")
|
||||
data["scanned_item_desc"] = (scanned_item ? (scanned_item.desc ? scanned_item.desc : "No information on record.") : "")
|
||||
data["last_scan_data"] = last_scan_data
|
||||
//
|
||||
data["scan_progress"] = round(scanner_progress)
|
||||
data["scanning"] = scanning
|
||||
//
|
||||
data["scanner_seal_integrity"] = round(scanner_seal_integrity)
|
||||
data["scanner_rpm"] = round(scanner_rpm)
|
||||
data["scanner_temperature"] = round(scanner_temperature)
|
||||
//
|
||||
data["coolant_usage_rate"] = "[coolant_usage_rate]"
|
||||
data["unused_coolant_abs"] = round(fresh_coolant)
|
||||
data["unused_coolant_per"] = round(fresh_coolant / reagents.maximum_volume * 100)
|
||||
data["coolant_purity"] = "[coolant_purity * 100]"
|
||||
//
|
||||
data["optimal_wavelength"] = round(optimal_wavelength)
|
||||
data["maser_wavelength"] = round(maser_wavelength)
|
||||
data["maser_efficiency"] = round(maser_efficiency * 100)
|
||||
//
|
||||
data["radiation"] = round(radiation)
|
||||
data["t_left_radspike"] = round(t_left_radspike)
|
||||
data["rad_shield_on"] = rad_shield
|
||||
|
||||
var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, ui_key)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new one
|
||||
ui = new(user, src, ui_key, "geoscanner.tmpl", "High Res Radiocarbon Spectrometer", 900, 825)
|
||||
// When the UI is first opened this is the data it will use
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
// Auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
else
|
||||
// The UI is already open so push the new data to it
|
||||
ui.push_data(data)
|
||||
return
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/process()
|
||||
if(scanning)
|
||||
if(!scanned_item || scanned_item.loc != src)
|
||||
scanned_item = null
|
||||
stop_scanning()
|
||||
else if(scanner_progress >= 100)
|
||||
complete_scan()
|
||||
else
|
||||
//calculate time difference
|
||||
var/deltaT = (world.time - last_process_worldtime) * 0.1
|
||||
|
||||
//modify the RPM over time
|
||||
//i want 1u to last for 10 sec at 500 RPM, scaling linearly
|
||||
scanner_rpm += scanner_rpm_dir * 50 * deltaT
|
||||
if(scanner_rpm > 1000)
|
||||
scanner_rpm = 1000
|
||||
scanner_rpm_dir = -1 * pick(0.5, 2.5, 5.5)
|
||||
else if(scanner_rpm < 1)
|
||||
scanner_rpm = 1
|
||||
scanner_rpm_dir = 1 * pick(0.5, 2.5, 5.5)
|
||||
|
||||
//heat up according to RPM
|
||||
//each unit of coolant
|
||||
scanner_temperature += scanner_rpm * deltaT * 0.05
|
||||
|
||||
//radiation
|
||||
t_left_radspike -= deltaT
|
||||
if(t_left_radspike > 0)
|
||||
//ordinary radiation
|
||||
radiation = rand() * 15
|
||||
else
|
||||
//radspike
|
||||
if(t_left_radspike > -5)
|
||||
radiation = rand() * 15 + 85
|
||||
if(!rad_shield)
|
||||
//irradiate nearby mobs
|
||||
for(var/mob/living/M in view(7,src))
|
||||
M.apply_effect(radiation / 25, IRRADIATE, 0)
|
||||
else
|
||||
t_left_radspike = pick(10,15,25)
|
||||
|
||||
//use some coolant to cool down
|
||||
if(coolant_usage_rate > 0)
|
||||
var/coolant_used = min(fresh_coolant, coolant_usage_rate * deltaT)
|
||||
if(coolant_used > 0)
|
||||
fresh_coolant -= coolant_used
|
||||
used_coolant += coolant_used
|
||||
scanner_temperature = max(scanner_temperature - coolant_used * coolant_purity * 20, 0)
|
||||
|
||||
//modify the optimal wavelength
|
||||
tleft_retarget_optimal_wavelength -= deltaT
|
||||
if(tleft_retarget_optimal_wavelength <= 0)
|
||||
tleft_retarget_optimal_wavelength = pick(4,8,15)
|
||||
optimal_wavelength_target = rand() * 9900 + 100
|
||||
//
|
||||
if(optimal_wavelength < optimal_wavelength_target)
|
||||
optimal_wavelength = min(optimal_wavelength + 700 * deltaT, optimal_wavelength_target)
|
||||
else if(optimal_wavelength > optimal_wavelength_target)
|
||||
optimal_wavelength = max(optimal_wavelength - 700 * deltaT, optimal_wavelength_target)
|
||||
//
|
||||
maser_efficiency = 1 - max(min(10000, abs(optimal_wavelength - maser_wavelength) * 3), 1) / 10000
|
||||
|
||||
//make some scan progress
|
||||
if(!rad_shield)
|
||||
scanner_progress = min(100, scanner_progress + scanner_rate * maser_efficiency * deltaT)
|
||||
|
||||
//degrade the seal over time according to temperature
|
||||
//i want temperature of 50K to degrade at 1%/sec
|
||||
scanner_seal_integrity -= (max(scanner_temperature, 1) / 1000) * deltaT
|
||||
|
||||
//emergency stop if seal integrity reaches 0
|
||||
if(scanner_seal_integrity <= 0 || (scanner_temperature >= 1273 && !rad_shield))
|
||||
stop_scanning()
|
||||
src.visible_message("\blue \icon[src] buzzes unhappily. It has failed mid-scan!", 2)
|
||||
|
||||
if(prob(5))
|
||||
src.visible_message("\blue \icon[src] [pick("whirrs","chuffs","clicks")][pick(" excitedly"," energetically"," busily")].", 2)
|
||||
else
|
||||
//gradually cool down over time
|
||||
if(scanner_temperature > 0)
|
||||
scanner_temperature = max(scanner_temperature - 5 - 10 * rand(), 0)
|
||||
if(prob(0.75))
|
||||
src.visible_message("\blue \icon[src] [pick("plinks","hisses")][pick(" quietly"," softly"," sadly"," plaintively")].", 2)
|
||||
last_process_worldtime = world.time
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/proc/stop_scanning()
|
||||
scanning = 0
|
||||
scanner_rpm_dir = 1
|
||||
scanner_rpm = 0
|
||||
optimal_wavelength = 0
|
||||
maser_efficiency = 0
|
||||
maser_wavelength = 0
|
||||
coolant_usage_rate = 0
|
||||
radiation = 0
|
||||
t_left_radspike = 0
|
||||
if(used_coolant)
|
||||
src.reagents.remove_any(used_coolant)
|
||||
used_coolant = 0
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/proc/complete_scan()
|
||||
src.visible_message("\blue \icon[src] makes an insistent chime.", 2)
|
||||
|
||||
if(scanned_item)
|
||||
//create report
|
||||
var/obj/item/weapon/paper/P = new(src)
|
||||
P.name = "[src] report #[++report_num]: [scanned_item.name]"
|
||||
P.stamped = list(/obj/item/weapon/stamp)
|
||||
P.overlays = list("paper_stamped")
|
||||
|
||||
//work out data
|
||||
var/data = " - Mundane object: [scanned_item.desc ? scanned_item.desc : "No information on record."]<br>"
|
||||
var/datum/geosample/G
|
||||
switch(scanned_item.type)
|
||||
if(/obj/item/weapon/ore)
|
||||
var/obj/item/weapon/ore/O = scanned_item
|
||||
if(O.geological_data)
|
||||
G = O.geological_data
|
||||
|
||||
if(/obj/item/weapon/rocksliver)
|
||||
var/obj/item/weapon/rocksliver/O = scanned_item
|
||||
if(O.geological_data)
|
||||
G = O.geological_data
|
||||
|
||||
if(/obj/item/weapon/archaeological_find)
|
||||
data = " - Mundane object (archaic xenos origins)<br>"
|
||||
|
||||
var/obj/item/weapon/archaeological_find/A = scanned_item
|
||||
if(A.speaking_to_players)
|
||||
data = " - Exhibits properties consistent with sonic reproduction.<br>"
|
||||
if(A.listening_to_players)
|
||||
data = " - Exhibits properties similar to audio capture technology.<br>"
|
||||
|
||||
var/anom_found = 0
|
||||
if(G)
|
||||
data = " - Spectometric analysis on mineral sample has determined type [finds_as_strings[responsive_carriers.Find(G.source_mineral)]]<br>"
|
||||
if(G.age_billion > 0)
|
||||
data += " - Radiometric dating shows age of [G.age_billion].[G.age_million] billion years<br>"
|
||||
else if(G.age_million > 0)
|
||||
data += " - Radiometric dating shows age of [G.age_million].[G.age_thousand] million years<br>"
|
||||
else
|
||||
data += " - Radiometric dating shows age of [G.age_thousand * 1000 + G.age] years<br>"
|
||||
data += " - Chromatographic analysis shows the following materials present:<br>"
|
||||
for(var/carrier in G.find_presence)
|
||||
if(G.find_presence[carrier])
|
||||
var/index = responsive_carriers.Find(carrier)
|
||||
if(index > 0 && index <= finds_as_strings.len)
|
||||
data += " > [100 * G.find_presence[carrier]]% [finds_as_strings[index]]<br>"
|
||||
|
||||
if(G.artifact_id && G.artifact_distance >= 0)
|
||||
anom_found = 1
|
||||
data += " - Hyperspectral imaging reveals exotic energy wavelength detected with ID: [G.artifact_id]<br>"
|
||||
data += " - Fourier transform analysis on anomalous energy absorption indicates energy source located inside emission radius of [G.artifact_distance]m<br>"
|
||||
|
||||
if(!anom_found)
|
||||
data += " - No anomalous data<br>"
|
||||
|
||||
P.info = "<b>[src] analysis report #[report_num]</b><br>"
|
||||
P.info += "<b>Scanned item:</b> [scanned_item.name]<br><br>" + data
|
||||
last_scan_data = P.info
|
||||
P.loc = src.loc
|
||||
|
||||
scanned_item.loc = src.loc
|
||||
scanned_item = null
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/Topic(href, href_list)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0 // don't update UIs attached to this object
|
||||
|
||||
if(href_list["scanItem"])
|
||||
if(scanning)
|
||||
stop_scanning()
|
||||
else
|
||||
if(scanned_item)
|
||||
if(scanner_seal_integrity > 0)
|
||||
scanner_progress = 0
|
||||
scanning = 1
|
||||
t_left_radspike = pick(5,10,15)
|
||||
usr << "<span class='notice'>Scan initiated.</span>"
|
||||
else
|
||||
usr << "<span class='warning'>Could not initiate scan, seal requires replacing.</span>"
|
||||
else
|
||||
usr << "<span class='warning'>Insert an item to scan.</span>"
|
||||
|
||||
if(href_list["maserWavelength"])
|
||||
maser_wavelength = max(min(maser_wavelength + 1000 * text2num(href_list["maserWavelength"]), 10000), 1)
|
||||
|
||||
if(href_list["coolantRate"])
|
||||
coolant_usage_rate = max(min(coolant_usage_rate + text2num(href_list["coolantRate"]), 10000), 0)
|
||||
|
||||
if(href_list["toggle_rad_shield"])
|
||||
if(rad_shield)
|
||||
rad_shield = 0
|
||||
else
|
||||
rad_shield = 1
|
||||
|
||||
if(href_list["ejectItem"])
|
||||
if(scanned_item)
|
||||
scanned_item.loc = src.loc
|
||||
scanned_item = null
|
||||
|
||||
add_fingerprint(usr)
|
||||
return 1 // update UIs attached to this object
|
||||
@@ -49,6 +49,8 @@
|
||||
<li><b>Core sampler</b> - use this to take core samples from rock faces, which you can then run to the lab for analysis.</li>
|
||||
<li><b>Depth scanner</b> - uses x-ray diffraction to locate anomalous densities in rock, indicating archaeological deposits or mineral veins.
|
||||
Comes with a handy reference log containing co-ordinates and time of each scan.</li>
|
||||
<li><b>Alden-Saraspova counter</b> - uses a patented application of Fourier Transform analysis to determine the difference between background and
|
||||
exotic radiation. Use it to determine how far you are from anomalous energy sources.</li>
|
||||
<li><b>Radio beacon locater</b> - leave a beacon at an item of interest, then track it down later with this handy gadget. Watch for interference from other
|
||||
devices though.</li>
|
||||
<li><b>Flashlight or portable light source</b> - Self explanatory, I hope.</li>
|
||||
@@ -129,51 +131,50 @@
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Terms">A note on terms</a></li>
|
||||
<li><a href="#Isotope">Isotope ratio spectrometer</a></li>
|
||||
<li><a href="#Accelerator">Accelerator spectrometer</a></li>
|
||||
<li><a href="#Gas">Gas chromatography spectrometer</a></li>
|
||||
<li><a href="#Ion">Ion mobility spectrometer</a></li>
|
||||
<li><a href="#Analysis">Analysis progression</a></li>
|
||||
<li><a href="#Heat">Heat management</a></li>
|
||||
<li><a href="#Radiation">Ambient radiation</a></li>
|
||||
</ol>
|
||||
|
||||
<br>
|
||||
<h1><a name="Terms">A note on terms</a></h1>
|
||||
<list>
|
||||
<li><b>Dissonance ratio</b> - This is a pseudoarbitrary value indicating the overal presence of a particular element in a greater composite.
|
||||
It takes into account volume, density, molecular excitation and isotope spread.</li>
|
||||
<li><b>Mass spectrometry</b> - MS is the procedure used used to measure and quantify the components of matter. The most prized tool in the field of
|
||||
'Materials analysis'</li>
|
||||
<li><b>Radiometric dating</b> - MS applied using the right carrier reagents can be used to accurately determine the age of a sample.</li>
|
||||
<li><b>Sample specifity</b> - A pseudoarbitrary value used to indicate how well a sample resonates with the employed carrier reagent. Great specifity
|
||||
(material resonance) indicates that there is much of the carrier reagent present in the sample.</li>
|
||||
<li><b>Dissonance ratio</b> - This is a pseudoarbitrary value indicating the overal presence of a particular element in a greater composite.
|
||||
It takes into account volume, density, molecular excitation and isotope spread.</li>
|
||||
<li><b>Vacuum seal integrity</b> - A reference to how close an airtight seal is to failure.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Isotope">Isotope ratio spectrometer</a></h1>
|
||||
Isotope ratio mass spectrometers work by coating a small surface with a semiliquid <i>stationary phase</i> consisting of the sample to be
|
||||
analysed, and recording it's interactions with a gaseous <i>mobile phase</i> comprised of an inert or nonreactive gas such as helium or nitrogen.<br>
|
||||
<h1><a name="Analysis">Analysis progression</a></h1>
|
||||
Modern mass spectrometry requires constant attention from the diligant researcher in order to be successul. There are many different elements to juggle,
|
||||
and later chapters will delve into them. For the spectrometry assistant, the first thing you need to know is that the scanner wavelength is automatically
|
||||
calculated for you. Just tweak the settings and try to match it with the actual wavelength as closely as possible.<br>
|
||||
<br>
|
||||
IRMS are employed as radiometric daters, extremely accurate but only so up to ages of one billion years.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Accelerator">Accelerator spectrometer</a></h1>
|
||||
The accelerator mass spectrometer works by accelerating ions to extraordinarily high kinetic energies before mass analysis. The special strength of AMS is
|
||||
isolate rare or low-strength isotopes, making it able to determine much greater ages with reasonable accuracy.<br>
|
||||
<h1><a name="Seal">Seal integrity</a></h1>
|
||||
In order to maintain sterile and environmentally static procedures, a special chamber is setup inside the spectrometer. It's protected by a proprietary vacuum seal
|
||||
produced by top tier industrial science. It will only last for a certain number of scans before failing outright, but it can be resealed through use of nanite paste.
|
||||
Unfortunately, it's susceptible to malforming under heat stress so exposing it to higher temperatures will cause it's operation life to drop significantly.<br>
|
||||
<br>
|
||||
AMS are employed as extreme age radiometric daters, able to determine the age of the sample on a scale of billions of years.
|
||||
They are commonly located in geology and archaeology laboratories.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Gas">Gas chromatography spectrometer</a></h1>
|
||||
Gas-liquid chromatography mass spectrometers work by coating a small surface with a semiliquid <i>stationary phase</i> consisting of the sample to be
|
||||
analysed, and recording it's interactions with a gaseous <i>mobile phase</i> comprised of an inert or nonreactive gas such as helium or nitrogen.<br>
|
||||
<h1><a name="Heat">Heat management</a></h1>
|
||||
The scanner relies on a gyro-rotational system that varies in speed and intensity. Over the course of an ordinary scan, the RPMs can change dramatically. Higher RPMs
|
||||
means greater heat generation, but is necessary for the ongoing continuation of the scan. To offset heat production, spectrometers have an inbuilt cooling system.
|
||||
Researchers can modify the flow rate of coolant to aid in dropping temperature as necessary, but are advised that frequent coolant replacements may be necessary
|
||||
depending on coolant purity. Water and substances such as cryoxadone are viable substitutes, but nowhere near as effective as pure coolant itself.<br>
|
||||
<br>
|
||||
GLCS are employed in forensic and geological analysis to determine what elements are present in a sample.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Ion">Ion mobility spectrometer</a></h1>
|
||||
Ion mobility mass spectrometers work by examining the mobility of ionized molecules in an inert carrier gas<br>
|
||||
<h1><a name="Radiation">Ambient radiation</a></h1>
|
||||
Researchers are warned that while operational, mass spectrometers emit period bursts of radiation and are thus advised to wear protective gear. In the event of
|
||||
radiation spikes, there is also a special shield that can be lowered to block emissions. Lowering this, however, will have the effect of blocking the scanner
|
||||
so use it sparingly.<br>
|
||||
<br>
|
||||
IMS returns a dissonance ratio over the scanned sample and carrier reagent, indicating the average total presence of the sample.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
@@ -197,67 +198,17 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Terms">Some useful phrases for you</a></li>
|
||||
<li><a href="#Sample">Sample preparation and analysis</a></li>
|
||||
<li><a href="#Fourier">Fourier transform spectroscope</a></li>
|
||||
<li><a href="#Hyperspectral">Hyperspectral Imager</a></li>
|
||||
</ol>
|
||||
|
||||
<br>
|
||||
<h1><a name="Terms">Some useful phrases for you</a></h1>
|
||||
<list>
|
||||
<li><b>Spectroscopy</b> - Spectroscopy is the study of the behaviour of light, commonly used in the 26th century for analysis of anomalous
|
||||
behaviour of energy or light.</li>
|
||||
<li><b>Sample specifity</b> - A pseudoarbitrary value used to indicate how well a sample resonates with the employed carrier reagent. Great specifity
|
||||
(material resonance) indicates that there is much of the carrier reagent present in the sample.</li>
|
||||
<li><b>Anomalies</b> - Inexplicable or uncategorised occurrences in the cosmos. A fascinating and dangerous study is made to determine the function of
|
||||
these rare finds, and the term is often applied to describe technology left behind by vastly superior ancient alien forerunners.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Sample">Sample preparation and analysis</a></h1>
|
||||
When you are readying your spectrometry lab for analysis, you'll need to make sure the sample is in a form the machines can glean data from.
|
||||
<list>
|
||||
<li><b>Obtain material sample</b> - This should be an ordinary chunk of matter the size of your finger, a good example is a 6mm rock core.</li>
|
||||
<li><b>Run density separation treatment</b> - Perform the DST procedure on your sample, following generic specifications.</li>
|
||||
<li><b>Ensure sample purity</b> - DST can sometimes leave behind chemical waste or chunks of matter, make sure there aren't any before proceeding.</li>
|
||||
<li><b>Prepare analysis tray</b> - A sample tray holds a miniscule amount of liquid (2u), but that's all that our spectrometers require for a good reading.</li>
|
||||
<li><b>Choose carrier reagent</b> - Standard spectrometers require 1u of the material sample, and 1u of a 'carrier' reagent to provide control comparison
|
||||
and to enable refraction inferencing.</li>
|
||||
<li><b>Insert sample tray into machine</b> - And press the 'Go' button. Now go make a cup of coffee.</li>
|
||||
<li><b>Monitor machine heat levels</b> - The upper end mass spectrometers have quite complex internals, and have a tendency to critically overheat.
|
||||
Make sure the heat limit isn't exceeded, or there may be potentially disastrous consequences.</li>
|
||||
<li><b>Examine analysis report</b> - it won't always make sense or provide the information you hoped for, but if you've been careful during DST and ensured
|
||||
sample integrity, then there's always something to be learnt. Just don't lose the paperwork!</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Fourier">Fourier transform spectroscope</a></h1>
|
||||
The FTS measures temporal coherence of radiating energy, then applies time-and-space domain measurements on the collected emission data. The collective
|
||||
procedure is known as the <i>Fourier Transform Procedure,</i> with the mathematical algorithms dating back to the 19th century on Earth.<br>
|
||||
<br>
|
||||
As well as providing background energy readings, an FTS calculates the approximate distance and direction towards any anomalous energy signatures from
|
||||
the location the scanned sample was taken from.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Hyperspectral">Hyperspectral Imager</a></h1>
|
||||
The imager scans and collates spectral energy signatures from across the electromagnetic spectrum. The collected data is then presented to the viewer in
|
||||
graph form, with any anomalous (uncatalogued or unidentified) energy signatures highlighted.<br>
|
||||
<br>
|
||||
As well as visualising background energy readings, a hyperspectral imager will isolate and identify any anomalous energy signatures in the sample.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
It's perhaps one of the most exciting times to be alive, with the recent breakthroughs in understanding and categorisation of things we may one day no longer call
|
||||
'anomalies,' but rather 'infrequent or rare occurrences of certain celestial weather or phenomena.' Perhaps a little more long winded, but no less eloquent all the
|
||||
same! Why, look at the strides we're making in piercing the walls of bluespace or our steadily improving ability to clarify and stabilise subspace emissions; it's
|
||||
certainly an exciting time to be alive. For the moment the Hydrolian hasn't seen two spatial anomalies alike but the day will come and it is soon, I can feel it.
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/materials_chemistry_analysis
|
||||
name = "Chemical preparation for materials analysis"
|
||||
name = "Materials analysis and the chemical implications"
|
||||
icon_state = "chemistry"
|
||||
author = "Jasper Pascal, Senior Lecturer in Materials Analysis at the University of Jol'Nar"
|
||||
title = "Chemical preparation for materials analysis"
|
||||
title = "Materials analysis and the chemical implications"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
@@ -270,70 +221,13 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Terms">Relevant words and their meanings</a></li>
|
||||
<li><a href="#Sample">Sample preparation for spectrometry/spectroscopy</a></li>
|
||||
<li><a href="#DST">Density Separation Treatment</a></li>
|
||||
<li><a href="#Carrier">Choosing a carrier reagent</a></li>
|
||||
</ol>
|
||||
In today's high tech research fields, leaps and bounds are being made every day. Whether it's great strides forward in our understanding of the physical universe
|
||||
or the operation of some fancy new piece of equipment, it seems like all the cool fields are producing new toys to play with leaving doddery old fields such as
|
||||
materials analysis and chemistry relegated to the previous few centuries, when we were still learning the makeup and structure of the elements.<br>
|
||||
<br>
|
||||
<h1><a name="Terms">Relevant words and their meanings</a></h1>
|
||||
<list>
|
||||
<li><b>Dissonance ratio</b> - This is a pseudoarbitrary value indicating the overal presence of a particular element in a greater composite.
|
||||
It takes into account volume, density, molecular excitation and isotope spread.</li>
|
||||
<li><b>Density separation treatment</b> - The DST procedure purifies a sample, removing any unwanted matter to ensure the finest scan resolution possible.</li>
|
||||
<li><b>Mass spectrometry</b> - MS is the procedure used used to measure and quantify the components of matter. The most prized tool in the field of
|
||||
'Materials analysis'</li>
|
||||
<li><b>Spectroscopy</b> - Spectroscopy is the study of the behaviour of light, commonly used in the 26th century for analysis of anomalous
|
||||
behaviour of energy or light.</li>
|
||||
<li><b>Sample specifity</b> - A pseudoarbitrary value used to indicate how well a sample resonates with the employed carrier reagent. Great specifity
|
||||
(material resonance) indicates that there is much of the carrier reagent present in the sample.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Sample">Sample preparation for spectrometry/spectroscopy</a></h1>
|
||||
When you are readying your spectrometry lab for analysis, you'll need to make sure the sample is in a form the machines can glean data from.
|
||||
<list>
|
||||
<li><b>Obtain material sample</b> - This should be an ordinary chunk of matter the size of your finger, a good example is a 6mm rock core.</li>
|
||||
<li><b>Run density separation treatment</b> - Perform the DST procedure on your sample, following generic specifications.</li>
|
||||
<li><b>Ensure sample purity</b> - DST can sometimes leave behind chemical waste or chunks of matter, make sure there aren't any before proceeding.</li>
|
||||
<li><b>Prepare analysis tray</b> - A sample tray holds a miniscule amount of liquid (2u), but that's all that our spectrometers require for a good reading.</li>
|
||||
<li><b>Choose carrier reagent</b> - Standard spectrometers require 1u of the material sample, and 1u of a 'carrier' reagent to provide control comparison
|
||||
and to enable refraction inferencing.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="DST">Density Separation Treatment</a></h1>
|
||||
<list>
|
||||
<li><b>Obtain material sample</b> - This should be an ordinary chunk of matter the size of your finger, a good example is a 6mm rock core.</li>
|
||||
<li><b>Grind material to powder</b> - In order to treat the material, we have to have the sample in it's basest form.</li>
|
||||
<li><b>Prepare separator solution</b> - A chemical solution called LiNa2WO4, or <i>Lithium Sodium Tungstate</i> must be prepared to separate
|
||||
the the denser clumps of matter out of the refined sample. This is done by mixing 1 part lithium, 2 parts sodium, 1 part tungsten, 4 parts oxygen.</li>
|
||||
<li><b>Mix separator with sample</b> - The resulting mixture is very close to the final product, but make sure to extract any leftover reagents and
|
||||
the chemical waste byproduct.</li>
|
||||
<li><b>Bring sample to boil</b> - Using a standard bunsen burner, bring the mixture containing at least 5u of DST to a boil to vaporise the remaining unwanted matter. Remember
|
||||
to again clear out any waste byproducts.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Carrier">Choosing a carrier reagent</a></h1>
|
||||
Below is a list of the most commonly used scan carrier reagents, and the particular molecules they resonate most strongly with:
|
||||
<list>
|
||||
<li><b>Carbon</b> - Trace organic cells, typically used for carbon dating of organic remains.</li>
|
||||
<li><b>Potassium</b> - Long exposure particles floating in the depths of space, such as meteorites.</li>
|
||||
<li><b>Hydrogen</b> - Trace water particles.</li>
|
||||
<li><b>Nitrogen</b> - Crystalline structures.</li>
|
||||
<li><b>Mercury</b> - Metallic derivatives such as ferritic elements and pure metallic substances.</li>
|
||||
<li><b>Iron</b> - Metallic composites such as alloys and atomic structures that are metallic in nature.</li>
|
||||
<li><b>Chlorine</b> - Metamorphic/igneous rock composite.</li>
|
||||
<li><b>Phosphorus</b> - Metamorphic/sedimentary rock composite.</li>
|
||||
<li><b>Plasma</b> - Anomalous materials such as bluespace phased composites that are not fully understood by modern science.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Well, when you're out there building the next gryo-whatsitron or isotope mobility thingummy, remember how the field of archaeology experienced a massive new rebirth
|
||||
following the excavations at Paranol IV and consider how all of the scientific greats will come crawling back to basic paradigms of natural philosophy when they discover
|
||||
a new element that defies classification. I defy you to classify it without reviving this once great field!
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/anomaly_testing
|
||||
@@ -391,10 +285,11 @@
|
||||
matter composites that are spatially fixed relative to the source.<br>
|
||||
<br>
|
||||
By taking samples of such 'fixed' matter, we can apply complex analytics such as the modified Fourier Transform Procedure to reverse engineer the path of the
|
||||
energy, and determine the approximate distance and direction that the energy source is, relative to the sample's point in space.<br>
|
||||
energy, and determine the approximate distance and direction that the energy source is, relative to the sample's point in space. Modern portable devices can do
|
||||
all this purely by taking readings of local radiation.<br>
|
||||
<br>
|
||||
A canny researcher can thusly analyse material samples from pre-chosen points strategically scattered around an area, and if there are any anomalous energy
|
||||
emissions in range of those points, combined they can direct the researcher to the source.<br>
|
||||
A canny researcher can thusly analyse radiationat pre-chosen points strategically scattered around an area, and if there are any anomalous energy
|
||||
emissions in range of those points, combined the researcher can triangulate the source.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Synthetic">Harvesting and utilising anomalous energy signatures</a></h1>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
|
||||
//---- Noticeboard
|
||||
|
||||
/obj/structure/noticeboard/anomaly/New()
|
||||
/obj/structure/noticeboard/anomaly
|
||||
notices = 5
|
||||
icon_state = "nboard05"
|
||||
|
||||
/obj/structure/noticeboard/anomaly/New()
|
||||
//add some memos
|
||||
var/obj/item/weapon/paper/P = new()
|
||||
P.name = "Memo RE: proper analysis procedure"
|
||||
P.info = "Rose,<br>activate <i>then</i> analyse the artifacts, the machine will have a much easier time determining their function/s. Remember to employ basic quasi-elemental forces such as heat, energy, force and various chemical mixes - who knows why those ancient aliens made such obscure activation indices.<br><br>And don't forget your suit this time, I can't afford to have any researchers out of commision for as long as that again!.<br>Ward"
|
||||
P.info = "<br>We keep test dummies in pens here for a reason, so standard procedure should be to activate newfound alien artifacts and place the two in close proximity. Promising items I might even approve monkey testing on."
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
@@ -29,7 +30,7 @@
|
||||
|
||||
P = new()
|
||||
P.name = "READ ME! Before you people destroy any more samples"
|
||||
P.info = "how many times do i have to tell you people, these xeno-arch samples are del-i-cate, and should be handled so! careful application of a focussed, ceoncentrated heat or some corrosive liquids should clear away the extraneous carbon matter, while application of an energy beam will most decidedly destroy it entirely! W, <b>the one who signs your paychecks</b>"
|
||||
P.info = "how many times do i have to tell you people, these xeno-arch samples are del-i-cate, and should be handled so! careful application of a focussed, concentrated heat or some corrosive liquids should clear away the extraneous carbon matter, while application of an energy beam will most decidedly destroy it entirely - like someone did to the chemical dispenser! W, <b>the one who signs your paychecks</b>"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
/obj/item/device/ano_scanner
|
||||
name = "Alden-Saraspova counter"
|
||||
desc = "Aids in triangulation of exotic particles."
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "flashgun"
|
||||
item_state = "lampgreen"
|
||||
w_class = 1.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
var/nearest_artifact_id = "unknown"
|
||||
var/nearest_artifact_distance = -1
|
||||
var/last_scan_time = 0
|
||||
|
||||
/obj/item/device/ano_scanner/New()
|
||||
..()
|
||||
spawn(0)
|
||||
scan()
|
||||
|
||||
/obj/item/device/ano_scanner/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
|
||||
/obj/item/device/ano_scanner/interact(var/mob/user as mob)
|
||||
var/message = "Background radiation levels detected."
|
||||
if(nearest_artifact_distance >= 0)
|
||||
message = "Exotic energy detected on wavelength '[nearest_artifact_id]' in a radius of [nearest_artifact_distance * 2]m"
|
||||
user << "<span class='info'>[message]</span>"
|
||||
if(world.time - last_scan_time > 50)
|
||||
spawn(0)
|
||||
scan()
|
||||
|
||||
/obj/item/device/ano_scanner/proc/scan()
|
||||
set background = 1
|
||||
|
||||
last_scan_time = world.time
|
||||
nearest_artifact_distance = -1
|
||||
for(var/turf/simulated/mineral/T in artifact_spawning_turfs)
|
||||
if(T.artifact_find && T.z == src.z)
|
||||
var/cur_dist = get_dist(src.loc, T)
|
||||
if(nearest_artifact_distance < 0 || cur_dist < nearest_artifact_distance)
|
||||
nearest_artifact_distance = cur_dist + rand() * 2 - 1
|
||||
nearest_artifact_id = T.artifact_find.artifact_id
|
||||
src.visible_message("\icon[src] <span class='info>[src] clicks.</span>")
|
||||
@@ -37,17 +37,19 @@
|
||||
D.record_index = positive_locations.len + 1
|
||||
D.material = M.mineralName
|
||||
|
||||
//find whichever is closer: find or mineral
|
||||
//find the first artifact and store it
|
||||
if(M.finds.len)
|
||||
var/datum/find/F = M.finds[1]
|
||||
D.depth = F.excavation_required * 2
|
||||
D.depth = F.excavation_required * 2 //0-100% and 0-200cm
|
||||
D.clearance = F.clearance_range * 2
|
||||
D.material = get_responsive_reagent(F.find_type)
|
||||
|
||||
//check if there are minerals interfering with the scan
|
||||
if(M.excavation_minerals.len)
|
||||
if(M.excavation_minerals[1] < D.depth)
|
||||
if(!D.depth || M.excavation_minerals[1] < D.depth)
|
||||
D.depth = M.excavation_minerals[1]
|
||||
D.clearance = rand(2,6)
|
||||
D.dissonance_spread = rand(1,1000) / 100
|
||||
D.clearance = rand() * 4 + 1
|
||||
D.material = M.mineralName
|
||||
|
||||
positive_locations.Add(D)
|
||||
|
||||
@@ -71,7 +73,7 @@
|
||||
positive_locations.Add(D)
|
||||
|
||||
for(var/mob/L in range(src, 1))
|
||||
L << "\blue \icon[src] [src] pings [pick("madly","wildly","excitedly","crazily")]."
|
||||
L << "\blue \icon[src] [src] pings [pick("madly","wildly","excitedly","crazily")]!."
|
||||
|
||||
/obj/item/device/depth_scanner/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
@@ -85,7 +87,11 @@
|
||||
dat += "Anomaly depth: [current.depth] cm<br>"
|
||||
dat += "Clearance above anomaly depth: [current.clearance] cm<br>"
|
||||
dat += "Dissonance spread: [current.dissonance_spread]<br>"
|
||||
dat += "Anomaly material: [current.material]<br>"
|
||||
var/index = responsive_carriers.Find(current.material)
|
||||
if(index > 0 && index <= finds_as_strings.len)
|
||||
dat += "Anomaly material: [finds_as_strings[index]]<br>"
|
||||
else
|
||||
dat += "Anomaly material: Unknown<br>"
|
||||
dat += "<A href='?src=\ref[src];clear=[current.record_index]'>clear entry</a><br>"
|
||||
else
|
||||
dat += "Select an entry from the list<br>"
|
||||
|
||||
Reference in New Issue
Block a user