diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm index 1e5740ed8e0..57f1bc4be6e 100644 --- a/code/game/machinery/floodlight.dm +++ b/code/game/machinery/floodlight.dm @@ -6,66 +6,58 @@ icon_state = "flood00" density = 1 var/on = 0 - var/obj/item/weapon/cell/cell = null - var/use = 1 + var/obj/item/weapon/cell/high/cell = null + var/use = 5 var/unlocked = 0 var/open = 0 + var/brightness_on = 999 //can't remember what the maxed out value is + +/obj/machinery/floodlight/New() + src.cell = new(src) + ..() /obj/machinery/floodlight/proc/updateicon() icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]" /obj/machinery/floodlight/process() - if (!on) - if (luminosity) + if(on) + cell.charge -= use + if(cell.charge <= 0) + on = 0 updateicon() - //sd_SetLuminosity(0) - return - - if(!luminosity && cell && cell.charge > 0) - //sd_SetLuminosity(10) - updateicon() - - if(!cell && luminosity) - on = 0 - updateicon() - //sd_SetLuminosity(0) - return - - cell.charge -= use - - if(cell.charge <= 0 && luminosity) - on = 0 - updateicon() - //sd_SetLuminosity(0) - return + SetLuminosity(0) + src.visible_message("[src] shuts down due to lack of power!") + return /obj/machinery/floodlight/attack_hand(mob/user as mob) if(open && cell) - cell.loc = usr - cell.layer = 20 - if (user.hand ) - user.l_hand = cell + if(ishuman(user)) + if(!user.get_active_hand()) + user.put_in_hands(cell) + cell.loc = user.loc else - user.r_hand = cell + cell.loc = loc cell.add_fingerprint(user) - updateicon() cell.updateicon() src.cell = null user << "You remove the power cell" + updateicon() return if(on) on = 0 - user << "You turn off the light" + user << "\blue You turn off the light" + SetLuminosity(0) else if(!cell) return if(cell.charge <= 0) return on = 1 - user << "You turn on the light" + user << "\blue You turn on the light" + SetLuminosity(brightness_on) updateicon() @@ -101,10 +93,3 @@ cell = W user << "You insert the power cell." updateicon() - -/obj/machinery/floodlight/New() - src.cell = new/obj/item/weapon/cell(src) - cell.maxcharge = 1000 - cell.charge = 1000 - ..() - diff --git a/code/modules/research/xenoarchaeology/analysis.dm b/code/modules/research/xenoarchaeology/analysis.dm index c864915d3a4..0d2579191ec 100644 --- a/code/modules/research/xenoarchaeology/analysis.dm +++ b/code/modules/research/xenoarchaeology/analysis.dm @@ -5,12 +5,10 @@ // var/obj/item/weapon/reagent_containers/glass/held_container var/obj/item/weapon/tank/fuel_container - var/scan_time = 30 //change to 300 later + var/target_scan_ticks = 60 var/report_num = 0 - var/scanning = 0 - var/safety_enabled = 1 - var/warning_given = 0 - var/heat_accumulation_rate = 0 + var/scan_process = 0 + var/heat_accumulation_rate = 1 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 @@ -18,6 +16,7 @@ var/obj/machinery/anomaly/scanner/owned_scanner = null /obj/machinery/anomaly/New() + ..() //connect to a nearby scanner pad if(scanner_dir) owned_scanner = locate(/obj/machinery/anomaly/scanner) in get_step(src, scanner_dir) @@ -32,6 +31,49 @@ S.reagents.add_reagent("analysis_sample", 1, D.geological_data) S.reagents.add_reagent("chlorine", 1, D.geological_data) +/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() + + //heat up as we go, but if the air is freezing then heat up much slower + var/new_heat = heat_accumulation_rate + heat_accumulation_rate * rand(-5,5) / 10 + if(environmental_temp < temperature) + new_heat *= 0.75 + temperature += new_heat + 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(10)) + src.visible_message("\blue \icon[src] [pick("whirrs","chuffs","clicks")][pick(" quietly"," softly"," sadly"," excitedly"," energetically"," angrily"," plaintively")].", 2) + + else if(temperature > environmental_temp) + //cool down to match the air + temperature -= heat_accumulation_rate + heat_accumulation_rate * rand(-5,5) / 10 + if(temperature < environmental_temp) + temperature = environmental_temp + if(prob(10)) + src.visible_message("\blue \icon[src] hisses softly.", 2) + + else if(temperature < environmental_temp) + //heat up to match the air + temperature += heat_accumulation_rate + rand(-5,5) / 10 + if(temperature > environmental_temp) + temperature = environmental_temp + else + if(prob(10)) + src.visible_message("\blue \icon[src] plinks quietly.", 2) + + //warm up the lab slightly + if(env.temperature < temperature) + env.temperature += (temperature - env.temperature) * 0.1 + //this proc should be overriden by each individual machine /obj/machinery/anomaly/attack_hand(var/mob/user as mob) if(stat & (NOPOWER|BROKEN)) @@ -42,7 +84,7 @@ dat += "Module heat level: [temperature] kelvin
" dat += "Safeties set at 600k, shielding failure at 1200k. Failure to maintain safe heat levels may result in equipment damage.
" dat += "
" - if(scanning) + if(scan_process) dat += "Scan in progress


