mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 12:29:46 +01:00
Integrated Circuitry Miniupdate (#21971)
- Updates the **medical analysers** to get health values significant to Brainmed instead of Pointmed. About 6 years late? - Adds a **radiation scanner**. - Adds a **light scanner**. - Adds a **custom ticker** that can be calibrated between 2 (fast ticker equivalent) and 600 seconds. - Adds a **face scanner** that can get basic information about humanoids, including: name (same as an examiner), general flavourtext, face flavourtext, species, height, estimated age, and eye colour. Has applications for species-specific circuitry, identity confirmation, or flavour usage. - Adds a **flasher** that functions similarly to the **shocker**, but applies a non-weakening/non-stunning flash instead. Shocker nerfed to have much higher power draw, which the flasher also mimics. - Redid all of the **tickers** to actually use seconds (as advertised in their descriptions). Their intervals have also been changed to be more significant: 10-secs, 30-secs, 5-mins, 2-secs (upgraded printer only), custom 2sec to 10mins (upgraded printer only). - Adds an **Alden-Saraspova counter circuit**. Scans only immediate (in-view) surroundings for mineral deposits with artefacts inside and returns a distance. - Adds a **bluespace portal circuit**. Consumes bluespace crystals (either tear apart Telescience OR get high tech levels + every material) to open a portal with a destination based on a supplied *direction* and *power*. Worse than telescience in every way (5x5m variance; cardinal/ordinals only; no cross z-level teleporting; 1-way; BUT it's portable!) - Adds a **bubble shield circuit**. Relies on relative coordinate inputs to generate a low health shield. Max range of 3 tiles. Max lifespan of 60 seconds. Can only project 3 shields at a time. **To-Do:** - [x] Test everything - [x] Add any other quick requests before I hit review - [x] Fuck around with circuits ingame for a bit to figure out any other gaps - [x] Test everything again --------- Signed-off-by: c#min7 <sadkermit01@gmail.com> Co-authored-by: SleepyGemmy <99297919+SleepyGemmy@users.noreply.github.com>
This commit is contained in:
@@ -102,8 +102,13 @@
|
||||
complexity = 4
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"total health %" = IC_PINTYPE_NUMBER,
|
||||
"total missing health" = IC_PINTYPE_NUMBER
|
||||
// Basic medical analyser stuff
|
||||
"brain activity" = IC_PINTYPE_NUMBER,
|
||||
"heart pulse" = IC_PINTYPE_NUMBER,
|
||||
"blood pressure" = IC_PINTYPE_LIST,
|
||||
"blood oxygenation" = IC_PINTYPE_NUMBER,
|
||||
"body temperature" = IC_PINTYPE_NUMBER,
|
||||
"in cardiac arrest?" = IC_PINTYPE_BOOLEAN,
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
@@ -114,12 +119,18 @@
|
||||
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
|
||||
var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100
|
||||
var/missing_health = H.getMaxHealth() - H.health
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, total_health)
|
||||
set_pin_data(IC_OUTPUT, 2, missing_health)
|
||||
if(H.isSynthetic() || H.is_diona()) // incompatible anatomy
|
||||
return
|
||||
|
||||
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
|
||||
// Basic medical analyser stuff
|
||||
set_pin_data(IC_OUTPUT, 1, H.get_brain_result())
|
||||
set_pin_data(IC_OUTPUT, 2, H.get_pulse_as_number(GETPULSE_TOOL))
|
||||
set_pin_data(IC_OUTPUT, 3, H.blood_pressure())
|
||||
set_pin_data(IC_OUTPUT, 4, H.get_blood_oxygenation())
|
||||
set_pin_data(IC_OUTPUT, 5, H.bodytemperature)
|
||||
set_pin_data(IC_OUTPUT, 6, H.is_asystole())
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -132,13 +143,19 @@
|
||||
complexity = 12
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"total health %" = IC_PINTYPE_NUMBER,
|
||||
"total missing health" = IC_PINTYPE_NUMBER,
|
||||
"brute damage" = IC_PINTYPE_NUMBER,
|
||||
"burn damage" = IC_PINTYPE_NUMBER,
|
||||
"tox damage" = IC_PINTYPE_NUMBER,
|
||||
"oxy damage" = IC_PINTYPE_NUMBER,
|
||||
"clone damage" = IC_PINTYPE_NUMBER
|
||||
// Basic medical analyser stuff
|
||||
"brain activity" = IC_PINTYPE_NUMBER,
|
||||
"heart pulse" = IC_PINTYPE_NUMBER,
|
||||
"blood pressure" = IC_PINTYPE_LIST,
|
||||
"blood oxygenation" = IC_PINTYPE_NUMBER,
|
||||
"body temperature" = IC_PINTYPE_NUMBER,
|
||||
"in cardiac arrest?" = IC_PINTYPE_BOOLEAN,
|
||||
// Advanced
|
||||
"brute damage" = IC_PINTYPE_NUMBER,
|
||||
"burn damage" = IC_PINTYPE_NUMBER,
|
||||
"toxin damage" = IC_PINTYPE_NUMBER,
|
||||
"radiation dose" = IC_PINTYPE_NUMBER,
|
||||
"genetic instability" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
@@ -149,17 +166,24 @@
|
||||
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
|
||||
var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100
|
||||
var/missing_health = H.getMaxHealth() - H.health
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, total_health)
|
||||
set_pin_data(IC_OUTPUT, 2, missing_health)
|
||||
set_pin_data(IC_OUTPUT, 3, H.getBruteLoss())
|
||||
set_pin_data(IC_OUTPUT, 4, H.getFireLoss())
|
||||
set_pin_data(IC_OUTPUT, 5, H.getToxLoss())
|
||||
set_pin_data(IC_OUTPUT, 6, H.getOxyLoss())
|
||||
set_pin_data(IC_OUTPUT, 7, H.getCloneLoss())
|
||||
if(H.isSynthetic() || H.is_diona()) // incompatible anatomy
|
||||
return
|
||||
|
||||
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
|
||||
// Basic medical analyser stuff
|
||||
set_pin_data(IC_OUTPUT, 1, H.get_brain_result())
|
||||
set_pin_data(IC_OUTPUT, 2, H.get_pulse_as_number(GETPULSE_TOOL))
|
||||
set_pin_data(IC_OUTPUT, 3, H.blood_pressure())
|
||||
set_pin_data(IC_OUTPUT, 4, H.get_blood_oxygenation())
|
||||
set_pin_data(IC_OUTPUT, 5, H.bodytemperature)
|
||||
set_pin_data(IC_OUTPUT, 6, H.is_asystole())
|
||||
// Advanced
|
||||
set_pin_data(IC_OUTPUT, 7, H.getBruteLoss())
|
||||
set_pin_data(IC_OUTPUT, 8, H.getFireLoss())
|
||||
set_pin_data(IC_OUTPUT, 9, H.getToxLoss())
|
||||
set_pin_data(IC_OUTPUT, 10, H.total_radiation)
|
||||
set_pin_data(IC_OUTPUT, 11, H.getCloneLoss())
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -532,7 +556,7 @@
|
||||
GAS_DEUTERIUM = IC_PINTYPE_NUMBER,
|
||||
GAS_TRITIUM = IC_PINTYPE_NUMBER,
|
||||
GAS_HELIUM = IC_PINTYPE_NUMBER,
|
||||
GAS_HELIUMFUE = IC_PINTYPE_NUMBER,
|
||||
GAS_HELIUMFUEL = IC_PINTYPE_NUMBER,
|
||||
GAS_SULFUR = IC_PINTYPE_NUMBER,
|
||||
GAS_NO2 = IC_PINTYPE_NUMBER,
|
||||
GAS_CHLORINE = IC_PINTYPE_NUMBER,
|
||||
@@ -760,9 +784,6 @@
|
||||
var/gas_display_name = GAS_OXYGEN
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/Initialize()
|
||||
name = "[gas_display_name] sensor"
|
||||
displayed_name = "[gas_display_name] sensor"
|
||||
desc = "A tiny [gas_display_name] sensor module similar to that found in a PDA atmosphere analyser."
|
||||
outputs = list(
|
||||
gas_name = IC_PINTYPE_NUMBER
|
||||
)
|
||||
@@ -785,50 +806,86 @@
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/co2
|
||||
name = "carbon dioxide sensor"
|
||||
displayed_name = "carbon dioxide sensor"
|
||||
desc = "A tiny carbon dioxide sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_CO2
|
||||
gas_display_name = "carbon dioxide"
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/nitrogen
|
||||
name = "nitrogen sensor"
|
||||
displayed_name = "nitrogen sensor"
|
||||
desc = "A tiny nitrogen sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_NITROGEN
|
||||
gas_display_name = "nitrogen"
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/phoron
|
||||
name = "phoron sensor"
|
||||
displayed_name = "phoron sensor"
|
||||
desc = "A tiny phoron sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_PHORON
|
||||
gas_display_name = GAS_PHORON
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/hydrogen_level
|
||||
name = "hydrogen sensor"
|
||||
displayed_name = "hydrogen sensor"
|
||||
desc = "A tiny hydrogen sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_HYDROGEN
|
||||
gas_display_name = GAS_HYDROGEN
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/deuterium_level
|
||||
name = "deuterium sensor"
|
||||
displayed_name = "deuterium sensor"
|
||||
desc = "A tiny deuterium sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_DEUTERIUM
|
||||
gas_display_name = GAS_DEUTERIUM
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/tritium_level
|
||||
name = "tritium sensor"
|
||||
displayed_name = "tritium sensor"
|
||||
desc = "A tiny tritium sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_TRITIUM
|
||||
gas_display_name = GAS_TRITIUM
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/helium_level
|
||||
name = "helium sensor"
|
||||
displayed_name = "helium sensor"
|
||||
desc = "A tiny helium sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_HELIUM
|
||||
gas_display_name = GAS_HELIUM
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/helium3_level
|
||||
name = "helium-3 sensor"
|
||||
displayed_name = "helium-3 sensor"
|
||||
desc = "A tiny helium-3 sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_HELIUMFUEL
|
||||
gas_display_name = GAS_HELIUMFUEL
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/sulfurdioxide_level
|
||||
name = "sulphur dioxide sensor"
|
||||
displayed_name = "sulphur dioxide sensor"
|
||||
desc = "A tiny sulphur dioxide sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_SULFUR
|
||||
gas_display_name = GAS_SULFUR
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/nitrogendioxide_level
|
||||
name = "nitrogen dioxide sensor"
|
||||
displayed_name = "nitrogen dioxide sensor"
|
||||
desc = "A tiny nitrogen dioxide sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_NO2
|
||||
gas_display_name = GAS_NO2
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/chlorine_level
|
||||
name = "chlorine sensor"
|
||||
displayed_name = "chlorine sensor"
|
||||
desc = "A tiny chlorine sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_CHLORINE
|
||||
gas_display_name = GAS_CHLORINE
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/watervapor_level
|
||||
name = "water vapour sensor"
|
||||
displayed_name = "water vapour sensor"
|
||||
desc = "A tiny water vapour sensor module similar to that found in a PDA atmosphere analyser."
|
||||
gas_name = GAS_WATERVAPOR
|
||||
gas_display_name = GAS_WATERVAPOR
|
||||
|
||||
@@ -1073,3 +1130,129 @@
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/input/radiation_sensor
|
||||
name = "radiation sensor"
|
||||
desc = "A tiny radiation sensor module similar to that found in a geiger counter."
|
||||
icon_state = "medscan_adv"
|
||||
complexity = 3
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"radiation" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3)
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/input/radiation_sensor/do_work()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T)) //Invalid input
|
||||
return
|
||||
|
||||
var/radiation_count = SSradiation.get_rads_at_turf(get_turf(src))
|
||||
|
||||
if(radiation_count)
|
||||
set_pin_data(IC_OUTPUT, 1, round(radiation_count,0.1))
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, 0)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/input/light_sensor
|
||||
name = "light sensor"
|
||||
desc = "A tiny light sensor module."
|
||||
icon_state = "medscan_adv"
|
||||
complexity = 3
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"lumens" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3)
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/input/light_sensor/do_work()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T)) //Invalid input
|
||||
return
|
||||
|
||||
var/lumens = T.get_lumcount(0, 3) * 5
|
||||
if(lumens)
|
||||
set_pin_data(IC_OUTPUT, 1, round(lumens,0.1))
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, 0)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/input/face_scanner
|
||||
name = "face scanner"
|
||||
desc = "A complex camera and in-built scanner, similar to an examiner but specifically for people.\
|
||||
It can identify species type, height and eye colour, and it can estimate age (to the half-decade).\
|
||||
It also provides a short description of the person and their face (if able)."
|
||||
icon_state = "video_camera"
|
||||
complexity = 12
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"name" = IC_PINTYPE_STRING,
|
||||
"description (general)" = IC_PINTYPE_STRING,
|
||||
"description (face)" = IC_PINTYPE_STRING,
|
||||
"species" = IC_PINTYPE_STRING,
|
||||
"height" = IC_PINTYPE_NUMBER,
|
||||
"estimated age" = IC_PINTYPE_NUMBER,
|
||||
"eye colour" = IC_PINTYPE_COLOR
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT, "not scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 5)
|
||||
power_draw_per_use = 100
|
||||
|
||||
/obj/item/integrated_circuit/input/face_scanner/do_work()
|
||||
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
|
||||
if(H in view(get_turf(src))) // This is a camera. It can't examine things that it can't see.
|
||||
set_pin_data(IC_OUTPUT, 1, H.name)
|
||||
set_pin_data(IC_OUTPUT, 2, H.flavor_texts["general"])
|
||||
set_pin_data(IC_OUTPUT, 3, H.flavor_texts["face"])
|
||||
set_pin_data(IC_OUTPUT, 4, H.species.name)
|
||||
set_pin_data(IC_OUTPUT, 5, H.height)
|
||||
set_pin_data(IC_OUTPUT, 6, round(H.age, 5))
|
||||
set_pin_data(IC_OUTPUT, 7, rgb(H.r_eyes, H.g_eyes, H.b_eyes))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
|
||||
/obj/item/integrated_circuit/input/anomaly_scanner
|
||||
name = "alden-saraspova counter"
|
||||
desc = "A miniaturised Alden-Saraspova counter, used to detected anomalous readings. Often used by xenoarchaeologists."
|
||||
extended_desc = "It can only scan a 14x14 area and has an built-in 15 second cooldown."
|
||||
icon_state = "medscan_adv"
|
||||
complexity = 12
|
||||
outputs = list(
|
||||
"exotic particle type" = IC_PINTYPE_STRING,
|
||||
"range detected at" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "anomaly found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_MAGNET = 6, TECH_BLUESPACE = 4)
|
||||
power_draw_per_use = 200
|
||||
cooldown_per_use = 15 SECONDS // sizeable cooldown to prevent view spam
|
||||
|
||||
/obj/item/integrated_circuit/input/anomaly_scanner/do_work()
|
||||
if(!SSxenoarch)
|
||||
return
|
||||
|
||||
var/turf/our_turf = get_turf(src)
|
||||
for(var/turf/simulated/mineral/scanned_turf in view(our_turf)) // Restrict range to only visible tiles, instead of the entire Z-level like standalone AS counters
|
||||
if(scanned_turf.artifact_find)
|
||||
if(scanned_turf.artifact_find.artifact_id)
|
||||
set_pin_data(IC_OUTPUT, 1, scanned_turf.artifact_find.artifact_id)
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, "Exotic Particles (Various)")
|
||||
set_pin_data(IC_OUTPUT, 2, get_dist(our_turf, scanned_turf))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
break
|
||||
..()
|
||||
|
||||
@@ -313,7 +313,7 @@
|
||||
desc = "Used to shock adjacent creatures with electricity."
|
||||
icon_state = "shocker"
|
||||
extended_desc = "The circuit accepts a reference to creature to shock. It can shock a target on adjacent tiles. \
|
||||
Severity determines the power draw and usage of each shock. It accepts values between 0 and 20."
|
||||
Severity determines the power draw and usage of each shock. It accepts values between 0 and 20. It has a 5 second cooldown."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 24
|
||||
inputs = list("target" = IC_PINTYPE_REF,"severity" = IC_PINTYPE_NUMBER)
|
||||
@@ -325,7 +325,7 @@
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/shocker/on_data_written()
|
||||
var/s = get_pin_data(IC_INPUT, 2)
|
||||
power_draw_per_use = clamp(s,0,20)*8
|
||||
power_draw_per_use = clamp(s,0,20)*20 // big power draw to shock large creatures
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/shocker/do_work()
|
||||
..()
|
||||
@@ -339,8 +339,211 @@
|
||||
to_chat(M, SPAN_DANGER("You feel a light tingle from [src]. Luckily it was charging!"))
|
||||
return
|
||||
else
|
||||
msg_admin_attack("An integrated circuit with a shocker circuit was used to shock [M.name] ([M.ckey]) (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
to_chat(M, SPAN_DANGER("You feel a sharp shock from the [src]!"))
|
||||
spark(get_turf(M), 3, 1)
|
||||
M.stun_effect_act(0, clamp(get_pin_data(IC_INPUT, 2),0,20), null)
|
||||
shocktime = world.time
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/flasher
|
||||
name = "flasher circuit"
|
||||
desc = "Used to flash adjacent creatures."
|
||||
icon_state = "video_camera"
|
||||
extended_desc = "The circuit accepts a reference to creature to flash. It can shock a target on adjacent tiles. \
|
||||
Severity determines the power draw and duration of each flash. It accepts values between 1 and 4. It has a 5 second cooldown."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 24
|
||||
inputs = list("target" = IC_PINTYPE_REF,"severity" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("flash" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 0
|
||||
var/flashtime
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/flasher/on_data_written()
|
||||
var/s = get_pin_data(IC_INPUT, 2)
|
||||
power_draw_per_use = clamp(s,1,4)*200 // big power draw to achieve a blinding flash
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/flasher/do_work()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/scanned_mob = get_pin_data_as_type(IC_INPUT, 1, /mob/living)
|
||||
if(!istype(scanned_mob)) //Invalid input
|
||||
return
|
||||
if(!T.Adjacent(scanned_mob))
|
||||
return //Can't reach
|
||||
if((flashtime + (5 SECONDS)) > world.time) // Cooldown
|
||||
visible_message(SPAN_WARNING("You see a weak flash from the [src]."))
|
||||
else
|
||||
var/flash_duration = clamp(get_pin_data(IC_INPUT, 2),1,4)
|
||||
|
||||
scanned_mob.flash_act(length = flash_duration SECONDS)
|
||||
|
||||
flashtime = world.time
|
||||
msg_admin_attack("An integrated circuit with a flasher was used to flash [scanned_mob.name] ([scanned_mob.ckey]) (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/portal_opener // basically a mini telescience setup, but consumes bluespace crystals, is one-way, only along cardinals and ordinals, cannot cross z-levels, and more imprecise (higher chance of getting beamed into a wall/table).
|
||||
name = "bluespace portal circuit"
|
||||
desc = "A miniaturised circuit that uses bluespace crystals to open a one-way bluespace portal. Costlier to use than a standard telescience set up, but portable."
|
||||
extended_desc = "The circuit can store 3 bluespace crystals; each crystal is 1 use. Power determines number of tiles jumped (max 50m). Lifespan determines how long the portal is there (3-15 sec). Imprecise with a high variance <b>(DANGER IN CLOSED SPACES!)</b>. It has a cooldown of 30 seconds."
|
||||
icon_state = "shocker"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
size = 20
|
||||
complexity = 30 // needs a big assembly if you want to use this in any non-simplistic way
|
||||
inputs = list("direction" = IC_PINTYPE_DIR, "power" = IC_PINTYPE_NUMBER, "lifespan" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("bluespace crystals stored" = IC_PINTYPE_NUMBER)
|
||||
activators = list("open portal" = IC_PINTYPE_PULSE_IN, "portal opened" = IC_PINTYPE_PULSE_OUT, "cannot open portal" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 100 // multiplied by up to 50 during on_data_written(). should slurp up power in smaller assemblies or those without power generation
|
||||
cooldown_per_use = 30 SECONDS // big cooldown
|
||||
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 5)
|
||||
|
||||
/// Lazylist of stored bluespace crystals stored in the device for amount checks/deletions.
|
||||
var/list/obj/item/bluespace_crystal/crystals
|
||||
|
||||
/// Maximum number of crystals the circuit can store.
|
||||
var/max_crystals = 3
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/portal_opener/Destroy()
|
||||
for(var/obj/item/bluespace_crystal/crystal in crystals)
|
||||
crystal.dropInto(get_turf(assembly))
|
||||
LAZYNULL(crystals)
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/portal_opener/attackby(obj/item/attacking_item, mob/user, params)
|
||||
if(istype(attacking_item, /obj/item/bluespace_crystal))
|
||||
if(LAZYLEN(crystals) >= max_crystals)
|
||||
to_chat(user, SPAN_WARNING("There are not enough crystal slots."))
|
||||
return
|
||||
|
||||
user.visible_message("[user] inserts [attacking_item] into \the [src]'s crystal slot.", SPAN_NOTICE("You insert [attacking_item] into \the [src]'s crystal slot."))
|
||||
user.drop_item(src)
|
||||
LAZYADD(crystals, attacking_item)
|
||||
attacking_item.forceMove(null)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/portal_opener/on_data_written()
|
||||
power_draw_per_use = round(between(100, 100*(get_pin_data(IC_INPUT, 2)), 5000), 50) // potentially big power draw for a maximum jump range
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/portal_opener/do_work()
|
||||
if(!LAZYLEN(crystals) >= 1) // no crystals, no portal
|
||||
activate_pin(3)
|
||||
return
|
||||
|
||||
var/turf/assembly_turf = get_turf(assembly)
|
||||
if(assembly_turf)
|
||||
// maffs
|
||||
var/proj_power = round(between(1, get_pin_data(IC_INPUT, 2), 50), 1) // max range of 50 metres
|
||||
var/proj_rotation = dir2angle(get_pin_data(IC_INPUT, 1)) // in degrees please
|
||||
var/proj_angle = 60
|
||||
|
||||
var/datum/projectile_data/proj_data = projectile_trajectory(assembly_turf.x, assembly_turf.y, proj_rotation, proj_angle, proj_power)
|
||||
|
||||
var/destination_x = clamp(round(proj_data.dest_x, 1), 1, world.maxx) // dont want to exit map
|
||||
var/destination_y = clamp(round(proj_data.dest_y, 1), 1, world.maxy)
|
||||
|
||||
var/turf/portal_destination = locate(destination_x, destination_y, assembly_turf.z)
|
||||
|
||||
// effects
|
||||
playsound(assembly.loc, 'sound/weapons/flash.ogg', 25, 1)
|
||||
spark(assembly, 5, GLOB.alldirs)
|
||||
|
||||
// portal creation
|
||||
var/lifespan = between(30, SecondsToTicks(get_pin_data(IC_INPUT, 2)), 150)
|
||||
var/obj/effect/portal/our_portal = new /obj/effect/portal(assembly_turf, null, null, lifespan, 0)
|
||||
our_portal.set_target(portal_destination)
|
||||
our_portal.precision = 2 // very imprecise, 5x5 turf variance. best used in very open spaces
|
||||
our_portal.has_failed = FALSE
|
||||
|
||||
// consume a bluespace crystal
|
||||
var/obj/item/bluespace_crystal/consumed_bsc = LAZYACCESS(crystals, 1)
|
||||
LAZYREMOVE(crystals, consumed_bsc)
|
||||
qdel(consumed_bsc)
|
||||
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, LAZYLEN(crystals)) // set the bluespace crystals counter
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/bubble_shield
|
||||
name = "bubble shield circuit"
|
||||
desc = "A large bubble shield generator circuit, like those found in atmospheric emergency shields... sans all the automated features."
|
||||
extended_desc = "Receives relative coordinates to project a shield upon (must be within 3 tiles). Strength determines shield hitpoints (range: 10-50). Lifespan given in seconds (range: 2-60 secs). Can only sustain 3 shields."
|
||||
icon_state = "power_transmitter"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
size = 30 // needs a medium-sized assembly minimum
|
||||
complexity = 20
|
||||
inputs = list("relative X" = IC_PINTYPE_NUMBER, "relative Y" = IC_PINTYPE_NUMBER, "strength" = IC_PINTYPE_NUMBER, "lifespan" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("shields projected" = IC_PINTYPE_NUMBER)
|
||||
activators = list("create shield" = IC_PINTYPE_PULSE_IN, "shield created" = IC_PINTYPE_PULSE_OUT, "shield capacity reached" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 100
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_MAGNET = 5)
|
||||
|
||||
/// A list of shields deployed by this circuit for amount checks/shield deletions.
|
||||
var/list/obj/machinery/shield/deployed_shields
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/bubble_shield/Destroy()
|
||||
QDEL_LAZYLIST(deployed_shields)
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/bubble_shield/proc/kill_shield(var/obj/machinery/shield/shield)
|
||||
LAZYREMOVE(deployed_shields, shield)
|
||||
qdel(shield)
|
||||
set_pin_data(IC_OUTPUT, 1, LAZYLEN(deployed_shields))
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/bubble_shield/do_work()
|
||||
if(!assembly)
|
||||
return
|
||||
|
||||
var/strength = between(10, get_pin_data(IC_INPUT, 3), 50)
|
||||
var/lifespan = between(2, get_pin_data(IC_INPUT, 4), 60)
|
||||
|
||||
// find target turf based on relative coordinates
|
||||
var/target_relative_x = round(get_pin_data(IC_INPUT, 1))
|
||||
var/target_relative_y = round(get_pin_data(IC_INPUT, 2))
|
||||
|
||||
var/turf/our_turf = get_turf(assembly)
|
||||
var/target_x = our_turf.x + target_relative_x
|
||||
var/target_y = our_turf.y + target_relative_y
|
||||
if (target_x > world.maxx || target_x < 1 || target_y > world.maxy || target_y < 1)
|
||||
return // Off the edge of the map.
|
||||
|
||||
var/target_turf = locate(target_x, target_y, our_turf.z)
|
||||
|
||||
// create the shield
|
||||
if(target_turf && (target_turf in view(3, our_turf))) // must be in view and within 3 tiles
|
||||
if(locate(/obj/machinery/shield) in target_turf) // already got a shield
|
||||
return
|
||||
|
||||
if(LAZYLEN(deployed_shields) >= 3) // do not generate more than 3 shields
|
||||
activate_pin(2)
|
||||
return
|
||||
//actually creating the shield
|
||||
var/obj/machinery/shield/shield = new /obj/machinery/shield(target_turf)
|
||||
shield.name = "bubble shield"
|
||||
shield.health = strength
|
||||
LAZYADD(deployed_shields, shield)
|
||||
addtimer(CALLBACK(src, PROC_REF(kill_shield), shield), lifespan SECONDS, TIMER_DELETE_ME) // clean up after ourselves later
|
||||
set_pin_data(IC_OUTPUT, 1, LAZYLEN(deployed_shields))
|
||||
activate_pin(1)
|
||||
|
||||
// power stuff
|
||||
if(deployed_shields)
|
||||
power_draw_per_use = initial(power_draw_per_use)*(strength/10)*LAZYLEN(deployed_shields)
|
||||
else
|
||||
power_draw_per_use = initial(power_draw_per_use)
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/bubble_shield/power_fail()
|
||||
for(var/obj/machinery/shield/shield in deployed_shields)
|
||||
kill_shield(shield)
|
||||
|
||||
@@ -59,25 +59,21 @@
|
||||
inputs = list("delay time" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/custom/do_work()
|
||||
var/delay_input = get_pin_data(IC_INPUT, 1)
|
||||
if(delay_input && isnum(delay_input) )
|
||||
var/new_delay = between(1, delay_input, 1 HOUR)
|
||||
delay = new_delay
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/custom/on_data_written()
|
||||
delay = between(1, get_pin_data(IC_INPUT, 1), 1 HOUR)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker
|
||||
name = "ticker circuit"
|
||||
desc = "This circuit sends an automatic pulse every four seconds."
|
||||
name = "ten second ticker"
|
||||
desc = "This circuit sends an automatic pulse every ten seconds."
|
||||
icon_state = "tick-m"
|
||||
complexity = 8
|
||||
var/ticks_to_pulse = 4
|
||||
var/seconds_to_pulse = 10 SECONDS
|
||||
var/ticks_completed = 0
|
||||
var/is_running = FALSE
|
||||
inputs = list("enable ticking" = IC_PINTYPE_BOOLEAN)
|
||||
activators = list("outgoing pulse" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/Destroy()
|
||||
@@ -97,31 +93,54 @@
|
||||
/obj/item/integrated_circuit/time/ticker/process()
|
||||
var/process_ticks = SSelectronics.wait
|
||||
ticks_completed += process_ticks
|
||||
if(ticks_completed >= ticks_to_pulse)
|
||||
if(ticks_to_pulse >= process_ticks)
|
||||
ticks_completed -= ticks_to_pulse
|
||||
if(ticks_completed >= SecondsToTicks(seconds_to_pulse))
|
||||
if(SecondsToTicks(seconds_to_pulse) >= process_ticks)
|
||||
ticks_completed -= SecondsToTicks(seconds_to_pulse)
|
||||
else
|
||||
ticks_completed = 0
|
||||
activate_pin(1)
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/fast
|
||||
name = "fast ticker"
|
||||
name = "two second ticker"
|
||||
desc = "This advanced circuit sends an automatic pulse every two seconds."
|
||||
icon_state = "tick-f"
|
||||
complexity = 12
|
||||
ticks_to_pulse = 2
|
||||
seconds_to_pulse = 2 SECONDS
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 8
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/slow
|
||||
name = "slow ticker"
|
||||
desc = "This simple circuit sends an automatic pulse every six seconds."
|
||||
name = "thirty second ticker"
|
||||
desc = "This simple circuit sends an automatic pulse every thirty seconds."
|
||||
icon_state = "tick-s"
|
||||
complexity = 4
|
||||
ticks_to_pulse = 6
|
||||
seconds_to_pulse = 30 SECONDS
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/very_slow
|
||||
name = "five minute ticker"
|
||||
desc = "This simple circuit sends an automatic pulse every five minutes (three hundred seconds)."
|
||||
icon_state = "tick-s"
|
||||
complexity = 4
|
||||
seconds_to_pulse = 300 SECONDS
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/custom
|
||||
name = "custom ticker"
|
||||
desc = "This advanced circuit sends an automatic pulse with a configurable interval between 2 and 600 seconds. Default: 60 seconds."
|
||||
icon_state = "tick-f"
|
||||
complexity = 15
|
||||
seconds_to_pulse = 60 SECONDS
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 8
|
||||
inputs = list("enable ticking" = IC_PINTYPE_BOOLEAN, "ticker time" = IC_PINTYPE_NUMBER)
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/custom/on_data_written()
|
||||
seconds_to_pulse = between(2 SECONDS, get_pin_data(IC_INPUT, 2), 600 SECONDS)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/time/clock
|
||||
name = "integrated clock"
|
||||
desc = "Tells you what the local time is, specific to your station, planet, or facility."
|
||||
|
||||
Reference in New Issue
Block a user