" else dat += "[held_container ? "Eject beaker" : "No beaker inserted."]
" @@ -79,58 +121,28 @@ obj/machinery/anomaly/attackby(obj/item/weapon/W as obj, mob/living/user as mob) else return ..() -/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(scanning) - //heat up as we go, but if the air is freezing then heat up much slower - var/new_heat = heat_accumulation_rate + heat_accumulation_rate * rand(-0.5,0.5) - if(environmental_temp < 273) - new_heat /= 2 - temperature += new_heat - if(temperature >= 600) - if(!warning_given || temperature >= 1200) - src.visible_message("The [src] bleets.", 2) - warning_given = 1 - if(safety_enabled) - scanning = 0 - else if(temperature > environmental_temp) - //cool down to match the air - temperature -= 10 + rand(-5,5) - if(temperature < environmental_temp) - temperature = environmental_temp - else if(temperature < environmental_temp) - //heat up to match the air - temperature += 10 + rand(-5,5) - if(temperature > environmental_temp) - temperature = environmental_temp - obj/machinery/anomaly/proc/ScanResults() //instantiate in children to produce unique scan behaviour return "\red Error initialising scanning components." -obj/machinery/anomaly/proc/BeginScan() - var/total_scan_time = scan_time + scan_time * rand(-0.5, 0.5) +obj/machinery/anomaly/proc/FinishScan() + scan_process = 0 + updateDialog() - scanning = 1 - spawn(total_scan_time) - if(scanning) - scanning = 0 - updateDialog() - - //determine the results and print a report - if(held_container) - src.visible_message("\icon[src] makes an insistent chime.", 2) - var/obj/item/weapon/paper/P = new(src.loc) - P.name = "[src] report #[++report_num]" - P.info = "[src] analysis report #[report_num]

" + ScanResults() - P.stamped = list(/obj/item/weapon/stamp) - P.overlays = list("paper_stamped") - else - src.visible_message("\icon[src] makes a low buzzing noise.", 2) + //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 = "[src] analysis report #[report_num]

" + 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 @@ -141,34 +153,24 @@ obj/machinery/anomaly/Topic(href, href_list) fuel_container.loc = src.loc fuel_container = null if(href_list["begin"]) - if(temperature >= 600) + if(temperature >= 300) var/proceed = input("Unsafe internal temperature detected, do you wish to continue?","Warning") - if(proceed) - if(get_dist(src, usr) <= 1) - safety_enabled = 0 - BeginScan() - else - usr << "\red You must be closer to the [src]!" + if(proceed && get_dist(src, usr) <= 1) + scan_process = 1 else - BeginScan() + scan_process = 1 - ..() - updateDialog() + 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/datum/reagent/carrier) +obj/machinery/anomaly/proc/GetResultSpecifity(var/datum/geosample/scanned_sample, var/carrier) var/specifity = 0 - var/remaining = 1 if(scanned_sample && carrier) - for(var/index=1,index <= scanned_sample.find_presence.len, index++) - var/find = scanned_sample.find_presence[index] - if(find && responsive_carriers[index] == carrier) - specifity += 0.5 * remaining + rand(0, 0.25 * remaining) - remaining = 1 - specifity - - if(!specifity) - specifity += rand(0, 0.5) + if(scanned_sample.find_presence.Find(carrier)) + specifity = 0.7 * (scanned_sample.find_presence[carrier] / scanned_sample.total_spread) + 0.3 + else + specifity = rand(0, 0.5) return specifity diff --git a/code/modules/research/xenoarchaeology/analysis_fourier_transform.dm b/code/modules/research/xenoarchaeology/analysis_fourier_transform.dm index 7a402fdcd99..5e952c00bbd 100644 --- a/code/modules/research/xenoarchaeology/analysis_fourier_transform.dm +++ b/code/modules/research/xenoarchaeology/analysis_fourier_transform.dm @@ -33,9 +33,9 @@ obj/machinery/anomaly/fourier_transform/ScanResults() distance += distance * rand(-100 * offset, 100 * offset) / 100 accuracy = specifity results = "Fourier transform analysis on anomalous energy absorption through carrier ([carrier]) indicates source located inside emission radius ([100 * accuracy]% accuracy): [distance]." - if(carrier == scanned_sample.source_mineral) - results += "
Warning, analysis may be contaminated by high quantities of molecular carrier present throughout sample." else - results = "Standard energy dispersion detected throughout sample." + results = "Energy dispersion detected throughout sample consistent with background readings.
" + if(carrier == scanned_sample.source_mineral) + results += "Warning, analysis may be contaminated by high quantities of molecular carrier present throughout sample." return results diff --git a/code/modules/research/xenoarchaeology/analysis_ion_mobility.dm b/code/modules/research/xenoarchaeology/analysis_ion_mobility.dm index 221b4417b51..cdc388d7c87 100644 --- a/code/modules/research/xenoarchaeology/analysis_ion_mobility.dm +++ b/code/modules/research/xenoarchaeology/analysis_ion_mobility.dm @@ -22,15 +22,24 @@ obj/machinery/anomaly/ion_mobility/ScanResults() 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 following composition:

" + results = "Kinetic analysis on sample's ionic residue in carrier ([carrier]) indicates the dissonance spread:

" 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]
" + 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]%
" found++ + */ if(!found) - results = "Kinetic analysis on sample's ionic residue in carrier ([carrier]) to determine composition were inconclusive." + results = "Kinetic analysis on sample's ionic residue in carrier ([carrier]) to determine composition were inconclusive.
" + if(carrier == scanned_sample.source_mineral) + results += "Warning, analysis may be contaminated by high quantities of molecular carrier present throughout sample." return results diff --git a/code/modules/research/xenoarchaeology/suspension_generator.dm b/code/modules/research/xenoarchaeology/suspension_generator.dm new file mode 100644 index 00000000000..3c1449f6b49 --- /dev/null +++ b/code/modules/research/xenoarchaeology/suspension_generator.dm @@ -0,0 +1,324 @@ +//these are probably broken + +/obj/machinery/suspension_gen + name = "suspension field generator" + desc = "It has stubby legs bolted up against it's body for stabilising." + icon = 'xenoarchaeology.dmi' + icon_state = "suspension2" + density = 1 + req_access = list(access_research) + var/obj/item/weapon/cell/cell + var/obj/item/weapon/card/id/auth_card + var/locked = 1 + var/open = 0 + var/screwed = 1 + var/field_type = "" + var/power_use = 25 + var/obj/effect/suspension_field/suspension_field + var/list/secured_mobs = list() + +/obj/machinery/suspension_gen/New() + src.cell = new/obj/item/weapon/cell/high(src) + ..() + +/obj/machinery/suspension_gen/process() + set background = 1 + + if (suspension_field) + cell.charge -= power_use + + var/turf/T = get_turf(suspension_field) + if(field_type == "carbon") + for(var/mob/living/carbon/M in T) + M.weakened = max(M.weakened, 3) + cell.charge -= power_use + if(prob(10)) + M << "\blue [pick("You feel tingly.","You feel like floating.","It is hard to speak.","You can barely move.")]" + + if(field_type == "silicon") + for(var/mob/living/silicon/M in T) + M.weakened = max(M.weakened, 3) + cell.charge -= power_use + if(prob(10)) + M << "\blue [pick("You feel tingly.","You feel like floating.","It is hard to speak.","You can barely move.")]" + + for(var/obj/item/I in T) + if(!suspension_field.contents.len) + suspension_field.icon_state = "energynet" + suspension_field.overlays += "shield2" + I.loc = suspension_field + + for(var/mob/living/simple_animal/M in T) + M.weakened = max(M.weakened, 3) + cell.charge -= power_use + if(prob(10)) + M << "\blue [pick("You feel tingly.","You feel like floating.","It is hard to speak.","You can barely move.")]" + + if(cell.charge <= 0) + deactivate() + +/obj/machinery/suspension_gen/interact(mob/user as mob) + var/dat = "Multi-phase mobile suspension field generator MK II \"Steadfast\"
" + if(cell) + var/colour = "red" + if(cell.charge / cell.maxcharge > 0.66) + colour = "green" + else if(cell.charge / cell.maxcharge > 0.33) + colour = "orange" + dat += "Energy cell: [100 * cell.charge / cell.maxcharge]%
" + else + dat += "Energy cell: None
" + if(auth_card) + dat += "\[[auth_card]\]
" + if(!locked) + dat += "
[suspension_field ? "Disable" : "Enable"] field
" + else + dat += "
" + else + dat += "\[------\]
" + if(!locked) + dat += "
[suspension_field ? "Disable" : "Enable"] field
" + else + dat += "Enter your ID to begin.
" + + dat += "
" + if(!locked) + dat += "Select field mode
" + dat += "[field_type=="carbon"?"":"" ]Diffracted CO2 laser
" + dat += "[field_type=="helium"?"":"" ]Helium tracer field
" + dat += "[field_type=="beryllium"?"":"" ]Beryllium dispersion wave
" + dat += "[field_type=="neon"?"":"" ]Neon refrigerant cloud
" + dat += "[field_type=="aluminium"?"":"" ]Aluminium transmitted field
" + dat += "[field_type=="silicon"?"":"" ]Silicon wafer conduction
" + dat += "[field_type=="calcium"?"":"" ]Calcium binary deoxidiser
" + else + dat += "
" + dat += "
" + dat += "
" + dat += "
" + dat += "
" + dat += "
" + dat += "
" + dat += "
" + dat += "
" + dat += "Always wear safety gear and consult a field manual before operation.
" + if(!locked) + dat += "Lock console
" + else + dat += "
" + dat += "Refresh console
" + dat += "Close console" + user << browse(dat, "window=suspension;size=500x400") + onclose(user, "suspension") + +/obj/machinery/suspension_gen/Topic(href, href_list) + ..() + usr.set_machine(src) + + if(href_list["toggle_field"]) + if(!suspension_field) + if(cell.charge > 0) + if(anchored) + activate() + else + usr << "You are unable to activate [src] until it is properly secured on the ground." + else + deactivate() + if(href_list["select_field"]) + field_type = href_list["select_field"] + else if(href_list["insertcard"]) + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/weapon/card)) + usr.drop_item() + I.loc = src + auth_card = I + if(attempt_unlock(I)) + usr << "You insert [I], the console flashes \'Access granted.\'" + else + usr << "You insert [I], the console flashes \'Access denied.\'" + else if(href_list["ejectcard"]) + if(auth_card) + if(ishuman(usr)) + auth_card.loc = usr.loc + if(!usr.get_active_hand()) + usr.put_in_hands(auth_card) + auth_card = null + else + auth_card.loc = loc + auth_card = null + else if(href_list["lock"]) + locked = 1 + else if(href_list["close"]) + usr.unset_machine() + usr << browse(null, "window=suspension") + + updateUsrDialog() + +/obj/machinery/suspension_gen/attack_hand(mob/user as mob) + if(!open) + interact(user) + else if(cell) + cell.loc = loc + cell.add_fingerprint(user) + cell.updateicon() + + icon_state = "suspension0" + cell = null + user << "You remove the power cell" + +/obj/machinery/suspension_gen/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/screwdriver)) + if(!open) + if(screwed) + screwed = 0 + else + screwed = 1 + user << "You [screwed ? "screw" : "unscrew"] the battery panel." + else if (istype(W, /obj/item/weapon/crowbar)) + if(!locked) + if(!screwed) + if(!suspension_field) + if(open) + open = 0 + else + open = 1 + user << "You crowbar the battery panel [open ? "open" : "in place"]." + icon_state = "suspension[open ? (cell ? "1" : "0") : "2"]" + else + user << "[src]'s safety locks are engaged, shut it down first." + else + user << "Unscrew [src]'s battery panel first." + else + user << "[src]'s security locks are engaged." + else if (istype(W, /obj/item/weapon/wrench)) + if(!suspension_field) + if(anchored) + anchored = 0 + else + anchored = 1 + user << "You wrench the stabilising legs [anchored ? "into place" : "up against the body"]." + if(anchored) + desc = "It is resting securely on four stubby legs." + else + desc = "It has stubby legs bolted up against it's body for stabilising." + else + user << "You are unable to secure [src] while it is active!" + else if (istype(W, /obj/item/weapon/cell)) + if(open) + if(cell) + user << "There is a power cell already installed." + else + user.drop_item() + W.loc = src + cell = W + user << "You insert the power cell." + icon_state = "suspension1" + else if(istype(W, /obj/item/weapon/card)) + var/obj/item/weapon/card/I = W + if(!auth_card) + if(attempt_unlock(I)) + user << "You swipe [I], the console flashes \'Access granted.\'" + else + user << "You swipe [I], console flashes \'Access denied.\'" + else + user << "Remove [auth_card] first." + +/obj/machinery/suspension_gen/proc/attempt_unlock(var/obj/item/weapon/card/C) + if(!open) + if(istype(C, /obj/item/weapon/card/emag) && cell.charge > 0) + //put sparks here + if(prob(95)) + locked = 0 + else if(istype(C, /obj/item/weapon/card/id) && check_access(C)) + locked = 0 + + if(!locked) + return 1 + +//checks for whether the machine can be activated or not should already have occurred by this point +/obj/machinery/suspension_gen/proc/activate() + //depending on the field type, we might pickup certain items + var/turf/T = get_turf(get_step(src,dir)) + var/success = 0 + var/collected = 0 + switch(field_type) + if("carbon") + success = 1 + for(var/mob/living/carbon/C in T) + C.weakened += 5 + C.visible_message("\blue \icon[C] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.") + if("helium") + success = 1 + // + if("beryllium") + success = 1 + // + if("neon") + success = 1 + // + if("aluminium") + success = 1 + // + if("silicon") + success = 1 + for(var/mob/living/silicon/R in T) + R.weakened += 5 + R.visible_message("\blue \icon[R] [R] begins to float in the air!","You feel tingly and light, but it is difficult to move.") + if("calcium") + success = 1 + // + //in case we have a bad field type + if(!success) + return + + for(var/mob/living/simple_animal/C in T) + C.visible_message("\blue \icon[C] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.") + C.weakened += 5 + + suspension_field = new(T) + suspension_field.field_type = field_type + src.visible_message("\blue \icon[src] [src] activates with a low hum.") + icon_state = "suspension3" + + for(var/obj/item/I in T) + I.loc = suspension_field + collected++ + + if(collected) + suspension_field.icon_state = "energynet" + suspension_field.overlays += "shield2" + src.visible_message("\blue \icon[suspension_field] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].") + else + if(istype(T,/turf/simulated/mineral) || istype(T,/turf/simulated/wall)) + suspension_field.icon_state = "shieldsparkles" + else + suspension_field.icon_state = "shield2" + +/obj/machinery/suspension_gen/proc/deactivate() + //drop anything we picked up + var/turf/T = get_turf(suspension_field) + + for(var/mob/M in T) + M << "You no longer feel like floating." + M.weakened = min(M.weakened, 3) + + src.visible_message("\blue \icon[src] [src] deactivates with a gentle shudder.") + del(suspension_field) + icon_state = "suspension2" + +/obj/machinery/suspension_gen/Del() + //safety checks: clear the field and drop anything it's holding + deactivate() + ..() + +/obj/effect/suspension_field + name = "energy field" + icon = 'icons/effects/effects.dmi' + anchored = 1 + density = 1 + var/field_type = "calcium" + +/obj/effect/suspension_field/Del() + for(var/obj/I in src) + I.loc = src.loc + ..()