Merge branch 'master' into upstream-merge-32280
This commit is contained in:
@@ -4,8 +4,7 @@
|
||||
var/F = file("[GLOB.log_directory]/[subject].html")
|
||||
WRITE_FILE(F, "<small>[time_stamp()] [REF(src)] ([x],[y],[z])</small> || [src] [message]<br>")
|
||||
|
||||
|
||||
/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS) )
|
||||
/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION) )
|
||||
set name = "Investigate"
|
||||
set category = "Admin"
|
||||
if(!holder)
|
||||
|
||||
@@ -607,6 +607,20 @@
|
||||
dat += "<td><A href='?priv_msg=[blob.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
|
||||
var/list/pirates = get_antagonists(/datum/antagonist/pirate)
|
||||
if(pirates.len > 0)
|
||||
dat += "<br><table cellspacing=5><tr><td><B>Pirates</B></td><td></td></tr>"
|
||||
for(var/datum/mind/N in pirates)
|
||||
var/mob/M = N.current
|
||||
if(!M)
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[N]'>[N.name]([N.key])</a><i>No body.</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
if(istype(SSticker.mode, /datum/game_mode/monkey))
|
||||
var/datum/game_mode/monkey/mode = SSticker.mode
|
||||
|
||||
@@ -778,6 +778,13 @@ GLOBAL_PROTECT(LastAdminCalledProc)
|
||||
|
||||
usr << browse(dellog.Join(), "window=dellog")
|
||||
|
||||
/client/proc/cmd_display_overlay_log()
|
||||
set category = "Debug"
|
||||
set name = "Display overlay Log"
|
||||
set desc = "Display SSoverlays log of everything that's passed through it."
|
||||
|
||||
render_stats(SSoverlays.stats, src)
|
||||
|
||||
/client/proc/cmd_display_init_log()
|
||||
set category = "Debug"
|
||||
set name = "Display Initialize() Log"
|
||||
|
||||
@@ -678,15 +678,7 @@
|
||||
update_icon()
|
||||
return
|
||||
else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/device/pda))// trying to unlock the interface with an ID card
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
to_chat(user, "<span class='warning'>It does nothing!</span>")
|
||||
else
|
||||
if(src.allowed(usr) && !wires.is_cut(WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [ locked ? "lock" : "unlock"] the air alarm interface.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Access denied.</span>")
|
||||
return
|
||||
togglelock(user)
|
||||
else if(panel_open && is_wire_tool(W))
|
||||
wires.interact(user)
|
||||
return
|
||||
@@ -751,6 +743,25 @@
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/airalarm/AltClick(mob/user)
|
||||
..()
|
||||
if(!issilicon(user) && (!user.canUseTopic(src, be_close=TRUE) || !isturf(loc)))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
else
|
||||
togglelock(user)
|
||||
|
||||
/obj/machinery/airalarm/proc/togglelock(mob/living/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
to_chat(user, "<span class='warning'>It does nothing!</span>")
|
||||
else
|
||||
if(src.allowed(usr) && !wires.is_cut(WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [ locked ? "lock" : "unlock"] the air alarm interface.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Access denied.</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/airalarm/power_change()
|
||||
..()
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
var/volume = 100
|
||||
|
||||
var/efficiency = 1
|
||||
var/sleep_factor = 750
|
||||
var/unconscious_factor = 1000
|
||||
var/sleep_factor = 0.00125
|
||||
var/unconscious_factor = 0.001
|
||||
var/heat_capacity = 20000
|
||||
var/conduction_coefficient = 0.3
|
||||
|
||||
@@ -94,29 +94,29 @@
|
||||
if(occupant)
|
||||
var/image/occupant_overlay
|
||||
|
||||
if(ismonkey(occupant)) // Monkey
|
||||
occupant_overlay = image(CRYOMOBS, "monkey")
|
||||
occupant_overlay.copy_overlays(occupant)
|
||||
else if(isalienadult(occupant))
|
||||
if(isalienroyal(occupant)) // Queen and prae
|
||||
occupant_overlay = image(CRYOMOBS, "alienq")
|
||||
else if(isalienhunter(occupant)) // Hunter
|
||||
occupant_overlay = image(CRYOMOBS, "alienh")
|
||||
else if(isaliensentinel(occupant)) // Sentinel
|
||||
occupant_overlay = image(CRYOMOBS, "aliens")
|
||||
else // Drone or other
|
||||
occupant_overlay = image(CRYOMOBS, "aliend")
|
||||
|
||||
else if(ishuman(occupant) || islarva(occupant) || (isanimal(occupant) && !ismegafauna(occupant))) // Mobs that are smaller than cryotube
|
||||
occupant_overlay = image(occupant.icon, occupant.icon_state)
|
||||
|
||||
if(ishuman(occupant) || islarva(occupant) || (isanimal(occupant) && !ismegafauna(occupant))) // Mobs that are smaller than cryotube
|
||||
occupant_overlay = image(occupant.icon, occupant.icon_state)
|
||||
occupant_overlay.copy_overlays(occupant)
|
||||
|
||||
else if(ismonkey(occupant)) // Monkey
|
||||
occupant_overlay = image(CRYOMOBS, "monkey")
|
||||
occupant_overlay.copy_overlays(occupant)
|
||||
|
||||
else if(!isalienadult(occupant))
|
||||
else
|
||||
occupant_overlay = image(CRYOMOBS, "generic")
|
||||
|
||||
else if(isalienroyal(occupant)) // Queen and prae
|
||||
occupant_overlay = image(CRYOMOBS, "alienq")
|
||||
|
||||
else if(isalienhunter(occupant)) // Hunter
|
||||
occupant_overlay = image(CRYOMOBS, "alienh")
|
||||
|
||||
else if(isaliensentinel(occupant)) // Sentinel
|
||||
occupant_overlay = image(CRYOMOBS, "aliens")
|
||||
|
||||
else // Drone or other
|
||||
occupant_overlay = image(CRYOMOBS, "aliend")
|
||||
|
||||
occupant_overlay.dir = SOUTH
|
||||
occupant_overlay.pixel_y = 22
|
||||
|
||||
@@ -182,8 +182,8 @@
|
||||
|
||||
if(air1.gases.len)
|
||||
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
|
||||
mob_occupant.Sleeping((mob_occupant.bodytemperature / sleep_factor) * 2000)
|
||||
mob_occupant.Unconscious((mob_occupant.bodytemperature / unconscious_factor) * 2000)
|
||||
mob_occupant.Sleeping((mob_occupant.bodytemperature * sleep_factor) * 2000)
|
||||
mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_factor) * 2000)
|
||||
if(beaker)
|
||||
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
|
||||
beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic.
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/obj/machinery/atmospherics/components/unary/generator_input
|
||||
|
||||
icon_state = "he_intact"
|
||||
density = TRUE
|
||||
|
||||
name = "generator input"
|
||||
desc = "An input for a generator."
|
||||
layer = LOW_OBJ_LAYER
|
||||
|
||||
var/update_cycle
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/generator_input/update_icon()
|
||||
icon_state = NODE1 ? "intact" : "exposed"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/generator_input/proc/return_exchange_air()
|
||||
return AIR1
|
||||
@@ -1,57 +0,0 @@
|
||||
/obj/machinery/atmospherics/components/unary/oxygen_generator
|
||||
|
||||
icon_state = "o2gen_map"
|
||||
|
||||
name = "oxygen generator"
|
||||
desc = "Generates oxygen."
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH
|
||||
layer = GAS_SCRUBBER_LAYER
|
||||
|
||||
var/on = FALSE
|
||||
|
||||
var/oxygen_content = 10
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/oxygen_generator/update_icon_nopipes()
|
||||
|
||||
cut_overlays()
|
||||
if(showpipe)
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/unary_devices.dmi', "scrub_cap", initialize_directions)) //it works for now
|
||||
|
||||
if(!NODE1 || !on || !is_operational())
|
||||
icon_state = "o2gen_off"
|
||||
return
|
||||
|
||||
else
|
||||
icon_state = "o2gen_on"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/oxygen_generator/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
air_contents.volume = 50
|
||||
AIR1 = air_contents
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/oxygen_generator/process_atmos()
|
||||
|
||||
..()
|
||||
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
|
||||
var/total_moles = air_contents.total_moles()
|
||||
|
||||
if(total_moles < oxygen_content)
|
||||
var/current_heat_capacity = air_contents.heat_capacity()
|
||||
|
||||
var/added_oxygen = oxygen_content - total_moles
|
||||
|
||||
air_contents.temperature = (current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen)
|
||||
ASSERT_GAS(/datum/gas/oxygen, air_contents)
|
||||
air_contents.gases[/datum/gas/oxygen][MOLES] += added_oxygen
|
||||
|
||||
update_parents()
|
||||
|
||||
return 1
|
||||
@@ -5,6 +5,8 @@
|
||||
device_type = UNARY
|
||||
pipe_flags = PIPING_ONE_PER_TURF
|
||||
construction_type = /obj/item/pipe/directional
|
||||
var/uid
|
||||
var/static/gl_uid = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/SetInitDirections()
|
||||
initialize_directions = dir
|
||||
@@ -16,3 +18,7 @@
|
||||
/obj/machinery/atmospherics/components/unary/hide(intact)
|
||||
update_icon()
|
||||
..(intact)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/proc/assign_uid_vents()
|
||||
uid = num2text(gl_uid++)
|
||||
return uid
|
||||
@@ -50,8 +50,7 @@
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/New()
|
||||
..()
|
||||
if(!id_tag)
|
||||
assign_uid()
|
||||
id_tag = num2text(uid)
|
||||
id_tag = assign_uid_vents()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/Destroy()
|
||||
var/area/A = get_area(src)
|
||||
|
||||
@@ -38,8 +38,7 @@
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/New()
|
||||
..()
|
||||
if(!id_tag)
|
||||
assign_uid()
|
||||
id_tag = num2text(uid)
|
||||
id_tag = assign_uid_vents()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/on
|
||||
on = TRUE
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
/obj/effect/mob_spawn
|
||||
name = "Unknown"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/mob_type = null
|
||||
var/mob_name = ""
|
||||
var/mob_gender = null
|
||||
@@ -21,8 +23,7 @@
|
||||
var/burn_damage = 0
|
||||
var/mob_color //Change the mob's color
|
||||
var/assignedrole
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/show_flavour = TRUE
|
||||
var/banType = "lavaland"
|
||||
|
||||
/obj/effect/mob_spawn/attack_ghost(mob/user)
|
||||
@@ -60,7 +61,7 @@
|
||||
/obj/effect/mob_spawn/proc/equip(mob/M)
|
||||
return
|
||||
|
||||
/obj/effect/mob_spawn/proc/create(ckey, flavour = TRUE, name)
|
||||
/obj/effect/mob_spawn/proc/create(ckey, name)
|
||||
var/mob/living/M = new mob_type(get_turf(src)) //living mobs only
|
||||
if(!random)
|
||||
M.real_name = mob_name ? mob_name : M.name
|
||||
@@ -80,7 +81,7 @@
|
||||
|
||||
if(ckey)
|
||||
M.ckey = ckey
|
||||
if(flavour)
|
||||
if(show_flavour)
|
||||
to_chat(M, "[flavour_text]")
|
||||
var/datum/mind/MM = M.mind
|
||||
if(objectives)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/safety_warning = "For safety reasons the automated supply shuttle \
|
||||
cannot transport live organisms, classified nuclear weaponry or \
|
||||
homing beacons."
|
||||
var/blockade_warning = "Bluespace instability detected. Shuttle movement impossible."
|
||||
|
||||
light_color = "#E2853D"//orange
|
||||
|
||||
@@ -54,8 +55,12 @@
|
||||
data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE
|
||||
data["loan"] = !!SSshuttle.shuttle_loan
|
||||
data["loan_dispatched"] = SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched
|
||||
data["message"] = SSshuttle.centcom_message || "Remember to stamp and send back the supply manifests."
|
||||
|
||||
var/message = "Remember to stamp and send back the supply manifests."
|
||||
if(SSshuttle.centcom_message)
|
||||
message = SSshuttle.centcom_message
|
||||
if(SSshuttle.supplyBlocked)
|
||||
message = blockade_warning
|
||||
data["message"] = message
|
||||
data["supplies"] = list()
|
||||
for(var/pack in SSshuttle.supply_packs)
|
||||
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
|
||||
@@ -102,6 +107,9 @@
|
||||
if(!SSshuttle.supply.canMove())
|
||||
say(safety_warning)
|
||||
return
|
||||
if(SSshuttle.supplyBlocked)
|
||||
say(blockade_warning)
|
||||
return
|
||||
if(SSshuttle.supply.getDockedId() == "supply_home")
|
||||
SSshuttle.supply.emagged = emagged
|
||||
SSshuttle.supply.contraband = contraband
|
||||
@@ -116,6 +124,9 @@
|
||||
if("loan")
|
||||
if(!SSshuttle.shuttle_loan)
|
||||
return
|
||||
if(SSshuttle.supplyBlocked)
|
||||
say(blockade_warning)
|
||||
return
|
||||
else if(SSshuttle.supply.mode != SHUTTLE_IDLE)
|
||||
return
|
||||
else if(SSshuttle.supply.getDockedId() != "supply_away")
|
||||
|
||||
@@ -938,10 +938,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
|
||||
|
||||
if("flavor_text")
|
||||
var/msg = input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(features["flavor_text"])) as message
|
||||
var/msg = stripped_multiline_input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(features["flavor_text"]), MAX_MESSAGE_LEN*2, TRUE) as message
|
||||
if(msg != null)
|
||||
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
|
||||
msg = html_encode(msg)
|
||||
msg = copytext(msg, 1, MAX_MESSAGE_LEN*2)
|
||||
features["flavor_text"] = msg
|
||||
|
||||
if("metadata")
|
||||
|
||||
@@ -78,20 +78,38 @@
|
||||
suit_store = /obj/item/gun/energy/laser/bluetag
|
||||
|
||||
/datum/outfit/pirate
|
||||
name = "Pirate"
|
||||
name = "Space Pirate"
|
||||
|
||||
uniform = /obj/item/clothing/under/pirate
|
||||
shoes = /obj/item/clothing/shoes/sneakers/brown
|
||||
suit = /obj/item/clothing/suit/pirate
|
||||
head = /obj/item/clothing/head/bandana
|
||||
glasses = /obj/item/clothing/glasses/eyepatch
|
||||
r_hand = /obj/item/melee/transforming/energy/sword/pirate
|
||||
|
||||
/datum/outfit/pirate/space
|
||||
name = "Space Pirate"
|
||||
|
||||
suit = /obj/item/clothing/suit/space/pirate
|
||||
head = /obj/item/clothing/head/helmet/space/pirate/bandana
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
suit_store = /obj/item/tank/internals/oxygen
|
||||
ears = /obj/item/device/radio/headset/syndicate
|
||||
id = /obj/item/card/id
|
||||
|
||||
/datum/outfit/pirate/space/captain
|
||||
head = /obj/item/clothing/head/helmet/space/pirate
|
||||
|
||||
/datum/outfit/pirate/post_equip(mob/living/carbon/human/H)
|
||||
H.faction |= "pirate"
|
||||
|
||||
var/obj/item/device/radio/R = H.ears
|
||||
if(R)
|
||||
R.set_frequency(GLOB.SYND_FREQ)
|
||||
R.freqlock = 1
|
||||
|
||||
var/obj/item/card/id/W = H.wear_id
|
||||
if(W)
|
||||
W.registered_name = H.real_name
|
||||
W.update_label(H.real_name)
|
||||
|
||||
/datum/outfit/tunnel_clown
|
||||
name = "Tunnel Clown"
|
||||
|
||||
|
||||
@@ -137,10 +137,16 @@ Contains:
|
||||
item_state = "pirate"
|
||||
armor = list(melee = 30, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30, fire = 60, acid = 75)
|
||||
flags_1 = STOPSPRESSUREDMAGE_1
|
||||
flags_inv = HIDEHAIR
|
||||
strip_delay = 40
|
||||
equip_delay_other = 20
|
||||
flags_cover = HEADCOVERSEYES
|
||||
|
||||
/obj/item/clothing/head/helmet/space/pirate/bandana
|
||||
name = "pirate bandana"
|
||||
icon_state = "bandana"
|
||||
item_state = "bandana"
|
||||
|
||||
/obj/item/clothing/suit/space/pirate
|
||||
name = "pirate coat"
|
||||
desc = "Yarr."
|
||||
|
||||
@@ -108,11 +108,12 @@
|
||||
var/datum/round_event_control/control
|
||||
|
||||
var/startWhen = 0 //When in the lifetime to call start().
|
||||
var/announceWhen = 0 //When in the lifetime to call announce(). Set an event's announceWhen to >0 if there is an announcement.
|
||||
var/announceWhen = 0 //When in the lifetime to call announce(). Set an event's announceWhen to -1 if announcement should not be shown.
|
||||
var/endWhen = 0 //When in the lifetime the event should end.
|
||||
|
||||
var/activeFor = 0 //How long the event has existed. You don't need to change this.
|
||||
var/current_players = 0 //Amount of of alive, non-AFK human players on server at the time of event start
|
||||
var/fakeable = TRUE //Can be faked by fake news event.
|
||||
|
||||
//Called first before processing.
|
||||
//Allows you to setup your event, such as randomly
|
||||
@@ -133,7 +134,7 @@
|
||||
//Called when the tick is equal to the announceWhen variable.
|
||||
//Allows you to announce before starting or vice versa.
|
||||
//Only called once.
|
||||
/datum/round_event/proc/announce()
|
||||
/datum/round_event/proc/announce(fake)
|
||||
return
|
||||
|
||||
//Called on or after the tick counter is equal to startWhen.
|
||||
@@ -167,7 +168,7 @@
|
||||
|
||||
if(activeFor == announceWhen)
|
||||
processing = FALSE
|
||||
announce()
|
||||
announce(FALSE)
|
||||
processing = TRUE
|
||||
|
||||
if(startWhen < activeFor && activeFor < endWhen)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
/datum/round_event/ghost_role/abductor
|
||||
minimum_required = 2
|
||||
role_name = "abductor team"
|
||||
fakeable = FALSE //Nothing to fake here
|
||||
|
||||
/datum/round_event/ghost_role/abductor/spawn_role()
|
||||
var/list/mob/dead/observer/candidates = get_candidates("abductor", null, ROLE_ABDUCTOR)
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
control.occurrences--
|
||||
return ..()
|
||||
|
||||
/datum/round_event/ghost_role/alien_infestation/announce()
|
||||
if(successSpawn)
|
||||
/datum/round_event/ghost_role/alien_infestation/announce(fake)
|
||||
if(successSpawn || fake)
|
||||
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg')
|
||||
|
||||
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
/datum/round_event_control/anomaly
|
||||
name = "Anomaly: Energetic Flux"
|
||||
typepath = /datum/round_event/anomaly
|
||||
|
||||
min_players = 1
|
||||
max_occurrences = 0 //This one probably shouldn't occur! It'd work, but it wouldn't be very fun.
|
||||
weight = 15
|
||||
|
||||
/datum/round_event/anomaly
|
||||
var/area/impact_area
|
||||
var/obj/effect/anomaly/newAnomaly
|
||||
announceWhen = 1
|
||||
|
||||
|
||||
/datum/round_event/anomaly/setup(loop=0)
|
||||
var/safety_loop = loop + 1
|
||||
if(safety_loop > 50)
|
||||
kill()
|
||||
end()
|
||||
impact_area = findEventArea()
|
||||
if(!impact_area)
|
||||
setup(safety_loop)
|
||||
var/list/turf_test = get_area_turfs(impact_area)
|
||||
if(!turf_test.len)
|
||||
setup(safety_loop)
|
||||
|
||||
/datum/round_event/anomaly/announce()
|
||||
priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/flux(T)
|
||||
/datum/round_event_control/anomaly
|
||||
name = "Anomaly: Energetic Flux"
|
||||
typepath = /datum/round_event/anomaly
|
||||
|
||||
min_players = 1
|
||||
max_occurrences = 0 //This one probably shouldn't occur! It'd work, but it wouldn't be very fun.
|
||||
weight = 15
|
||||
|
||||
/datum/round_event/anomaly
|
||||
var/area/impact_area
|
||||
var/obj/effect/anomaly/newAnomaly
|
||||
announceWhen = 1
|
||||
|
||||
|
||||
/datum/round_event/anomaly/setup(loop=0)
|
||||
var/safety_loop = loop + 1
|
||||
if(safety_loop > 50)
|
||||
kill()
|
||||
end()
|
||||
impact_area = findEventArea()
|
||||
if(!impact_area)
|
||||
setup(safety_loop)
|
||||
var/list/turf_test = get_area_turfs(impact_area)
|
||||
if(!turf_test.len)
|
||||
setup(safety_loop)
|
||||
|
||||
/datum/round_event/anomaly/announce(fake)
|
||||
priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/flux(T)
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/datum/round_event_control/anomaly/anomaly_bluespace
|
||||
name = "Anomaly: Bluespace"
|
||||
typepath = /datum/round_event/anomaly/anomaly_bluespace
|
||||
max_occurrences = 1
|
||||
weight = 5
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace
|
||||
startWhen = 3
|
||||
announceWhen = 10
|
||||
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace/announce()
|
||||
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/bluespace(T)
|
||||
/datum/round_event_control/anomaly/anomaly_bluespace
|
||||
name = "Anomaly: Bluespace"
|
||||
typepath = /datum/round_event/anomaly/anomaly_bluespace
|
||||
max_occurrences = 1
|
||||
weight = 5
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace
|
||||
startWhen = 3
|
||||
announceWhen = 10
|
||||
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace/announce(fake)
|
||||
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/bluespace(T)
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/datum/round_event_control/anomaly/anomaly_flux
|
||||
name = "Anomaly: Hyper-Energetic Flux"
|
||||
typepath = /datum/round_event/anomaly/anomaly_flux
|
||||
|
||||
min_players = 10
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux
|
||||
startWhen = 10
|
||||
announceWhen = 3
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux/announce()
|
||||
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/flux(T)
|
||||
/datum/round_event_control/anomaly/anomaly_flux
|
||||
name = "Anomaly: Hyper-Energetic Flux"
|
||||
typepath = /datum/round_event/anomaly/anomaly_flux
|
||||
|
||||
min_players = 10
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux
|
||||
startWhen = 10
|
||||
announceWhen = 3
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux/announce(fake)
|
||||
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/flux(T)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/datum/round_event_control/anomaly/anomaly_grav
|
||||
name = "Anomaly: Gravitational"
|
||||
typepath = /datum/round_event/anomaly/anomaly_grav
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav
|
||||
startWhen = 3
|
||||
announceWhen = 20
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav/announce()
|
||||
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/grav(T)
|
||||
/datum/round_event_control/anomaly/anomaly_grav
|
||||
name = "Anomaly: Gravitational"
|
||||
typepath = /datum/round_event/anomaly/anomaly_grav
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav
|
||||
startWhen = 3
|
||||
announceWhen = 20
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav/announce(fake)
|
||||
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/grav(T)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
startWhen = 3
|
||||
announceWhen = 10
|
||||
|
||||
/datum/round_event/anomaly/anomaly_pyro/announce()
|
||||
/datum/round_event/anomaly/anomaly_pyro/announce(fake)
|
||||
priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_pyro/start()
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/datum/round_event_control/anomaly/anomaly_vortex
|
||||
name = "Anomaly: Vortex"
|
||||
typepath = /datum/round_event/anomaly/anomaly_vortex
|
||||
|
||||
min_players = 20
|
||||
max_occurrences = 2
|
||||
weight = 5
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex
|
||||
startWhen = 10
|
||||
announceWhen = 3
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex/announce()
|
||||
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/bhole(T)
|
||||
/datum/round_event_control/anomaly/anomaly_vortex
|
||||
name = "Anomaly: Vortex"
|
||||
typepath = /datum/round_event/anomaly/anomaly_vortex
|
||||
|
||||
min_players = 20
|
||||
max_occurrences = 2
|
||||
weight = 5
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex
|
||||
startWhen = 10
|
||||
announceWhen = 3
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex/announce(fake)
|
||||
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex/start()
|
||||
var/turf/T = safepick(get_area_turfs(impact_area))
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/bhole(T)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
announceWhen = -1
|
||||
role_name = "blob overmind"
|
||||
|
||||
/datum/round_event/ghost_role/blob/announce()
|
||||
/datum/round_event/ghost_role/blob/announce(fake)
|
||||
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
|
||||
|
||||
/datum/round_event/ghost_role/blob/spawn_role()
|
||||
|
||||
@@ -21,9 +21,14 @@
|
||||
"You don't want to buy anything? Yeah, well, I didn't want to buy your mom either.")
|
||||
|
||||
|
||||
/datum/round_event/brand_intelligence/announce()
|
||||
priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [originMachine.name].", "Machine Learning Alert")
|
||||
|
||||
/datum/round_event/brand_intelligence/announce(fake)
|
||||
var/source = "unknown machine"
|
||||
if(fake)
|
||||
var/obj/machinery/vending/cola/example = /obj/machinery/vending/cola
|
||||
source = initial(example.name)
|
||||
else if(originMachine)
|
||||
source = originMachine.name
|
||||
priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Machine Learning Alert")
|
||||
|
||||
/datum/round_event/brand_intelligence/start()
|
||||
for(var/obj/machinery/vending/V in GLOB.machines)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/datum/round_event/camera_failure
|
||||
startWhen = 1
|
||||
endWhen = 2
|
||||
announceWhen = 0
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/camera_failure/tick()
|
||||
var/iterations = 1
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/datum/round_event/carp_migration/setup()
|
||||
startWhen = rand(40, 60)
|
||||
|
||||
/datum/round_event/carp_migration/announce()
|
||||
/datum/round_event/carp_migration/announce(fake)
|
||||
priority_announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
|
||||
|
||||
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/datum/round_event_control/communications_blackout
|
||||
name = "Communications Blackout"
|
||||
typepath = /datum/round_event/communications_blackout
|
||||
weight = 30
|
||||
|
||||
/datum/round_event/communications_blackout
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/communications_blackout/announce()
|
||||
var/alert = pick( "Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you*%fj00)`5vc-BZZT", \
|
||||
"Ionospheric anomalies detected. Temporary telecommunication failu*3mga;b4;'1v�-BZZZT", \
|
||||
"Ionospheric anomalies detected. Temporary telec#MCi46:5.;@63-BZZZZT", \
|
||||
"Ionospheric anomalies dete'fZ\\kg5_0-BZZZZZT", \
|
||||
"Ionospheri:%� MCayj^j<.3-BZZZZZZT", \
|
||||
"#4nd%;f4y6,>�%-BZZZZZZZT")
|
||||
|
||||
for(var/mob/living/silicon/ai/A in GLOB.ai_list) //AIs are always aware of communication blackouts.
|
||||
to_chat(A, "<br><span class='warning'><b>[alert]</b></span><br>")
|
||||
|
||||
if(prob(30)) //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts.
|
||||
priority_announce(alert)
|
||||
|
||||
|
||||
/datum/round_event/communications_blackout/start()
|
||||
for(var/obj/machinery/telecomms/T in GLOB.telecomms_list)
|
||||
/datum/round_event_control/communications_blackout
|
||||
name = "Communications Blackout"
|
||||
typepath = /datum/round_event/communications_blackout
|
||||
weight = 30
|
||||
|
||||
/datum/round_event/communications_blackout
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/communications_blackout/announce(fake)
|
||||
var/alert = pick( "Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you*%fj00)`5vc-BZZT", \
|
||||
"Ionospheric anomalies detected. Temporary telecommunication failu*3mga;b4;'1v�-BZZZT", \
|
||||
"Ionospheric anomalies detected. Temporary telec#MCi46:5.;@63-BZZZZT", \
|
||||
"Ionospheric anomalies dete'fZ\\kg5_0-BZZZZZT", \
|
||||
"Ionospheri:%� MCayj^j<.3-BZZZZZZT", \
|
||||
"#4nd%;f4y6,>�%-BZZZZZZZT")
|
||||
|
||||
for(var/mob/living/silicon/ai/A in GLOB.ai_list) //AIs are always aware of communication blackouts.
|
||||
to_chat(A, "<br><span class='warning'><b>[alert]</b></span><br>")
|
||||
|
||||
if(prob(30) || fake) //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts.
|
||||
priority_announce(alert)
|
||||
|
||||
|
||||
/datum/round_event/communications_blackout/start()
|
||||
for(var/obj/machinery/telecomms/T in GLOB.telecomms_list)
|
||||
T.emp_act(EMP_HEAVY)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
/datum/round_event/ghost_role/devil
|
||||
var/success_spawn = 0
|
||||
role_name = "devil"
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/ghost_role/devil/kill()
|
||||
if(!success_spawn && control)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/virus_type
|
||||
|
||||
|
||||
/datum/round_event/disease_outbreak/announce()
|
||||
/datum/round_event/disease_outbreak/announce(fake)
|
||||
priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg')
|
||||
|
||||
/datum/round_event/disease_outbreak/setup()
|
||||
|
||||
+31
-30
@@ -1,30 +1,31 @@
|
||||
/datum/round_event_control/space_dust
|
||||
name = "Minor Space Dust"
|
||||
typepath = /datum/round_event/space_dust
|
||||
weight = 200
|
||||
max_occurrences = 1000
|
||||
earliest_start = 0
|
||||
alertadmins = 0
|
||||
|
||||
/datum/round_event/space_dust
|
||||
startWhen = 1
|
||||
endWhen = 2
|
||||
announceWhen = 0
|
||||
|
||||
/datum/round_event/space_dust/start()
|
||||
spawn_meteors(1, GLOB.meteorsC)
|
||||
|
||||
/datum/round_event_control/sandstorm
|
||||
name = "Sandstorm"
|
||||
typepath = /datum/round_event/sandstorm
|
||||
weight = 0
|
||||
max_occurrences = 0
|
||||
earliest_start = 0
|
||||
|
||||
/datum/round_event/sandstorm
|
||||
startWhen = 1
|
||||
endWhen = 150 // ~5 min
|
||||
announceWhen = 0
|
||||
|
||||
/datum/round_event/sandstorm/tick()
|
||||
spawn_meteors(10, GLOB.meteorsC)
|
||||
/datum/round_event_control/space_dust
|
||||
name = "Minor Space Dust"
|
||||
typepath = /datum/round_event/space_dust
|
||||
weight = 200
|
||||
max_occurrences = 1000
|
||||
earliest_start = 0
|
||||
alertadmins = 0
|
||||
|
||||
/datum/round_event/space_dust
|
||||
startWhen = 1
|
||||
endWhen = 2
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/space_dust/start()
|
||||
spawn_meteors(1, GLOB.meteorsC)
|
||||
|
||||
/datum/round_event_control/sandstorm
|
||||
name = "Sandstorm"
|
||||
typepath = /datum/round_event/sandstorm
|
||||
weight = 0
|
||||
max_occurrences = 0
|
||||
earliest_start = 0
|
||||
|
||||
/datum/round_event/sandstorm
|
||||
startWhen = 1
|
||||
endWhen = 150 // ~5 min
|
||||
announceWhen = 0
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/sandstorm/tick()
|
||||
spawn_meteors(10, GLOB.meteorsC)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/lightsoutRange = 25
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/electrical_storm/announce()
|
||||
/datum/round_event/electrical_storm/announce(fake)
|
||||
priority_announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
|
||||
|
||||
|
||||
|
||||
@@ -13,10 +13,8 @@
|
||||
var/list/possible_types = list()
|
||||
|
||||
for(var/datum/round_event_control/E in SSevents.control)
|
||||
if(istype(E, /datum/round_event_control/falsealarm))
|
||||
continue
|
||||
var/datum/round_event/event = E.typepath
|
||||
if(initial(event.announceWhen) <= 0)
|
||||
if(!initial(event.fakeable))
|
||||
continue
|
||||
possible_types += E
|
||||
|
||||
@@ -28,8 +26,11 @@
|
||||
/datum/round_event/falsealarm
|
||||
announceWhen = 0
|
||||
endWhen = 1
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/falsealarm/announce()
|
||||
/datum/round_event/falsealarm/announce(fake)
|
||||
if(fake) //What are you doing
|
||||
return
|
||||
var/players_amt = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
|
||||
var/gamemode = SSticker.mode.config_tag
|
||||
|
||||
@@ -45,7 +46,7 @@
|
||||
var/datum/round_event/Event = new event_control.typepath()
|
||||
message_admins("False Alarm: [Event]")
|
||||
Event.kill() //do not process this event - no starts, no ticks, no ends
|
||||
Event.announce() //just announce it like it's happening
|
||||
Event.announce(TRUE) //just announce it like it's happening
|
||||
|
||||
/proc/gather_false_events(players_amt, gamemode)
|
||||
. = list()
|
||||
@@ -56,6 +57,6 @@
|
||||
continue
|
||||
|
||||
var/datum/round_event/event = E.typepath
|
||||
if(initial(event.announceWhen) <= 0)
|
||||
if(!initial(event.fakeable))
|
||||
continue
|
||||
. += E
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
announceWhen = 1
|
||||
startWhen = 1
|
||||
|
||||
/datum/round_event/grid_check/announce()
|
||||
/datum/round_event/grid_check/announce(fake)
|
||||
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// Basically, cut the event frequency in half to simulate unluckiness.
|
||||
|
||||
/datum/round_event_control/fridaythethirteen
|
||||
name = "Friday the 13th"
|
||||
holidayID = FRIDAY_13TH
|
||||
typepath = /datum/round_event/fridaythethirteen
|
||||
weight = -1
|
||||
max_occurrences = 1
|
||||
earliest_start = 0
|
||||
|
||||
/datum/round_event/fridaythethirteen/start()
|
||||
//Very unlucky, cut the frequency of events in half.
|
||||
events.frequency_lower /= 2
|
||||
events.frequency_upper /= 2
|
||||
|
||||
/datum/round_event/fridaythethirteen/announce()
|
||||
for(var/mob/living/L in player_list)
|
||||
to_chat(L, "<span class='warning'>You are feeling unlucky today.</span>")
|
||||
// Basically, cut the event frequency in half to simulate unluckiness.
|
||||
|
||||
/datum/round_event_control/fridaythethirteen
|
||||
name = "Friday the 13th"
|
||||
holidayID = FRIDAY_13TH
|
||||
typepath = /datum/round_event/fridaythethirteen
|
||||
weight = -1
|
||||
max_occurrences = 1
|
||||
earliest_start = 0
|
||||
|
||||
/datum/round_event/fridaythethirteen/start()
|
||||
//Very unlucky, cut the frequency of events in half.
|
||||
events.frequency_lower /= 2
|
||||
events.frequency_upper /= 2
|
||||
|
||||
/datum/round_event/fridaythethirteen/announce(fake)
|
||||
for(var/mob/living/L in player_list)
|
||||
to_chat(L, "<span class='warning'>You are feeling unlucky today.</span>")
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc)
|
||||
qdel(Poly)
|
||||
|
||||
/datum/round_event/spooky/announce()
|
||||
/datum/round_event/spooky/announce(fake)
|
||||
priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE")
|
||||
|
||||
//spooky foods (you can't actually make these when it's not halloween)
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
to_chat(lover, "<span class='warning'><B>You're on a date with [date]! Protect them at all costs. This takes priority over all other loyalties.</B></span>")
|
||||
|
||||
|
||||
/datum/round_event/valentines/announce()
|
||||
/datum/round_event/valentines/announce(fake)
|
||||
priority_announce("It's Valentine's Day! Give a valentine to that special someone!")
|
||||
|
||||
/obj/item/valentine
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines)
|
||||
Monitor.icon_state = "entertainment_xmas"
|
||||
|
||||
/datum/round_event/presents/announce()
|
||||
/datum/round_event/presents/announce(fake)
|
||||
priority_announce("Ho Ho Ho, Merry Xmas!", "Unknown Transmission")
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
/datum/round_event/santa
|
||||
var/mob/living/carbon/human/santa //who is our santa?
|
||||
|
||||
/datum/round_event/santa/announce()
|
||||
/datum/round_event/santa/announce(fake)
|
||||
priority_announce("Santa is coming to town!", "Unknown Transmission")
|
||||
|
||||
/datum/round_event/santa/start()
|
||||
|
||||
@@ -16,7 +16,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
/datum/round_event/immovable_rod
|
||||
announceWhen = 5
|
||||
|
||||
/datum/round_event/immovable_rod/announce()
|
||||
/datum/round_event/immovable_rod/announce(fake)
|
||||
priority_announce("What the fuck was that?!", "General Alert")
|
||||
|
||||
/datum/round_event/immovable_rod/start()
|
||||
|
||||
+571
-571
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
/datum/round_event/meteor_wave/major_dust
|
||||
wave_name = "space dust"
|
||||
|
||||
/datum/round_event/meteor_wave/major_dust/announce()
|
||||
/datum/round_event/meteor_wave/major_dust/announce(fake)
|
||||
var/reason = pick(
|
||||
"The station is passing through a debris cloud, expect minor damage \
|
||||
to external fittings and fixtures.",
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/datum/round_event_control/mass_hallucination
|
||||
name = "Mass Hallucination"
|
||||
typepath = /datum/round_event/mass_hallucination
|
||||
weight = 7
|
||||
max_occurrences = 2
|
||||
min_players = 1
|
||||
|
||||
/datum/round_event/mass_hallucination/start()
|
||||
for(var/mob/living/carbon/C in GLOB.living_mob_list)
|
||||
C.hallucination += rand(20, 50)
|
||||
/datum/round_event_control/mass_hallucination
|
||||
name = "Mass Hallucination"
|
||||
typepath = /datum/round_event/mass_hallucination
|
||||
weight = 7
|
||||
max_occurrences = 2
|
||||
min_players = 1
|
||||
|
||||
/datum/round_event/mass_hallucination
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/mass_hallucination/start()
|
||||
for(var/mob/living/carbon/C in GLOB.living_mob_list)
|
||||
C.hallucination += rand(20, 50)
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
/datum/round_event/meteor_wave/meaty
|
||||
wave_name = "meaty"
|
||||
|
||||
/datum/round_event/meteor_wave/meaty/announce()
|
||||
/datum/round_event/meteor_wave/meaty/announce(fake)
|
||||
priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.",'sound/ai/meteors.ogg')
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
WARNING("Wave name of [wave_name] not recognised.")
|
||||
kill()
|
||||
|
||||
/datum/round_event/meteor_wave/announce()
|
||||
/datum/round_event/meteor_wave/announce(fake)
|
||||
priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg')
|
||||
|
||||
/datum/round_event/meteor_wave/tick()
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
weight = 10
|
||||
|
||||
/datum/round_event/mice_migration
|
||||
announceWhen = 0
|
||||
var/minimum_mice = 5
|
||||
var/maximum_mice = 15
|
||||
|
||||
/datum/round_event/mice_migration/announce()
|
||||
/datum/round_event/mice_migration/announce(fake)
|
||||
var/cause = pick("space-winter", "budget-cuts", "Ragnarok",
|
||||
"space being cold", "\[REDACTED\]", "climate change",
|
||||
"bad luck")
|
||||
@@ -22,7 +21,7 @@
|
||||
|
||||
priority_announce("Due to [cause], [plural] [name] have [movement] \
|
||||
into the [location].", "Migration Alert",
|
||||
'sound/effects/mousesqueek.ogg', 100, 1)
|
||||
'sound/effects/mousesqueek.ogg')
|
||||
|
||||
/datum/round_event/mice_migration/start()
|
||||
SSsqueak.trigger_migration(rand(minimum_mice, maximum_mice))
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
/datum/round_event/ghost_role/nightmare
|
||||
minimum_required = 1
|
||||
role_name = "nightmare"
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/ghost_role/nightmare/spawn_role()
|
||||
var/list/candidates = get_candidates("alien", null, ROLE_ALIEN)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
/datum/round_event/ghost_role/operative
|
||||
minimum_required = 1
|
||||
role_name = "lone operative"
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/ghost_role/operative/spawn_role()
|
||||
var/list/candidates = get_candidates("operative", null, ROLE_OPERATIVE)
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
#define LOOT_LOCATOR_COOLDOWN 150
|
||||
|
||||
/datum/round_event_control/pirates
|
||||
name = "Space Pirates"
|
||||
typepath = /datum/round_event/pirates
|
||||
weight = 8
|
||||
max_occurrences = 1
|
||||
min_players = 10
|
||||
earliest_start = 30 MINUTES
|
||||
gamemode_blacklist = list("nuclear")
|
||||
|
||||
/datum/round_event/pirates
|
||||
startWhen = 60 //2 minutes to answer
|
||||
var/datum/comm_message/threat
|
||||
var/payoff = 0
|
||||
var/paid_off = FALSE
|
||||
var/ship_name = "Space Privateers Association"
|
||||
var/shuttle_spawned = FALSE
|
||||
|
||||
/datum/round_event/pirates/setup()
|
||||
ship_name = pick(strings(PIRATE_NAMES_FILE, "ship_names"))
|
||||
|
||||
/datum/round_event/pirates/announce()
|
||||
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", 'sound/ai/commandreport.ogg')
|
||||
|
||||
if(!control) //Means this is false alarm, todo : explicit checks instead of using announceWhen
|
||||
return
|
||||
threat = new
|
||||
payoff = round(SSshuttle.points * 0.80)
|
||||
threat.title = "Business proposition"
|
||||
threat.content = "This is [ship_name]. Pay up [payoff] credits or you'll walk the plank."
|
||||
threat.possible_answers = list("We'll pay.","No way.")
|
||||
threat.answer_callback = CALLBACK(src,.proc/answered)
|
||||
SScommunications.send_message(threat,unique = TRUE)
|
||||
|
||||
/datum/round_event/pirates/proc/answered()
|
||||
if(threat && threat.answered == 1)
|
||||
if(SSshuttle.points >= payoff)
|
||||
SSshuttle.points -= payoff
|
||||
priority_announce("Thanks for the credits, landlubbers.",sender_override = ship_name)
|
||||
paid_off = TRUE
|
||||
return
|
||||
else
|
||||
priority_announce("Trying to cheat us ? You'll regret this!",sender_override = ship_name)
|
||||
if(!shuttle_spawned)
|
||||
spawn_shuttle()
|
||||
|
||||
|
||||
|
||||
/datum/round_event/pirates/start()
|
||||
if(!paid_off && !shuttle_spawned)
|
||||
spawn_shuttle()
|
||||
|
||||
/datum/round_event/pirates/proc/spawn_shuttle()
|
||||
shuttle_spawned = TRUE
|
||||
|
||||
var/list/candidates = pollGhostCandidates("Do you wish to be considered for pirate crew ?", ROLE_TRAITOR)
|
||||
shuffle_inplace(candidates)
|
||||
|
||||
var/datum/map_template/pirate_event_ship/ship = new
|
||||
var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width)
|
||||
var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height)
|
||||
var/z = ZLEVEL_EMPTY_SPACE
|
||||
var/turf/T = locate(x,y,z)
|
||||
if(!T)
|
||||
CRASH("Pirate event found no turf to load in")
|
||||
|
||||
if(!ship.load(T))
|
||||
CRASH("Loading pirate ship failed!")
|
||||
for(var/turf/A in ship.get_affected_turfs(T))
|
||||
for(var/obj/effect/mob_spawn/human/pirate/spawner in A)
|
||||
if(candidates.len > 0)
|
||||
var/mob/M = candidates[1]
|
||||
spawner.create(M.ckey)
|
||||
candidates -= M
|
||||
else
|
||||
notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE)
|
||||
|
||||
priority_announce("Unidentified armed ship detected near the station.")
|
||||
|
||||
//Shuttle equipment
|
||||
|
||||
/obj/machinery/shuttle_scrambler
|
||||
name = "Data Siphon"
|
||||
desc = "This heap of machinery steals credits and data from unprotected systems and locks down cargo shuttles."
|
||||
icon = 'icons/obj/machines/dominator.dmi'
|
||||
icon_state = "dominator"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/active = FALSE
|
||||
var/obj/item/device/gps/gps
|
||||
var/credits_stored = 0
|
||||
var/siphon_per_tick = 5
|
||||
|
||||
/obj/machinery/shuttle_scrambler/Initialize(mapload)
|
||||
. = ..()
|
||||
gps = new/obj/item/device/gps/internal/pirate(src)
|
||||
gps.tracking = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/shuttle_scrambler/process()
|
||||
if(active)
|
||||
if(z in GLOB.station_z_levels)
|
||||
var/siphoned = min(SSshuttle.points,siphon_per_tick)
|
||||
SSshuttle.points -= siphoned
|
||||
credits_stored += siphoned
|
||||
steal_tech()
|
||||
else
|
||||
return
|
||||
else
|
||||
STOP_PROCESSING(SSobj,src)
|
||||
|
||||
/obj/machinery/shuttle_scrambler/proc/toggle_on(mob/user)
|
||||
SSshuttle.registerTradeBlockade(src)
|
||||
gps.tracking = TRUE
|
||||
active = TRUE
|
||||
to_chat(user,"<span class='notice'>You toggle [src] [active ? "on":"off"].</span>")
|
||||
to_chat(user,"<span class='warning'>The scrambling signal can be now tracked by gps.</span>")
|
||||
START_PROCESSING(SSobj,src)
|
||||
|
||||
/obj/machinery/shuttle_scrambler/interact(mob/user)
|
||||
if(!active)
|
||||
if(alert(user, "Turning the scrambler on will make the shuttle trackable by GPS. Are you sure you want to do it ?", "Scrambler", "Yes", "Cancel") == "Cancel")
|
||||
return
|
||||
if(active || !user.canUseTopic(src))
|
||||
return
|
||||
toggle_on(user)
|
||||
update_icon()
|
||||
send_notification()
|
||||
else
|
||||
dump_loot(user)
|
||||
|
||||
//20% to sap tech levels on unlocked consoles
|
||||
/obj/machinery/shuttle_scrambler/proc/steal_tech()
|
||||
if(!prob(20))
|
||||
return
|
||||
var/datum/tech/target_tech = pick(subtypesof(/datum/tech))
|
||||
var/target_id = initial(target_tech.id)
|
||||
for(var/obj/machinery/computer/rdconsole/C in GLOB.machines)
|
||||
if(C.screen == RD_CONSOLE_LOCKED_SCREEN || C.stat & (NOPOWER|BROKEN))
|
||||
continue
|
||||
var/datum/research/files = C.files
|
||||
files.LowerTech(target_id,1)
|
||||
new /obj/effect/temp_visual/emp(get_turf(C))
|
||||
for(var/obj/machinery/r_n_d/server/S in GLOB.machines)
|
||||
if(S.stat & (NOPOWER|BROKEN))
|
||||
continue
|
||||
var/datum/research/files = S.files
|
||||
files.LowerTech(target_id,1)
|
||||
new /obj/effect/temp_visual/emp(get_turf(S))
|
||||
|
||||
/obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user)
|
||||
if(credits_stored < 200)
|
||||
to_chat(user,"<span class='notice'>Not enough credits to retrieve.</span>")
|
||||
return
|
||||
while(credits_stored >= 200)
|
||||
new /obj/item/stack/spacecash/c200(drop_location())
|
||||
credits_stored -= 200
|
||||
to_chat(user,"<span class='notice'>You retrieve the siphoned credits!</span>")
|
||||
|
||||
|
||||
/obj/machinery/shuttle_scrambler/proc/send_notification()
|
||||
priority_announce("Data theft signal detected, source registered on local gps units.")
|
||||
|
||||
/obj/machinery/shuttle_scrambler/proc/toggle_off(mob/user)
|
||||
SSshuttle.clearTradeBlockade(src)
|
||||
gps.tracking = FALSE
|
||||
active = FALSE
|
||||
STOP_PROCESSING(SSobj,src)
|
||||
|
||||
/obj/machinery/shuttle_scrambler/update_icon()
|
||||
if(active)
|
||||
icon_state = "dominator-blue"
|
||||
else
|
||||
icon_state = "dominator"
|
||||
|
||||
/obj/machinery/shuttle_scrambler/Destroy()
|
||||
toggle_off()
|
||||
QDEL_NULL(gps)
|
||||
return ..()
|
||||
|
||||
/datum/map_template/pirate_event_ship
|
||||
name = "Pirate Ship"
|
||||
mappath = "_maps/templates/pirate_ship.dmm"
|
||||
|
||||
/obj/item/device/gps/internal/pirate
|
||||
gpstag = "Nautical Signal"
|
||||
desc = "You can hear shanties over the static."
|
||||
|
||||
/obj/machinery/computer/shuttle/pirate
|
||||
name = "pirate shuttle console"
|
||||
shuttleId = "pirateship"
|
||||
icon_screen = "syndishuttle"
|
||||
icon_keyboard = "syndie_key"
|
||||
light_color = LIGHT_COLOR_RED
|
||||
possible_destinations = "pirateship_away;pirateship_home;pirateship_custom"
|
||||
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/pirate
|
||||
name = "pirate shuttle navigation computer"
|
||||
desc = "Used to designate a precise transit location for the pirate shuttle."
|
||||
shuttleId = "pirateship"
|
||||
station_lock_override = TRUE
|
||||
shuttlePortId = "pirateship_custom"
|
||||
shuttlePortName = "custom location"
|
||||
x_offset = 9
|
||||
y_offset = 0
|
||||
|
||||
/obj/docking_port/mobile/pirate
|
||||
name = "pirate shuttle"
|
||||
id = "pirateship"
|
||||
var/engines_cooling = FALSE
|
||||
var/engine_cooldown = 3 MINUTES
|
||||
|
||||
/obj/docking_port/mobile/pirate/getStatusText()
|
||||
. = ..()
|
||||
if(engines_cooling)
|
||||
return "[.] - Engines cooling."
|
||||
|
||||
/obj/docking_port/mobile/pirate/dock(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
|
||||
. = ..()
|
||||
if(. == DOCKING_SUCCESS && new_dock.z != ZLEVEL_TRANSIT)
|
||||
engines_cooling = TRUE
|
||||
addtimer(CALLBACK(src,.proc/reset_cooldown),engine_cooldown,TIMER_UNIQUE)
|
||||
|
||||
/obj/docking_port/mobile/pirate/proc/reset_cooldown()
|
||||
engines_cooling = FALSE
|
||||
|
||||
/obj/docking_port/mobile/pirate/canMove()
|
||||
if(engines_cooling)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/suit_storage_unit/pirate
|
||||
suit_type = /obj/item/clothing/suit/space
|
||||
helmet_type = /obj/item/clothing/head/helmet/space
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/oxygen
|
||||
|
||||
/obj/machinery/loot_locator
|
||||
name = "Booty Locator"
|
||||
desc = "This sophisticated machine scans the nearby space for items of value."
|
||||
icon = 'icons/obj/machines/research.dmi'
|
||||
icon_state = "tdoppler"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/cooldown = 0
|
||||
var/result_count = 3 //Show X results.
|
||||
|
||||
/obj/machinery/proc/display_current_value()
|
||||
var/area/current = get_area(src)
|
||||
var/value = 0
|
||||
for(var/turf/T in current.contents)
|
||||
value += export_item_and_contents(T,TRUE, TRUE, dry_run = TRUE)
|
||||
say("Current vault value : [value] credits.")
|
||||
|
||||
/obj/machinery/loot_locator/interact(mob/user)
|
||||
if(world.time <= cooldown)
|
||||
to_chat(user,"<span class='warning'>[src] is recharging.</span>")
|
||||
return
|
||||
cooldown = world.time + LOOT_LOCATOR_COOLDOWN
|
||||
display_current_value()
|
||||
var/list/results = list()
|
||||
for(var/atom/movable/AM in world)
|
||||
if(is_type_in_typecache(AM,GLOB.pirate_loot_cache))
|
||||
if(AM.z in GLOB.station_z_levels)
|
||||
if(get_area(AM) == get_area(src)) //Should this be variable ?
|
||||
continue
|
||||
results += AM
|
||||
CHECK_TICK
|
||||
if(!results.len)
|
||||
say("No valuables located. Try again later.")
|
||||
else
|
||||
for(var/i in 1 to result_count)
|
||||
if(!results.len)
|
||||
return
|
||||
var/atom/movable/AM = pick_n_take(results)
|
||||
var/area/loot_area = get_area(AM)
|
||||
say("Located: [AM.name] at [loot_area.name]")
|
||||
|
||||
#undef LOOT_LOCATOR_COOLDOWN
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
next_boss_spawn = startWhen + Ceiling(2 * number_of_hostiles / number_of_bosses)
|
||||
|
||||
/datum/round_event/portal_storm/announce()
|
||||
/datum/round_event/portal_storm/announce(fake)
|
||||
set waitfor = 0
|
||||
sound_to_playing_players('sound/magic/lightning_chargeup.ogg')
|
||||
sleep(80)
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
/datum/round_event_control/grey_tide
|
||||
name = "Grey Tide"
|
||||
typepath = /datum/round_event/grey_tide
|
||||
max_occurrences = 2
|
||||
min_players = 5
|
||||
|
||||
/datum/round_event/grey_tide
|
||||
announceWhen = 50
|
||||
endWhen = 20
|
||||
var/list/area/areasToOpen = list()
|
||||
var/list/potential_areas = list(/area/bridge,
|
||||
/area/engine,
|
||||
/area/medical,
|
||||
/area/security,
|
||||
/area/quartermaster,
|
||||
/area/science)
|
||||
var/severity = 1
|
||||
|
||||
|
||||
/datum/round_event/grey_tide/setup()
|
||||
announceWhen = rand(50, 60)
|
||||
endWhen = rand(20, 30)
|
||||
severity = rand(1,3)
|
||||
for(var/i in 1 to severity)
|
||||
var/picked_area = pick_n_take(potential_areas)
|
||||
for(var/area/A in world)
|
||||
if(istype(A, picked_area))
|
||||
areasToOpen += A
|
||||
|
||||
|
||||
/datum/round_event/grey_tide/announce()
|
||||
if(areasToOpen && areasToOpen.len > 0)
|
||||
priority_announce("Gr3y.T1d3 virus detected in [station_name()] door subroutines. Severity level of [severity]. Recommend station AI involvement.", "Security Alert")
|
||||
else
|
||||
log_world("ERROR: Could not initate grey-tide. No areas in the list!")
|
||||
kill()
|
||||
|
||||
|
||||
/datum/round_event/grey_tide/start()
|
||||
for(var/area/A in areasToOpen)
|
||||
for(var/obj/machinery/light/L in A)
|
||||
L.flicker(10)
|
||||
|
||||
/datum/round_event/grey_tide/end()
|
||||
for(var/area/A in areasToOpen)
|
||||
for(var/obj/O in A)
|
||||
/datum/round_event_control/grey_tide
|
||||
name = "Grey Tide"
|
||||
typepath = /datum/round_event/grey_tide
|
||||
max_occurrences = 2
|
||||
min_players = 5
|
||||
|
||||
/datum/round_event/grey_tide
|
||||
announceWhen = 50
|
||||
endWhen = 20
|
||||
var/list/area/areasToOpen = list()
|
||||
var/list/potential_areas = list(/area/bridge,
|
||||
/area/engine,
|
||||
/area/medical,
|
||||
/area/security,
|
||||
/area/quartermaster,
|
||||
/area/science)
|
||||
var/severity = 1
|
||||
|
||||
|
||||
/datum/round_event/grey_tide/setup()
|
||||
announceWhen = rand(50, 60)
|
||||
endWhen = rand(20, 30)
|
||||
severity = rand(1,3)
|
||||
for(var/i in 1 to severity)
|
||||
var/picked_area = pick_n_take(potential_areas)
|
||||
for(var/area/A in world)
|
||||
if(istype(A, picked_area))
|
||||
areasToOpen += A
|
||||
|
||||
|
||||
/datum/round_event/grey_tide/announce(fake)
|
||||
if(areasToOpen && areasToOpen.len > 0)
|
||||
priority_announce("Gr3y.T1d3 virus detected in [station_name()] door subroutines. Severity level of [severity]. Recommend station AI involvement.", "Security Alert")
|
||||
else
|
||||
log_world("ERROR: Could not initate grey-tide. No areas in the list!")
|
||||
kill()
|
||||
|
||||
|
||||
/datum/round_event/grey_tide/start()
|
||||
for(var/area/A in areasToOpen)
|
||||
for(var/obj/machinery/light/L in A)
|
||||
L.flicker(10)
|
||||
|
||||
/datum/round_event/grey_tide/end()
|
||||
for(var/area/A in areasToOpen)
|
||||
for(var/obj/O in A)
|
||||
if(istype(O, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/temp = O
|
||||
temp.overload_lighting()
|
||||
var/obj/machinery/power/apc/temp = O
|
||||
temp.overload_lighting()
|
||||
else if(istype(O, /obj/structure/closet/secure_closet))
|
||||
var/obj/structure/closet/secure_closet/temp = O
|
||||
var/obj/structure/closet/secure_closet/temp = O
|
||||
temp.locked = FALSE
|
||||
temp.update_icon()
|
||||
temp.update_icon()
|
||||
else if(istype(O, /obj/machinery/door/airlock))
|
||||
var/obj/machinery/door/airlock/temp = O
|
||||
temp.prison_open()
|
||||
var/obj/machinery/door/airlock/temp = O
|
||||
temp.prison_open()
|
||||
else if(istype(O, /obj/machinery/door_timer))
|
||||
var/obj/machinery/door_timer/temp = O
|
||||
temp.timer_end(forced = TRUE)
|
||||
var/obj/machinery/door_timer/temp = O
|
||||
temp.timer_end(forced = TRUE)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/datum/round_event/processor_overload
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/processor_overload/announce()
|
||||
/datum/round_event/processor_overload/announce(fake)
|
||||
var/alert = pick( "Exospheric bubble inbound. Processor overload is likely. Please contact you*%xp25)`6cq-BZZT", \
|
||||
"Exospheric bubble inbound. Processor overload is likel*1eta;c5;'1v¬-BZZZT", \
|
||||
"Exospheric bubble inbound. Processor ov#MCi46:5.;@63-BZZZZT", \
|
||||
@@ -22,7 +22,7 @@
|
||||
// Announce most of the time, but leave a little gap so people don't know
|
||||
// whether it's, say, a tesla zapping tcomms, or some selective
|
||||
// modification of the tcomms bus
|
||||
if(prob(80))
|
||||
if(prob(80) || fake)
|
||||
priority_announce(alert)
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
endWhen = startWhen + 1
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/radiation_storm/announce()
|
||||
/datum/round_event/radiation_storm/announce(fake)
|
||||
priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", 'sound/ai/radiation.ogg')
|
||||
//sound not longer matches the text, but an audible warning is probably good
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
var/animals = 1
|
||||
var/one = "one"
|
||||
|
||||
/datum/round_event/ghost_role/sentience/start()
|
||||
var/sentience_report = "<font size=3><b>[command_name()] Medium-Priority Update</b></font>"
|
||||
/datum/round_event/ghost_role/sentience/announce(fake)
|
||||
var/sentience_report = ""
|
||||
|
||||
var/data = pick("scans from our long-range sensors", "our sophisticated probabilistic models", "our omnipotence", "the communications traffic on your station", "energy emissions we detected", "\[REDACTED\]")
|
||||
var/pets = pick("animals/bots", "bots/animals", "pets", "simple animals", "lesser lifeforms", "\[REDACTED\]")
|
||||
@@ -19,8 +19,7 @@
|
||||
|
||||
sentience_report += "<br><br>Based on [data], we believe that [one] of the station's [pets] has developed [strength] level intelligence, and the ability to communicate."
|
||||
|
||||
print_command_report(text=sentience_report)
|
||||
..()
|
||||
priority_announce(sentience_report,"[command_name()] Medium-Priority Update")
|
||||
|
||||
/datum/round_event/ghost_role/sentience/spawn_role()
|
||||
var/list/mob/dead/observer/candidates
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
var/bonus_points = 10000
|
||||
var/thanks_msg = "The cargo shuttle should return in five minutes. Have some supply points for your trouble."
|
||||
|
||||
/datum/round_event/shuttle_loan/start()
|
||||
/datum/round_event/shuttle_loan/setup()
|
||||
dispatch_type = pick(HIJACK_SYNDIE, RUSKY_PARTY, SPIDER_GIFT, DEPARTMENT_RESUPPLY, ANTIDOTE_NEEDED, PIZZA_DELIVERY)
|
||||
|
||||
/datum/round_event/shuttle_loan/announce()
|
||||
/datum/round_event/shuttle_loan/announce(fake)
|
||||
SSshuttle.shuttle_loan = src
|
||||
switch(dispatch_type)
|
||||
if(HIJACK_SYNDIE)
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
max_occurrences = 3
|
||||
min_players = 10
|
||||
|
||||
/datum/round_event/spacevine
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/spacevine/start()
|
||||
var/list/turfs = list() //list of all the empty floor turfs in the hallway areas
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
announceWhen = rand(announceWhen, announceWhen + 50)
|
||||
spawncount = rand(5, 8)
|
||||
|
||||
/datum/round_event/spider_infestation/announce()
|
||||
/datum/round_event/spider_infestation/announce(fake)
|
||||
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg')
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
/datum/round_event_control/spontaneous_appendicitis
|
||||
name = "Spontaneous Appendicitis"
|
||||
typepath = /datum/round_event/spontaneous_appendicitis
|
||||
weight = 20
|
||||
max_occurrences = 4
|
||||
earliest_start = 6000
|
||||
min_players = 5 // To make your chance of getting help a bit higher.
|
||||
|
||||
/datum/round_event/spontaneous_appendicitis/start()
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
|
||||
/datum/round_event_control/spontaneous_appendicitis
|
||||
name = "Spontaneous Appendicitis"
|
||||
typepath = /datum/round_event/spontaneous_appendicitis
|
||||
weight = 20
|
||||
max_occurrences = 4
|
||||
earliest_start = 6000
|
||||
min_players = 5 // To make your chance of getting help a bit higher.
|
||||
|
||||
/datum/round_event/spontaneous_appendicitis
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/spontaneous_appendicitis/start()
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
|
||||
if(!H.client)
|
||||
continue
|
||||
if(H.stat == DEAD)
|
||||
@@ -19,8 +22,8 @@
|
||||
foundAlready = TRUE
|
||||
break
|
||||
if(foundAlready)
|
||||
continue
|
||||
|
||||
var/datum/disease/D = new /datum/disease/appendicitis
|
||||
H.ForceContractDisease(D)
|
||||
break
|
||||
continue
|
||||
|
||||
var/datum/disease/D = new /datum/disease/appendicitis
|
||||
H.ForceContractDisease(D)
|
||||
break
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/list/gunk = list("water","carbon","flour","radium","toxin","cleaner","nutriment","condensedcapsaicin","mushroomhallucinogen","lube",
|
||||
"plantbgone","banana","charcoal","space_drugs","morphine","holywater","ethanol","hot_coco","sacid")
|
||||
|
||||
/datum/round_event/vent_clog/announce()
|
||||
/datum/round_event/vent_clog/announce(fake)
|
||||
priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert")
|
||||
|
||||
|
||||
|
||||
@@ -1,32 +1,30 @@
|
||||
/datum/round_event_control/weightless
|
||||
name = "Gravity Systems Failure"
|
||||
typepath = /datum/round_event/weightless
|
||||
weight = 15
|
||||
|
||||
/datum/round_event/weightless
|
||||
startWhen = 5
|
||||
endWhen = 65
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/weightless/setup()
|
||||
startWhen = rand(0,10)
|
||||
endWhen = rand(40,80)
|
||||
|
||||
/datum/round_event/weightless/announce()
|
||||
command_alert("Warning: Failsafes for the station's artificial gravity arrays have been triggered. Please be aware that if this problem recurs it may result in formation of gravitational anomalies. Nanotrasen wishes to remind you that the unauthorised formation of anomalies within Nanotrasen facilities is strictly prohibited by health and safety regulation [rand(99,9999)][pick("a","b","c")]:subclause[rand(1,20)][pick("a","b","c")].")
|
||||
|
||||
/datum/round_event/weightless/start()
|
||||
for(var/area/A in world)
|
||||
A.gravitychange(0)
|
||||
|
||||
if(control)
|
||||
control.weight *= 2
|
||||
|
||||
/datum/round_event/weightless/end()
|
||||
for(var/area/A in world)
|
||||
A.gravitychange(1)
|
||||
|
||||
if(announceWhen >= 0)
|
||||
command_alert("Artificial gravity arrays are now functioning within normal parameters. Please report any irregularities to your respective head of staff.")
|
||||
|
||||
|
||||
/datum/round_event_control/weightless
|
||||
name = "Gravity Systems Failure"
|
||||
typepath = /datum/round_event/weightless
|
||||
weight = 15
|
||||
|
||||
/datum/round_event/weightless
|
||||
startWhen = 5
|
||||
endWhen = 65
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/weightless/setup()
|
||||
startWhen = rand(0,10)
|
||||
endWhen = rand(40,80)
|
||||
|
||||
/datum/round_event/weightless/announce(fake)
|
||||
command_alert("Warning: Failsafes for the station's artificial gravity arrays have been triggered. Please be aware that if this problem recurs it may result in formation of gravitational anomalies. Nanotrasen wishes to remind you that the unauthorised formation of anomalies within Nanotrasen facilities is strictly prohibited by health and safety regulation [rand(99,9999)][pick("a","b","c")]:subclause[rand(1,20)][pick("a","b","c")].")
|
||||
|
||||
/datum/round_event/weightless/start()
|
||||
for(var/area/A in world)
|
||||
A.gravitychange(0)
|
||||
|
||||
if(control)
|
||||
control.weight *= 2
|
||||
|
||||
/datum/round_event/weightless/end()
|
||||
for(var/area/A in world)
|
||||
A.gravitychange(1)
|
||||
|
||||
if(announceWhen >= 0)
|
||||
command_alert("Artificial gravity arrays are now functioning within normal parameters. Please report any irregularities to your respective head of staff.")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/datum/round_event/wizard/magicarp/setup()
|
||||
startWhen = rand(40, 60)
|
||||
|
||||
/datum/round_event/wizard/magicarp/announce()
|
||||
/datum/round_event/wizard/magicarp/announce(fake)
|
||||
priority_announce("Unknown magical entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
|
||||
|
||||
/datum/round_event/wizard/magicarp/start()
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
var/turf/T = pick(pick_turfs)
|
||||
wormholes += new /obj/effect/portal/wormhole(T, null, 0, null, FALSE)
|
||||
|
||||
/datum/round_event/wormholes/announce()
|
||||
/datum/round_event/wormholes/announce(fake)
|
||||
priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", 'sound/ai/spanomalies.ogg')
|
||||
|
||||
/datum/round_event/wormholes/tick()
|
||||
|
||||
@@ -13,7 +13,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
var/cookieSent = FALSE // Has the client sent a cookie for analysis
|
||||
var/broken = FALSE
|
||||
var/list/connectionHistory //Contains the connection history passed from chat cookie
|
||||
var/adminMusicVolume = 100 //This is for the Play Global Sound verb
|
||||
var/adminMusicVolume = 25 //This is for the Play Global Sound verb
|
||||
|
||||
/datum/chatOutput/New(client/C)
|
||||
owner = C
|
||||
|
||||
@@ -65,6 +65,8 @@ var opts = {
|
||||
'volumeUpdateDelay': 5000, //Time from when the volume updates to data being sent to the server
|
||||
'volumeUpdating': false, //True if volume update function set to fire
|
||||
'updatedVolume': 0, //The volume level that is sent to the server
|
||||
|
||||
'defaultMusicVolume': 25,
|
||||
|
||||
};
|
||||
|
||||
@@ -604,6 +606,8 @@ $(function() {
|
||||
opts.updatedVolume = newVolume;
|
||||
sendVolumeUpdate();
|
||||
internalOutput('<span class="internal boldnshit">Loaded music volume of: '+savedConfig.smusicVolume+'</span>', 'internal');
|
||||
} else {
|
||||
$('#adminMusic').prop('volume', opts.defaultMusicVolume / 100);
|
||||
}
|
||||
|
||||
(function() {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
max_occurrences = 1
|
||||
earliest_start = 0
|
||||
|
||||
/datum/round_event/easter/announce()
|
||||
/datum/round_event/easter/announce(fake)
|
||||
priority_announce(pick("Hip-hop into Easter!","Find some Bunny's stash!","Today is National 'Hunt a Wabbit' Day.","Be kind, give Chocolate Eggs!"))
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
weight = 5
|
||||
max_occurrences = 10
|
||||
|
||||
/datum/round_event/rabbitrelease/announce()
|
||||
/datum/round_event/rabbitrelease/announce(fake)
|
||||
priority_announce("Unidentified furry objects detected coming aboard [station_name()]. Beware of Adorable-ness.", "Fluffy Alert", 'sound/ai/aliens.ogg')
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
|
||||
|
||||
/obj/item/device/integrated_electronics/analyzer
|
||||
name = "circuit analyzer"
|
||||
desc = "This tool can scan an assembly and generate code necessary to recreate it in a circuit printer."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "analyzer"
|
||||
flags_1 = CONDUCT_1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/list/circuit_list = list()
|
||||
var/list/assembly_list = list(/obj/item/device/electronic_assembly,
|
||||
/obj/item/device/electronic_assembly/medium,
|
||||
/obj/item/device/electronic_assembly/large,
|
||||
/obj/item/device/electronic_assembly/drone)
|
||||
|
||||
/obj/item/device/integrated_electronics/analyzer/afterattack(var/atom/A, var/mob/living/user)
|
||||
visible_message( "<span class='notice'>attempt to scan</span>")
|
||||
if(ispath(A.type,/obj/item/device/electronic_assembly))
|
||||
var/i = 0
|
||||
var/j = 0
|
||||
var/HTML ="start.assembly{{*}}" //1-st in chapters.1-st block is just to secure start of program from excess symbols.{{*}} is delimeter for chapters.
|
||||
visible_message( "<span class='notice'>start of scan</span>")
|
||||
for(var/ix in 1 to assembly_list.len)
|
||||
var/obj/item/I = assembly_list[ix]
|
||||
if( A.type == I )
|
||||
HTML += initial(I.name) +"=-="+A.name //2-nd block.assembly type and name. Maybe in future there will also be color and accesories.
|
||||
break
|
||||
/*
|
||||
If(I.name == "electronic implant")
|
||||
var/obj/item/weapon/implant/integrated_circuit/PI = PA //now it can't recreate electronic implants.and devices maybe I'll fix it later.
|
||||
var/obj/item/device/electronic_assembly/implant/PIC = PI.IC
|
||||
A = PIC
|
||||
*/
|
||||
HTML += "{{*}}components" //3-rd block.components. First element is useless.delimeter for elements is ^%^.In element first circuit's default name.Second is user given name.delimiter is =-=
|
||||
|
||||
for(var/obj/item/integrated_circuit/IC in A.contents)
|
||||
i =i + 1
|
||||
HTML += "^%^"+IC.name+"=-="+IC.displayed_name
|
||||
if(i == 0)
|
||||
return
|
||||
HTML += "{{*}}values" //4-th block.values. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second is data type.third is value.delimiter is :+:
|
||||
|
||||
i = 0
|
||||
var/val
|
||||
var/list/inp=list()
|
||||
var/list/out=list()
|
||||
var/list/act=list()
|
||||
var/list/ioa=list()
|
||||
for(var/obj/item/integrated_circuit/IC in A.contents)
|
||||
i += 1
|
||||
if(IC.inputs && IC.inputs.len)
|
||||
for(j in 1 to IC.inputs.len)
|
||||
var/datum/integrated_io/IN =IC.inputs[j]
|
||||
inp[IN] = "[i]i[j]"
|
||||
if(islist(IN.data))
|
||||
val = list2params(IN.data)
|
||||
HTML += "^%^"+"[i]i[j]:+:list:+:[val]"
|
||||
else if(isnum(IN.data))
|
||||
val= IN.data
|
||||
HTML += "^%^"+"[i]i[j]:+:num:+:[val]"
|
||||
else if(istext(IN.data))
|
||||
val = IN.data
|
||||
HTML += "^%^"+"[i]i[j]:+:text:+:[val]"
|
||||
if(IC.outputs && IC.outputs.len)
|
||||
for(j in 1 to IC.outputs.len) //Also this block uses for setting all i/o id's
|
||||
var/datum/integrated_io/OUT = IC.outputs[j]
|
||||
out[OUT] = "[i]o[j]"
|
||||
if(IC.activators && IC.activators.len)
|
||||
for(j in 1 to IC.activators.len)
|
||||
var/datum/integrated_io/ACT = IC.activators[j]
|
||||
act[ACT] = "[i]a[j]"
|
||||
ioa.Add(inp)
|
||||
ioa.Add(out)
|
||||
ioa.Add(act)
|
||||
HTML += "{{*}}wires"
|
||||
if(inp && inp.len)
|
||||
for(i in 1 to inp.len) //5-th block.wires. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second too.delimiter is =-=
|
||||
var/datum/integrated_io/P = inp[i]
|
||||
for(j in 1 to P.linked.len)
|
||||
var/datum/integrated_io/C = P.linked[j]
|
||||
HTML += "^%^"+inp[P]+"=-="+ioa[C]
|
||||
if(out && out.len)
|
||||
for(i in 1 to out.len) //5-th block.wires. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second too.delimiter is =-=
|
||||
var/datum/integrated_io/P = out[i]
|
||||
for(j in 1 to P.linked.len)
|
||||
var/datum/integrated_io/C = P.linked[j]
|
||||
HTML += "^%^"+out[P]+"=-="+ioa[C]
|
||||
if(act && act.len)
|
||||
for(i in 1 to act.len) //5-th block.wires. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second too.delimiter is =-=
|
||||
var/datum/integrated_io/P = act[i]
|
||||
for(j in 1 to P.linked.len)
|
||||
var/datum/integrated_io/C = P.linked[j]
|
||||
HTML += "^%^"+act[P]+"=-="+ioa[C]
|
||||
|
||||
HTML += "{{*}}end" //6 block.like 1.
|
||||
visible_message( "<span class='notice'>[A] has been scanned,</span>")
|
||||
user << browse(jointext(HTML, null), "window=analyzer;size=[500]x[600];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
#define IC_MAX_SIZE_BASE 25
|
||||
#define IC_COMPLEXITY_BASE 75
|
||||
|
||||
/obj/item/device/electronic_assembly
|
||||
name = "electronic assembly"
|
||||
desc = "It's a case, for building small electronics with."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "setup_small"
|
||||
flags_1 = NOBLUDGEON_1
|
||||
var/max_components = IC_MAX_SIZE_BASE
|
||||
var/max_complexity = IC_COMPLEXITY_BASE
|
||||
var/opened = FALSE
|
||||
var/obj/item/stock_parts/cell/battery // Internal cell which most circuits need to work.
|
||||
var/cell_type = /obj/item/stock_parts/cell
|
||||
var/can_charge = TRUE //Can it be charged in a recharger?
|
||||
var/charge_sections = 4
|
||||
var/charge_tick = FALSE
|
||||
var/charge_delay = 4
|
||||
var/use_cyborg_cell = TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/check_interactivity(mob/user)
|
||||
return user.canUseTopic(src,be_close = TRUE)
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/medium
|
||||
name = "electronic mechanism"
|
||||
icon_state = "setup_medium"
|
||||
desc = "It's a case, for building medium-sized electronics with."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
max_components = IC_MAX_SIZE_BASE * 2
|
||||
max_complexity = IC_COMPLEXITY_BASE * 2
|
||||
|
||||
/obj/item/device/electronic_assembly/large
|
||||
name = "electronic machine"
|
||||
icon_state = "setup_large"
|
||||
desc = "It's a case, for building large electronics with."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
max_components = IC_MAX_SIZE_BASE * 4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 4
|
||||
anchored = FALSE
|
||||
|
||||
/obj/item/device/electronic_assembly/large/attackby(var/obj/item/O, var/mob/user)
|
||||
if(default_unfasten_wrench(user, O, 20))
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/electronic_assembly/large/attack_tk(mob/user)
|
||||
if(anchored)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/electronic_assembly/large/attack_hand(mob/user)
|
||||
if(anchored)
|
||||
attack_self(user)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/electronic_assembly/drone
|
||||
name = "electronic drone"
|
||||
icon_state = "setup_drone"
|
||||
desc = "It's a case, for building mobile electronics with."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
max_components = IC_MAX_SIZE_BASE * 3
|
||||
max_complexity = IC_COMPLEXITY_BASE * 3
|
||||
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/Initialize()
|
||||
.=..()
|
||||
START_PROCESSING(SScircuit, src)
|
||||
|
||||
/obj/item/device/electronic_assembly/Destroy()
|
||||
STOP_PROCESSING(SScircuit, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/electronic_assembly/process()
|
||||
handle_idle_power()
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/handle_idle_power()
|
||||
// First we generate power.
|
||||
for(var/obj/item/integrated_circuit/passive/power/P in contents)
|
||||
P.make_energy()
|
||||
|
||||
// Now spend it.
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
if(IC.power_draw_idle)
|
||||
if(!draw_power(IC.power_draw_idle))
|
||||
IC.power_fail()
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/interact(mob/user)
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
|
||||
var/total_part_size = return_total_size()
|
||||
var/total_complexity = return_total_complexity()
|
||||
var/HTML = list()
|
||||
|
||||
HTML += "<html><head><title>[name]</title></head><body>"
|
||||
HTML += "<br><a href='?src=[REF(src)]'>\[Refresh\]</a> | "
|
||||
HTML += "<a href='?src=[REF(src)];rename=1'>\[Rename\]</a><br>"
|
||||
HTML += "[total_part_size]/[max_components] ([round((total_part_size / max_components) * 100, 0.1)]%) space taken up in the assembly.<br>"
|
||||
HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.<br>"
|
||||
if(battery)
|
||||
HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. <a href='?src=[REF(src)];remove_cell=1'>\[Remove\]</a>"
|
||||
else
|
||||
HTML += "<span class='danger'>No powercell detected!</span>"
|
||||
HTML += "<br><br>"
|
||||
HTML += "Components:<hr>"
|
||||
HTML += "Built in:<br>"
|
||||
|
||||
|
||||
//Put removable circuits in separate categories from non-removable
|
||||
for(var/obj/item/integrated_circuit/circuit in contents)
|
||||
if(!circuit.removable)
|
||||
HTML += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];bottom=[REF(circuit)];from_assembly=1>\[Move to Bottom\]</a>"
|
||||
HTML += "<br>"
|
||||
|
||||
HTML += "<hr>"
|
||||
HTML += "Removable:<br>"
|
||||
|
||||
for(var/obj/item/integrated_circuit/circuit in contents)
|
||||
if(circuit.removable)
|
||||
HTML += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];remove=1;from_assembly=1>\[Remove\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];bottom=[REF(circuit)];from_assembly=1>\[Move to Bottom\]</a>"
|
||||
HTML += "<br>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
user << browse(jointext(HTML,null), "window=assembly-\[REF(src)];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
|
||||
/obj/item/device/electronic_assembly/Topic(href, href_list[])
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["rename"])
|
||||
rename(usr)
|
||||
|
||||
if(href_list["remove_cell"])
|
||||
if(!battery)
|
||||
to_chat(usr, "<span class='warning'>There's no power cell to remove from \the [src].</span>")
|
||||
else
|
||||
var/turf/T = get_turf(src)
|
||||
battery.forceMove(T)
|
||||
playsound(T, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
to_chat(usr, "<span class='notice'>You pull \the [battery] out of \the [src]'s power supplier.</span>")
|
||||
battery = null
|
||||
|
||||
interact(usr) // To refresh the UI.
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/rename()
|
||||
|
||||
var/mob/M = usr
|
||||
if(!check_interactivity(M))
|
||||
return
|
||||
|
||||
var/input = reject_bad_name(input("What do you want to name this?", "Rename", src.name) as null|text,1)
|
||||
if(!check_interactivity(M))
|
||||
return
|
||||
if(src && input)
|
||||
to_chat(M, "<span class='notice'>The machine now has a label reading '[input]'.</span>")
|
||||
name = input
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/can_move()
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/can_move()
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/update_icon()
|
||||
if(opened)
|
||||
icon_state = initial(icon_state) + "-open"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/device/electronic_assembly/examine(mob/user)
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
IC.external_examine(user)
|
||||
if(istype(IC,/obj/item/integrated_circuit/output/screen))
|
||||
var/obj/item/integrated_circuit/output/screen/S
|
||||
if(S.stuff_to_display)
|
||||
to_chat(user, "There's a little screen labeled '[S]', which displays '[S.stuff_to_display]'.")
|
||||
if(opened)
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/return_total_complexity()
|
||||
. = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
. += part.complexity
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/return_total_size()
|
||||
. = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
. += part.size
|
||||
|
||||
// Returns true if the circuit made it inside.
|
||||
/obj/item/device/electronic_assembly/proc/add_circuit(var/obj/item/integrated_circuit/IC, var/mob/user)
|
||||
if(!opened)
|
||||
to_chat(user, "<span class='warning'>\The [src] isn't opened, so you can't put anything inside. Try using a crowbar.</span>")
|
||||
return FALSE
|
||||
|
||||
if(IC.w_class > w_class)
|
||||
to_chat(user, "<span class='warning'>\The [IC] is way too big to fit into \the [src].</span>")
|
||||
return FALSE
|
||||
|
||||
var/total_part_size = return_total_size()
|
||||
var/total_complexity = return_total_complexity()
|
||||
|
||||
if((total_part_size + IC.size) > max_components)
|
||||
to_chat(user, "<span class='warning'>You can't seem to add the '[IC]', as there's insufficient space.</span>")
|
||||
return FALSE
|
||||
if((total_complexity + IC.complexity) > max_complexity)
|
||||
to_chat(user, "<span class='warning'>You can't seem to add the '[IC]', since this setup's too complicated for the case.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!user.transferItemToLoc(IC, src))
|
||||
return FALSE
|
||||
|
||||
IC.assembly = src
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity)
|
||||
for(var/obj/item/integrated_circuit/input/sensor/S in contents)
|
||||
if(!proximity)
|
||||
if(istype(S,/obj/item/integrated_circuit/input/sensor/ranged)||(!user))
|
||||
if(user.client)
|
||||
if(!(target in view(user.client)))
|
||||
continue
|
||||
else
|
||||
if(!(target in view(user)))
|
||||
continue
|
||||
else
|
||||
continue
|
||||
S.set_pin_data(IC_OUTPUT, 1, WEAKREF(target))
|
||||
S.check_then_do_work()
|
||||
S.scan(target)
|
||||
|
||||
visible_message("<span class='notice'> [user] waves [src] around [target].</span>")
|
||||
|
||||
/obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user)
|
||||
if(istype(I, /obj/item/integrated_circuit))
|
||||
if(!user.canUnEquip(I))
|
||||
return FALSE
|
||||
if(add_circuit(I, user))
|
||||
to_chat(user, "<span class='notice'>You slide [I] inside [src].</span>")
|
||||
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
interact(user)
|
||||
return TRUE
|
||||
else if(istype(I, /obj/item/crowbar))
|
||||
playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
|
||||
opened = !opened
|
||||
to_chat(user, "<span class='notice'>You [opened ? "opened" : "closed"] [src].</span>")
|
||||
update_icon()
|
||||
return TRUE
|
||||
else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger) || istype(I, /obj/item/screwdriver))
|
||||
if(opened)
|
||||
interact(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'> [src] isn't opened, so you can't fiddle with the internal components. \
|
||||
Try using a crowbar.</span>")
|
||||
else if(istype(I, /obj/item/stock_parts/cell))
|
||||
if(!opened)
|
||||
to_chat(user, "<span class='warning'> [src] isn't opened, so you can't put anything inside. Try using a crowbar.</span>")
|
||||
return FALSE
|
||||
if(battery)
|
||||
to_chat(user, "<span class='warning'> [src] already has \a [battery] inside. Remove it first if you want to replace it.</span>")
|
||||
return FALSE
|
||||
var/obj/item/stock_parts/cell = I
|
||||
user.transferItemToLoc(I, loc)
|
||||
cell.forceMove(src)
|
||||
battery = cell
|
||||
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
to_chat(user, "<span class='notice'>You slot \the [cell] inside \the [src]'s power supplier.</span>")
|
||||
interact(user)
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/electronic_assembly/attack_self(mob/user)
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
if(opened)
|
||||
interact(user)
|
||||
|
||||
var/list/input_selection = list()
|
||||
var/list/available_inputs = list()
|
||||
for(var/obj/item/integrated_circuit/input/input in contents)
|
||||
if(input.can_be_asked_input)
|
||||
available_inputs.Add(input)
|
||||
var/i = 0
|
||||
for(var/obj/item/integrated_circuit/s in available_inputs)
|
||||
if(s.name == input.name && s.displayed_name == input.displayed_name && s != input)
|
||||
i++
|
||||
var/disp_name= "[input.displayed_name] \[[input]\]"
|
||||
if(i)
|
||||
disp_name += " ([i+1])"
|
||||
input_selection.Add(disp_name)
|
||||
|
||||
var/obj/item/integrated_circuit/input/choice
|
||||
if(available_inputs)
|
||||
if(available_inputs.len ==1)
|
||||
choice = available_inputs[1]
|
||||
else
|
||||
var/selection = input(user, "What do you want to interact with?", "Interaction") as null|anything in input_selection
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
if(selection)
|
||||
var/index = input_selection.Find(selection)
|
||||
choice = available_inputs[index]
|
||||
|
||||
if(choice)
|
||||
choice.ask_for_input(user)
|
||||
|
||||
/obj/item/device/electronic_assembly/emp_act(severity)
|
||||
..()
|
||||
for(var/i in 1 to contents.len)
|
||||
var/atom/movable/AM = contents[i]
|
||||
AM.emp_act(severity)
|
||||
|
||||
// Returns true if power was successfully drawn.
|
||||
/obj/item/device/electronic_assembly/proc/draw_power(amount)
|
||||
if(battery && battery.use(amount * GLOB.CELLRATE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// Ditto for giving.
|
||||
/obj/item/device/electronic_assembly/proc/give_power(amount)
|
||||
if(battery && battery.give(amount * GLOB.CELLRATE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/electronic_assembly/Moved(oldLoc, dir)
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
IC.ext_moved(oldLoc, dir)
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
/obj/item/device/integrated_electronics/debugger
|
||||
name = "circuit debugger"
|
||||
desc = "This small tool allows one working with custom machinery to directly set data to a specific pin, useful for writing \
|
||||
settings to specific circuits, or for debugging purposes. It can also pulse activation pins."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "debugger"
|
||||
flags_1 = CONDUCT_1 | NOBLUDGEON_1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/data_to_write = null
|
||||
var/accepting_refs = FALSE
|
||||
|
||||
/obj/item/device/integrated_electronics/debugger/attack_self(mob/user)
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null")
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return
|
||||
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
accepting_refs = FALSE
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
if(istext(new_data) && user.IsAdvancedToolUser())
|
||||
data_to_write = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to \"[new_data]\".</span>")
|
||||
if("number")
|
||||
accepting_refs = FALSE
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && user.IsAdvancedToolUser())
|
||||
data_to_write = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to [new_data].</span>")
|
||||
if("ref")
|
||||
accepting_refs = TRUE
|
||||
to_chat(user, "<span class='notice'>You turn \the [src]'s ref scanner on. Slide it across \
|
||||
an object for a ref of that object to save it in memory.</span>")
|
||||
if("null")
|
||||
data_to_write = null
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to absolutely nothing.</span>")
|
||||
|
||||
/obj/item/device/integrated_electronics/debugger/afterattack(atom/target, mob/living/user, proximity)
|
||||
if(accepting_refs && proximity)
|
||||
data_to_write = WEAKREF(target)
|
||||
visible_message("<span class='notice'>[user] slides \a [src]'s over \the [target].</span>")
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to a reference to [target.name] \[Ref\]. The ref scanner is \
|
||||
now off.</span>")
|
||||
accepting_refs = FALSE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/integrated_electronics/debugger/proc/write_data(var/datum/integrated_io/io, mob/user)
|
||||
if(io.io_type == DATA_CHANNEL)
|
||||
io.write_data_to_pin(data_to_write)
|
||||
var/data_to_show = data_to_write
|
||||
if(isweakref(data_to_write))
|
||||
var/datum/weakref/w = data_to_write
|
||||
var/atom/A = w.resolve()
|
||||
data_to_show = A.name
|
||||
to_chat(user, "<span class='notice'>You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].</span>")
|
||||
else if(io.io_type == PULSE_CHANNEL)
|
||||
io.holder.check_then_do_work(ignore_power = TRUE)
|
||||
to_chat(user, "<span class='notice'>You pulse \the [io.holder]'s [io].</span>")
|
||||
|
||||
io.holder.interact(user) // This is to update the UI.
|
||||
@@ -0,0 +1,136 @@
|
||||
/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type, var/list/io_default_list)
|
||||
var/list/io_list_copy = io_list.Copy()
|
||||
io_list.Cut()
|
||||
for(var/i in 1 to io_list_copy.len)
|
||||
var/io_entry = io_list_copy[i]
|
||||
var/default_data = null
|
||||
var/io_type_override = null
|
||||
// Override the default data.
|
||||
if(io_default_list && io_default_list.len) // List containing special pin types that need to be added.
|
||||
default_data = io_default_list["[i]"] // This is deliberately text because the index is a number in text form.
|
||||
// Override the pin type.
|
||||
if(io_list_copy[io_entry])
|
||||
io_type_override = io_list_copy[io_entry]
|
||||
|
||||
if(io_type_override)
|
||||
// world << "io_type_override is now [io_type_override] on [src]."
|
||||
io_list.Add(new io_type_override(src, io_entry, default_data))
|
||||
else
|
||||
io_list.Add(new io_type(src, io_entry, default_data))
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/proc/set_pin_data(var/pin_type, var/pin_number, datum/new_data)
|
||||
if (istype(new_data) && !isweakref(new_data))
|
||||
new_data = WEAKREF(new_data)
|
||||
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
|
||||
return pin.write_data_to_pin(new_data)
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_data(var/pin_type, var/pin_number)
|
||||
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
|
||||
return pin.get_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_data_as_type(var/pin_type, var/pin_number, var/as_type)
|
||||
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
|
||||
return pin.data_as_type(as_type)
|
||||
|
||||
/obj/item/integrated_circuit/proc/activate_pin(var/pin_number)
|
||||
var/datum/integrated_io/activate/A = activators[pin_number]
|
||||
A.push_data()
|
||||
|
||||
/datum/integrated_io/proc/get_data()
|
||||
if(isweakref(data))
|
||||
return data.resolve()
|
||||
return data
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number)
|
||||
switch(pin_type)
|
||||
if(IC_INPUT)
|
||||
if(pin_number > inputs.len)
|
||||
return
|
||||
return inputs[pin_number]
|
||||
if(IC_OUTPUT)
|
||||
if(pin_number > outputs.len)
|
||||
return
|
||||
return outputs[pin_number]
|
||||
if(IC_ACTIVATOR)
|
||||
if(pin_number > activators.len)
|
||||
return
|
||||
return activators[pin_number]
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/handle_wire(var/datum/integrated_io/pin, var/obj/item/device/integrated_electronics/tool)
|
||||
if(istype(tool, /obj/item/device/integrated_electronics/wirer))
|
||||
var/obj/item/device/integrated_electronics/wirer/wirer = tool
|
||||
if(pin)
|
||||
wirer.wire(pin, usr)
|
||||
return TRUE
|
||||
|
||||
else if(istype(tool, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/debugger = tool
|
||||
if(pin)
|
||||
debugger.write_data(pin, usr)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/proc/asc2b64(var/S)
|
||||
var/static/list/b64 = list(
|
||||
"A"=0,"B"=1,"C"=2,"D"=3,
|
||||
"E"=4,"F"=5,"G"=6,"H"=7,
|
||||
"I"=8,"J"=9,"K"=10,"L"=11,
|
||||
"M"=12,"N"=13,"O"=14,"P"=15,
|
||||
"Q"=16,"R"=17,"S"=18,"T"=19,
|
||||
"U"=20,"V"=21,"W"=22,"X"=23,
|
||||
"Y"=24,"Z"=25,"a"=26,"b"=27,
|
||||
"c"=28,"d"=29,"e"=30,"f"=31,
|
||||
"g"=32,"h"=33,"i"=34,"j"=35,
|
||||
"k"=36,"l"=37,"m"=38,"n"=39,
|
||||
"o"=40,"p"=41,"q"=42,"r"=43,
|
||||
"s"=44,"t"=45,"u"=46,"v"=47,
|
||||
"w"=48,"x"=49,"y"=50,"z"=51,
|
||||
"0"=52,"1"=53,"2"=54,"3"=55,
|
||||
"4"=56,"5"=57,"6"=58,"7"=59,
|
||||
"8"=60,"9"=61,","=62,"."=63
|
||||
)
|
||||
var/ls = lentext(S)
|
||||
var/c
|
||||
var/i=1
|
||||
while(i <= ls)
|
||||
var/sb1=text2ascii(S,i)
|
||||
var/sb2=text2ascii(S,i+1)
|
||||
var/sb3=text2ascii(S,i+2)
|
||||
var/cb1 = (sb1 & 252)>>2
|
||||
var/cb2 = ((sb1 & 3)<<6 | (sb2 & 240)>>2)>>2
|
||||
var/cb3 = (sb2 & 15)<<2 | (sb3 & 192)>>6
|
||||
var/cb4 = (sb3 & 63)
|
||||
c=c+b64[cb1+1]+b64[cb2+1]+b64[cb3+1]+b64[cb4+1]
|
||||
i=i+3
|
||||
return c
|
||||
|
||||
/obj/item/integrated_circuit/proc/b642asc(var/S)
|
||||
var/static/list/b64 = list("A"=1,"B"=2,"C"=3,"D"=4,"E"=5,"F"=6,"G"=7,"H"=8,"I"=9,"J"=10,"K"=11,"L"=12,"M"=13,"N"=14,"O"=15,"P"=16,"Q"=17,"R"=18,
|
||||
"S"=19,"T"=20,"U"=21,"V"=22,"W"=23,"X"=24,"Y"=25,"Z"=26,"a"=27,"b"=28,"c"=29,"d"=30,"e"=31,"f"=32,"g"=33,"h"=34,"i"=35,"j"=36,"k"=37,"l"=38,"m"=39,"n"=40,"o"=41,
|
||||
"p"=42,"q"=43,"r"=44,"s"=45,"t"=46,"u"=47,"v"=48,"w"=49,"x"=50,"y"=51,"z"=52,"0"=53,"1"=54,"2"=55,"3"=56,"4"=57,"5"=58,"6"=59,"7"=60,"8"=61,"9"=62,","=63,"."=64)
|
||||
var/ls = lentext(S)
|
||||
var/c
|
||||
var/i=1
|
||||
while(i<=ls)
|
||||
var/cb1=b64[copytext(S,i,i+1)]-1
|
||||
var/cb2=b64[copytext(S,i+1,i+2)]-1
|
||||
var/cb3=b64[copytext(S,i+2,i+3)]-1
|
||||
var/cb4=b64[copytext(S,i+3,i+4)]-1
|
||||
var/sb1=cb1<<2 | (cb2 & 48)>>4
|
||||
var/sb2=(cb2 & 15) <<4 | (cb3 & 60)>>2
|
||||
var/sb3=(cb3 & 3)<<6 | cb4
|
||||
c=c+ascii2text(sb1)+ascii2text(sb2)+ascii2text(sb3)
|
||||
i=i+4
|
||||
return c
|
||||
|
||||
/proc/XorEncrypt(string,key)
|
||||
if(!string || !key ||!istext(string)||!istext(key))
|
||||
return
|
||||
var/r
|
||||
for(var/i = 1 to length(string))
|
||||
r += ascii2text(text2ascii(string,i) ^ text2ascii(key,(i-1)%length(string)+1))
|
||||
return r
|
||||
|
||||
@@ -0,0 +1,437 @@
|
||||
/obj/item/integrated_circuit
|
||||
name = "integrated circuit"
|
||||
desc = "It's a tiny chip! This one doesn't seem to do much, however."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "template"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/obj/item/device/electronic_assembly/assembly // Reference to the assembly holding this circuit, if any.
|
||||
var/extended_desc
|
||||
var/list/inputs = list()
|
||||
var/list/inputs_default = list()// Assoc list which will fill a pin with data upon creation. e.g. "2" = 0 will set input pin 2 to equal 0 instead of null.
|
||||
var/list/outputs = list()
|
||||
var/list/outputs_default =list()// Ditto, for output.
|
||||
var/list/activators = list()
|
||||
var/next_use = 0 // Uses world.time
|
||||
var/complexity = 1 // This acts as a limitation on building machines, more resource-intensive components cost more 'space'.
|
||||
var/size = 1 // This acts as a limitation on building machines, bigger components cost more 'space'. -1 for size 0
|
||||
var/cooldown_per_use = 9 // Circuits are limited in how many times they can be work()'d by this variable.
|
||||
var/power_draw_per_use = 0 // How much power is drawn when work()'d.
|
||||
var/power_draw_idle = 0 // How much power is drawn when doing nothing.
|
||||
var/spawn_flags // Used for world initializing, see the #defines above.
|
||||
var/category_text = "NO CATEGORY THIS IS A BUG" // To show up on circuit printer, and perhaps other places.
|
||||
var/removable = TRUE // Determines if a circuit is removable from the assembly.
|
||||
var/displayed_name = ""
|
||||
var/allow_multitool = TRUE // Allows additional multitool functionality
|
||||
// Used as a global var, (Do not set manually in children).
|
||||
|
||||
/*
|
||||
Integrated circuits are essentially modular machines. Each circuit has a specific function, and combining them inside Electronic Assemblies allows
|
||||
a creative player the means to solve many problems. Circuits are held inside an electronic assembly, and are wired using special tools.
|
||||
*/
|
||||
|
||||
/obj/item/integrated_circuit/examine(mob/user)
|
||||
interact(user)
|
||||
external_examine(user)
|
||||
. = ..()
|
||||
|
||||
// This should be used when someone is examining while the case is opened.
|
||||
/obj/item/integrated_circuit/proc/internal_examine(mob/user)
|
||||
to_chat(user, "This board has [inputs.len] input pin\s, [outputs.len] output pin\s and [activators.len] activation pin\s.")
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I.linked.len)
|
||||
to_chat(user, "The '[I]' is connected to [I.get_linked_to_desc()].")
|
||||
for(var/k in 1 to outputs.len)
|
||||
var/datum/integrated_io/O = outputs[k]
|
||||
if(O.linked.len)
|
||||
to_chat(user, "The '[O]' is connected to [O.get_linked_to_desc()].")
|
||||
for(var/k in 1 to activators.len)
|
||||
var/datum/integrated_io/activate/A = activators[k]
|
||||
if(A.linked.len)
|
||||
to_chat(user, "The '[A]' is connected to [A.get_linked_to_desc()].")
|
||||
any_examine(user)
|
||||
interact(user)
|
||||
|
||||
// This should be used when someone is examining from an 'outside' perspective, e.g. reading a screen or LED.
|
||||
/obj/item/integrated_circuit/proc/external_examine(mob/user)
|
||||
any_examine(user)
|
||||
|
||||
/obj/item/integrated_circuit/proc/any_examine(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/check_interactivity(mob/user)
|
||||
if(assembly)
|
||||
return assembly.check_interactivity(user)
|
||||
else
|
||||
return user.canUseTopic(src,be_close = TRUE)
|
||||
|
||||
/obj/item/integrated_circuit/Initialize()
|
||||
displayed_name = name
|
||||
setup_io(inputs, /datum/integrated_io, inputs_default)
|
||||
setup_io(outputs, /datum/integrated_io, outputs_default)
|
||||
setup_io(activators, /datum/integrated_io/activate)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit.
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/Destroy()
|
||||
QDEL_LIST(inputs)
|
||||
QDEL_LIST(outputs)
|
||||
QDEL_LIST(activators)
|
||||
. = ..()
|
||||
/*
|
||||
/obj/item/integrated_circuit/nano_host()
|
||||
if(istype(src.loc, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/assembly = loc
|
||||
return assembly.resolve_nano_host()
|
||||
return ..()
|
||||
*/
|
||||
/obj/item/integrated_circuit/emp_act(severity)
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.scramble()
|
||||
for(var/k in 1 to outputs.len)
|
||||
var/datum/integrated_io/O = outputs[k]
|
||||
O.scramble()
|
||||
for(var/k in 1 to activators.len)
|
||||
var/datum/integrated_io/activate/A = activators[k]
|
||||
A.scramble()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/verb/rename_component()
|
||||
set name = "Rename Circuit"
|
||||
set category = "Object"
|
||||
set desc = "Rename your circuit, useful to stay organized."
|
||||
|
||||
var/mob/M = usr
|
||||
if(!check_interactivity(M))
|
||||
return
|
||||
|
||||
var/input = reject_bad_name(input("What do you want to name this?", "Rename", src.name) as null|text,1)
|
||||
if(src && input && check_interactivity(M))
|
||||
to_chat(M, "<span class='notice'>The circuit '[src.name]' is now labeled '[input]'.</span>")
|
||||
displayed_name = input
|
||||
|
||||
/obj/item/integrated_circuit/interact(mob/user)
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
// if(!assembly)
|
||||
// return
|
||||
|
||||
var/window_height = 350
|
||||
var/window_width = 600
|
||||
|
||||
//var/table_edge_width = "[(window_width - window_width * 0.1) / 4]px"
|
||||
//var/table_middle_width = "[(window_width - window_width * 0.1) - (table_edge_width * 2)]px"
|
||||
var/table_edge_width = "30%"
|
||||
var/table_middle_width = "40%"
|
||||
|
||||
var/HTML = list()
|
||||
HTML += "<html><head><title>[src.displayed_name]</title></head><body>"
|
||||
HTML += "<div align='center'>"
|
||||
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 80%'>"
|
||||
|
||||
HTML += "<br><a href='?src=[REF(src)];return=1'>\[Return to Assembly\]</a>"
|
||||
|
||||
HTML += "<br><a href='?src=[REF(src)];'>\[Refresh\]</a> | "
|
||||
HTML += "<a href='?src=[REF(src)];rename=1'>\[Rename\]</a> | "
|
||||
HTML += "<a href='?src=[REF(src)];scan=1'>\[Scan with Device\]</a> | "
|
||||
if(src.removable)
|
||||
HTML += "<a href='?src=[REF(src)];remove=1'>\[Remove\]</a><br>"
|
||||
|
||||
HTML += "<colgroup>"
|
||||
HTML += "<col style='width: [table_edge_width]'>"
|
||||
HTML += "<col style='width: [table_middle_width]'>"
|
||||
HTML += "<col style='width: [table_edge_width]'>"
|
||||
HTML += "</colgroup>"
|
||||
|
||||
var/column_width = 3
|
||||
var/row_height = max(inputs.len, outputs.len, 1)
|
||||
|
||||
for(var/i = 1 to row_height)
|
||||
HTML += "<tr>"
|
||||
for(var/j = 1 to column_width)
|
||||
var/datum/integrated_io/io = null
|
||||
var/words = list()
|
||||
var/height = 1
|
||||
switch(j)
|
||||
if(1)
|
||||
io = get_pin_ref(IC_INPUT, i)
|
||||
if(io)
|
||||
words += "<b><a href=?src=[REF(src)];pin_name=1;pin=[REF(io)]>[io.display_pin_type()] [io.name]</a> <a href=?src=[REF(src)];pin_data=1;pin=[REF(io)]>[io.display_data(io.data)]</a></b><br>"
|
||||
if(io.linked.len)
|
||||
for(var/k in 1 to io.linked.len)
|
||||
var/datum/integrated_io/linked = io.linked[k]
|
||||
// words += "<a href=?src=[REF(linked.holder)];pin_name=1;pin=[REF(linked)];link=[REF(io)]>\[[linked]\]</a>
|
||||
words += "<a href=?src=[REF(src)];pin_unwire=1;pin=[REF(io)];link=[REF(linked)]>[linked]</a> \
|
||||
@ <a href=?src=[REF(linked.holder)];examine=1;>[linked.holder.displayed_name]</a><br>"
|
||||
|
||||
if(outputs.len > inputs.len)
|
||||
height = 1
|
||||
if(2)
|
||||
if(i == 1)
|
||||
words += "[src.displayed_name]<br>[src.name != src.displayed_name ? "([src.name])":""]<hr>[src.desc]"
|
||||
height = row_height
|
||||
else
|
||||
continue
|
||||
if(3)
|
||||
io = get_pin_ref(IC_OUTPUT, i)
|
||||
if(io)
|
||||
words += "<b><a href=?src=[REF(src)];pin_name=1;pin=[REF(io)]>[io.display_pin_type()] [io.name]</a> <a href=?src=[REF(src)];pin_data=1;pin=[REF(io)]>[io.display_data(io.data)]</a></b><br>"
|
||||
if(io.linked.len)
|
||||
for(var/k in 1 to io.linked.len)
|
||||
var/datum/integrated_io/linked = io.linked[k]
|
||||
// words += "<a href=?src=[REF(linked.holder)];pin_name=1;pin=[REF(linked)];link=[REF(io)]>\[[linked]\]</a>
|
||||
words += "<a href=?src=[REF(src)];pin_unwire=1;pin=[REF(io)];link=[REF(linked)]>[linked]</a> \
|
||||
@ <a href=?src=[REF(linked.holder)];examine=1;>[linked.holder.displayed_name]</a><br>"
|
||||
|
||||
if(inputs.len > outputs.len)
|
||||
height = 1
|
||||
HTML += "<td align='center' rowspan='[height]'>[jointext(words, null)]</td>"
|
||||
HTML += "</tr>"
|
||||
|
||||
for(var/activator in activators)
|
||||
var/datum/integrated_io/io = activator
|
||||
var/words = list()
|
||||
|
||||
words += "<b><a href=?src=[REF(src)];pin_name=1;pin=[REF(io)]><font color='FF0000'>[io]</font></a> <a href=?src=[REF(src)];pin_data=1;pin=[REF(io)]><font color='FF0000'>[io.data?"\<PULSE OUT\>":"\<PULSE IN\>"]</font></a></b><br>"
|
||||
if(io.linked.len)
|
||||
for(var/k in 1 to io.linked.len)
|
||||
var/datum/integrated_io/linked = io.linked[k]
|
||||
// words += "<a href=?src=[REF(linked.holder)];pin_name=1;pin=[REF(linked)];link=[REF(io)]>\[[linked]\]</a>
|
||||
words += "<a href=?src=[REF(src)];pin_unwire=1;pin=[REF(io)];link=[REF(linked)]><font color='FF0000'>[linked]</font></a> \
|
||||
@ <a href=?src=[REF(linked.holder)];examine=1;><font color='FF0000'>[linked.holder.displayed_name]</font></a><br>"
|
||||
|
||||
HTML += "<tr>"
|
||||
HTML += "<td colspan='3' align='center'>[jointext(words, null)]</td>"
|
||||
HTML += "</tr>"
|
||||
|
||||
HTML += "</table>"
|
||||
HTML += "</div>"
|
||||
|
||||
// HTML += "<br><font color='33CC33'>Meta Variables;</font>" // If more meta vars get introduced, uncomment this.
|
||||
// HTML += "<br>"
|
||||
|
||||
HTML += "<br><font color='0000AA'>Complexity: [complexity]</font>"
|
||||
if(power_draw_idle)
|
||||
HTML += "<br><font color='0000AA'>Power Draw: [power_draw_idle] W (Idle)</font>"
|
||||
if(power_draw_per_use)
|
||||
HTML += "<br><font color='0000AA'>Power Draw: [power_draw_per_use] W (Active)</font>" // Borgcode says that powercells' checked_use() takes joules as input.
|
||||
HTML += "<br><font color='0000AA'>[extended_desc]</font>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
if(src.assembly)
|
||||
user << browse(jointext(HTML, null), "window=assembly-[REF(src.assembly)];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
else
|
||||
user << browse(jointext(HTML, null), "window=circuit-[REF(src)];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
|
||||
onclose(user, "assembly-[REF(src.assembly)]")
|
||||
|
||||
/obj/item/integrated_circuit/Topic(href, href_list)
|
||||
if(!check_interactivity(usr))
|
||||
return
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/update = TRUE
|
||||
var/obj/item/device/electronic_assembly/A = src.assembly
|
||||
var/update_to_assembly = FALSE
|
||||
var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators
|
||||
var/datum/integrated_io/linked = null
|
||||
if(href_list["link"])
|
||||
linked = locate(href_list["link"]) in pin.linked
|
||||
|
||||
var/obj/held_item = usr.get_active_held_item()
|
||||
|
||||
if(href_list["rename"])
|
||||
rename_component(usr)
|
||||
if(href_list["from_assembly"])
|
||||
update = FALSE
|
||||
var/obj/item/device/electronic_assembly/ea = loc
|
||||
if(istype(ea))
|
||||
ea.interact(usr)
|
||||
|
||||
if(href_list["pin_name"])
|
||||
if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool)
|
||||
href_list["wire"] = TRUE
|
||||
else
|
||||
var/obj/item/device/multitool/M = held_item
|
||||
M.wire(pin,usr)
|
||||
|
||||
|
||||
|
||||
if(href_list["pin_data"])
|
||||
if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool)
|
||||
href_list["wire"] = TRUE
|
||||
|
||||
else
|
||||
var/datum/integrated_io/io = pin
|
||||
io.ask_for_pin_data(usr) // The pins themselves will determine how to ask for data, and will validate the data.
|
||||
/*
|
||||
if(io.io_type == DATA_CHANNEL)
|
||||
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number", "null")
|
||||
if(!check_interactivity(usr))
|
||||
return
|
||||
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
to_chat(usr, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
//to_chat(user, "<span class='notice'>You write '[new_data]' to the '[io]' pin of \the [io.holder].</span>")
|
||||
if("number")
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && check_interactivity(usr) )
|
||||
to_chat(usr, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
if("null")
|
||||
if(check_interactivity(usr))
|
||||
to_chat(usr, "<span class='notice'>You clear the pin's memory.</span>")
|
||||
|
||||
io.write_data_to_pin(new_data)
|
||||
|
||||
else if(io.io_type == PULSE_CHANNEL)
|
||||
io.holder.check_then_do_work(ignore_power = TRUE)
|
||||
to_chat(usr, "<span class='notice'>You pulse \the [io.holder]'s [io] pin.</span>")
|
||||
*/
|
||||
|
||||
|
||||
if(href_list["pin_unwire"])
|
||||
if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool)
|
||||
href_list["wire"] = TRUE
|
||||
else
|
||||
var/obj/item/device/multitool/M = held_item
|
||||
M.unwire(pin, linked, usr)
|
||||
|
||||
if(href_list["wire"])
|
||||
if(istype(held_item, /obj/item/device/integrated_electronics/wirer))
|
||||
var/obj/item/device/integrated_electronics/wirer/wirer = held_item
|
||||
if(linked)
|
||||
wirer.wire(linked, usr)
|
||||
else if(pin)
|
||||
wirer.wire(pin, usr)
|
||||
|
||||
else if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/debugger = held_item
|
||||
if(pin)
|
||||
debugger.write_data(pin, usr)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You can't do a whole lot without the proper tools.</span>")
|
||||
|
||||
if(href_list["examine"])
|
||||
var/obj/item/integrated_circuit/examined
|
||||
if(href_list["examined"])
|
||||
examined = href_list["examined"]
|
||||
else
|
||||
examined = src
|
||||
examined.interact(usr)
|
||||
update = FALSE
|
||||
|
||||
if(href_list["bottom"])
|
||||
var/obj/item/integrated_circuit/circuit = locate(href_list["bottom"]) in src.assembly.contents
|
||||
var/assy = circuit.assembly
|
||||
if(!circuit)
|
||||
return
|
||||
circuit.loc = null
|
||||
circuit.loc = assy
|
||||
. = TRUE
|
||||
update_to_assembly = TRUE
|
||||
|
||||
if(href_list["scan"])
|
||||
if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/D = held_item
|
||||
if(D.accepting_refs)
|
||||
D.afterattack(src, usr, TRUE)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>The Debugger's 'ref scanner' needs to be on.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You need a multitool/debugger set to 'ref' mode to do that.</span>")
|
||||
|
||||
if(href_list["return"])
|
||||
if(A)
|
||||
update_to_assembly = TRUE
|
||||
usr << browse(null, "window=circuit-[REF(src)];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>This circuit is not in an assembly!</span>")
|
||||
|
||||
|
||||
if(href_list["remove"])
|
||||
if(!A)
|
||||
to_chat(usr, "<span class='warning'>This circuit is not in an assembly!</span>")
|
||||
return
|
||||
if(!removable)
|
||||
to_chat(usr, "<span class='warning'>\The [src] seems to be permanently attached to the case.</span>")
|
||||
return
|
||||
var/obj/item/device/electronic_assembly/ea = loc
|
||||
disconnect_all()
|
||||
var/turf/T = get_turf(src)
|
||||
forceMove(T)
|
||||
assembly = null
|
||||
playsound(T, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
to_chat(usr, "<span class='notice'>You pop \the [src] out of the case, and slide it out.</span>")
|
||||
|
||||
if(istype(ea))
|
||||
ea.interact(usr)
|
||||
update = FALSE
|
||||
return
|
||||
|
||||
if(update)
|
||||
if(A && istype(A) && update_to_assembly)
|
||||
A.interact(usr)
|
||||
else
|
||||
interact(usr) // To refresh the UI.
|
||||
|
||||
/obj/item/integrated_circuit/proc/push_data()
|
||||
for(var/k in 1 to outputs.len)
|
||||
var/datum/integrated_io/O = outputs[k]
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/pull_data()
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/draw_idle_power()
|
||||
if(assembly)
|
||||
return assembly.draw_power(power_draw_idle)
|
||||
|
||||
// Override this for special behaviour when there's no power left.
|
||||
/obj/item/integrated_circuit/proc/power_fail()
|
||||
return
|
||||
|
||||
// Returns true if there's enough power to work().
|
||||
/obj/item/integrated_circuit/proc/check_power()
|
||||
if(!assembly)
|
||||
return FALSE // Not in an assembly, therefore no power.
|
||||
if(assembly.draw_power(power_draw_per_use))
|
||||
return TRUE // Battery has enough.
|
||||
return FALSE // Not enough power.
|
||||
|
||||
/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE)
|
||||
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
|
||||
return
|
||||
if(power_draw_per_use && !ignore_power)
|
||||
if(!check_power())
|
||||
power_fail()
|
||||
return
|
||||
next_use = world.time + cooldown_per_use
|
||||
do_work()
|
||||
|
||||
/obj/item/integrated_circuit/proc/do_work()
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/disconnect_all()
|
||||
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.disconnect()
|
||||
for(var/k in 1 to outputs.len)
|
||||
var/datum/integrated_io/O = outputs[k]
|
||||
O.disconnect()
|
||||
for(var/k in 1 to activators.len)
|
||||
var/datum/integrated_io/activate/A = activators[k]
|
||||
A.disconnect()
|
||||
|
||||
/obj/item/integrated_circuit/proc/ext_moved(oldLoc, dir)
|
||||
return
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
Pins both hold data for circuits, as well move data between them. Some also cause circuits to do their function. DATA_CHANNEL pins are the data holding/moving kind,
|
||||
where as PULSE_CHANNEL causes circuits to work() when their pulse hits them.
|
||||
|
||||
|
||||
A visualization of how pins work is below. Imagine the below image involves an addition circuit.
|
||||
When the bottom pin, the activator, receives a pulse, all the numbers on the left (input) get added, and the answer goes on the right side (output).
|
||||
|
||||
Inputs Outputs
|
||||
|
||||
A [2]\ /[8] result
|
||||
B [1]-\|++|/
|
||||
C [4]-/|++|
|
||||
D [1]/ ||
|
||||
||
|
||||
Activator
|
||||
|
||||
|
||||
|
||||
*/
|
||||
/datum/integrated_io
|
||||
var/name = "input/output"
|
||||
var/obj/item/integrated_circuit/holder
|
||||
var/datum/weakref/data // This is a weakref, to reduce typecasts. Note that oftentimes numbers and text may also occupy this.
|
||||
var/list/linked = list()
|
||||
var/io_type = DATA_CHANNEL
|
||||
|
||||
/datum/integrated_io/New(newloc, name1, new_data)
|
||||
name = name1
|
||||
if(new_data)
|
||||
data = new_data
|
||||
holder = newloc
|
||||
if(!istype(holder))
|
||||
message_admins("ERROR: An integrated_io ([name]) spawned without a valid holder! This is a bug.")
|
||||
|
||||
/datum/integrated_io/Destroy()
|
||||
disconnect()
|
||||
data = null
|
||||
holder = null
|
||||
return ..()
|
||||
/*
|
||||
/datum/integrated_io/nano_host()
|
||||
return holder.nano_host()
|
||||
*/
|
||||
|
||||
/datum/integrated_io/proc/data_as_type(var/as_type)
|
||||
if(!isweakref(data))
|
||||
return
|
||||
var/datum/weakref/w = data
|
||||
var/output = w.resolve()
|
||||
return istype(output, as_type) ? output : null
|
||||
|
||||
/datum/integrated_io/proc/display_data(var/input)
|
||||
if(isnull(input))
|
||||
return "(null)" // Empty data means nothing to show.
|
||||
|
||||
if(istext(input))
|
||||
return "(\"[input]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'.
|
||||
|
||||
/*
|
||||
list[](
|
||||
"A",
|
||||
"B",
|
||||
"C"
|
||||
)
|
||||
*/
|
||||
|
||||
if(islist(input))
|
||||
var/list/my_list = input
|
||||
var/result = "list\[[my_list.len]\]("
|
||||
if(my_list.len)
|
||||
result += "<br>"
|
||||
var/pos = 0
|
||||
for(var/line in my_list)
|
||||
result += "[display_data(line)]"
|
||||
pos++
|
||||
if(pos != my_list.len)
|
||||
result += ",<br>"
|
||||
result += "<br>"
|
||||
result += ")"
|
||||
return result
|
||||
|
||||
if(isweakref(input))
|
||||
var/datum/weakref/w = input
|
||||
var/atom/A = w.resolve()
|
||||
return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed.
|
||||
//return A ? "([REF(A)] \[Ref\])" : "(null)"
|
||||
|
||||
return "([input])" // Nothing special needed for numbers or other stuff.
|
||||
|
||||
/datum/integrated_io/activate/display_data()
|
||||
return "(\[pulse\])"
|
||||
|
||||
/datum/integrated_io/proc/display_pin_type()
|
||||
return IC_FORMAT_ANY
|
||||
|
||||
/datum/integrated_io/activate/display_pin_type()
|
||||
return IC_FORMAT_PULSE
|
||||
|
||||
/datum/integrated_io/proc/scramble()
|
||||
if(isnull(data))
|
||||
return
|
||||
if(isnum(data))
|
||||
write_data_to_pin(rand(-10000, 10000))
|
||||
if(istext(data))
|
||||
write_data_to_pin("ERROR")
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/activate/scramble()
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/proc/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || isnum(new_data) || istext(new_data) || isweakref(new_data))
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
else if(islist(new_data))
|
||||
var/list/new_list = new_data
|
||||
data = new_list.Copy(1,min( IC_MAX_LIST_LENGTH+1, new_list.len ))
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/proc/push_data()
|
||||
for(var/k in 1 to linked.len)
|
||||
var/datum/integrated_io/io = linked[k]
|
||||
io.write_data_to_pin(data)
|
||||
|
||||
/datum/integrated_io/activate/push_data()
|
||||
for(var/k in 1 to linked.len)
|
||||
var/datum/integrated_io/io = linked[k]
|
||||
io.holder.check_then_do_work()
|
||||
|
||||
/datum/integrated_io/proc/pull_data()
|
||||
for(var/k in 1 to linked.len)
|
||||
var/datum/integrated_io/io = linked[k]
|
||||
write_data_to_pin(io.data)
|
||||
|
||||
/datum/integrated_io/proc/get_linked_to_desc()
|
||||
if(linked.len)
|
||||
return "the [english_list(linked)]"
|
||||
return "nothing"
|
||||
|
||||
/datum/integrated_io/proc/disconnect()
|
||||
//First we iterate over everything we are linked to.
|
||||
if(linked && linked.len)
|
||||
for(var/i in 1 to linked.len)
|
||||
var/datum/integrated_io/their_io = linked[i]
|
||||
//While doing that, we iterate them as well, and disconnect ourselves from them.
|
||||
if(their_io.linked.len && their_io.linked)
|
||||
for(var/j in 1 to their_io.linked.len)
|
||||
var/datum/integrated_io/their_linked_io = their_io.linked[j]
|
||||
if(their_linked_io == src)
|
||||
their_io.linked.Remove(src)
|
||||
else
|
||||
continue
|
||||
//Now that we're removed from them, we gotta remove them from us.
|
||||
linked.Remove(their_io)
|
||||
|
||||
/datum/integrated_io/proc/ask_for_data_type(mob/user, var/default, var/list/allowed_data_types = list("string","number","null"))
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in allowed_data_types
|
||||
if(!holder.check_interactivity(user))
|
||||
return
|
||||
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
new_data = input("Now type in a string.","[src] string writing", istext(default) ? default : null) as null|text
|
||||
if(istext(new_data) && holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input "+new_data+" into the pin.</span>")
|
||||
return new_data
|
||||
if("number")
|
||||
new_data = input("Now type in a number.","[src] number writing", isnum(default) ? default : null) as null|num
|
||||
if(isnum(new_data) && holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
return new_data
|
||||
if("null")
|
||||
if(holder.check_interactivity(user))
|
||||
to_chat(user, "<span class='notice'>You clear the pin's memory.</span>")
|
||||
return new_data
|
||||
|
||||
// Basically a null check
|
||||
/datum/integrated_io/proc/is_valid()
|
||||
return !isnull(data)
|
||||
|
||||
// This proc asks for the data to write, then writes it.
|
||||
/datum/integrated_io/proc/ask_for_pin_data(mob/user)
|
||||
var/new_data = ask_for_data_type(user)
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/activate/ask_for_pin_data(mob/user) // This just pulses the pin.
|
||||
holder.check_then_do_work(ignore_power = TRUE)
|
||||
to_chat(user, "<span class='notice'>You pulse \the [holder]'s [src] pin.</span>")
|
||||
|
||||
/datum/integrated_io/activate
|
||||
name = "activation pin"
|
||||
io_type = PULSE_CHANNEL
|
||||
|
||||
/datum/integrated_io/activate/out // All this does is just make the UI say 'out' instead of 'in'
|
||||
data = 1
|
||||
@@ -0,0 +1,156 @@
|
||||
/obj/item/device/integrated_electronics/prefab
|
||||
var/debug = FALSE
|
||||
name = "prefab"
|
||||
desc = "new machine in package"
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "box_template"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
var/program="blank"
|
||||
var/list/as_names = list()
|
||||
|
||||
/obj/item/device/integrated_electronics/prefab/attack_self(var/mob/user)
|
||||
if(program && program != "blank")
|
||||
assemble(program)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/integrated_electronics/prefab/Initialize()
|
||||
. = ..()
|
||||
var/list/assembly_list = list(
|
||||
/obj/item/device/electronic_assembly,
|
||||
/obj/item/device/electronic_assembly/medium,
|
||||
/obj/item/device/electronic_assembly/large,
|
||||
/obj/item/device/electronic_assembly/drone,
|
||||
)
|
||||
for(var/k in 1 to assembly_list.len)
|
||||
var/obj/item/I = assembly_list[k]
|
||||
as_names[initial(I.name)] = I
|
||||
addtimer(CALLBACK(src, .proc/attack_self), 2) //IDK, why it's need dely,but otherwise it doesn't work.
|
||||
|
||||
/obj/item/device/integrated_electronics/prefab/proc/assemble(var/program)
|
||||
var/list/all_circuits = SScircuit.all_circuits //cached lists = free performance
|
||||
var/list/chap = splittext( program ,"{{*}}")
|
||||
var/list/elements = list()
|
||||
var/list/elements_input = list()
|
||||
var/list/element = list()
|
||||
var/obj/item/AS
|
||||
var/PA
|
||||
var/i = 0
|
||||
|
||||
var/list/ioa = list()
|
||||
var/datum/integrated_io/IO
|
||||
var/datum/integrated_io/IO2
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>started successful</span>")
|
||||
if(chap[2] != "")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>assembly</span>")
|
||||
element = splittext( chap[2] ,"=-=")
|
||||
PA = as_names[element[1]]
|
||||
AS = new PA(null)
|
||||
AS.loc = src
|
||||
AS.name = element[2]
|
||||
else
|
||||
return //what's the point if there is no assembly?
|
||||
if(chap[3] != "components") //if there is only one word,there is no components.
|
||||
elements_input = splittext( chap[3] ,"^%^")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>components[elements_input.len]</span>")
|
||||
i = 0
|
||||
elements = list()
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem) //I don't know,why Cut or copy don't works. If somebody can fix it, it should be fixed.
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>components[elements.len]</span>")
|
||||
if(!length(elements_input))
|
||||
return
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>inserting components[elements.len]</span>")
|
||||
var/obj/item/integrated_circuit/comp
|
||||
i=0
|
||||
for(var/E in elements)
|
||||
i=i+1
|
||||
element = splittext( E ,"=-=")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
var/path_to_use = all_circuits[element[1]]
|
||||
comp = new path_to_use(null)
|
||||
comp.loc = AS
|
||||
comp.displayed_name = element[2]
|
||||
comp.assembly = AS
|
||||
if(comp.inputs && comp.inputs.len)
|
||||
for(var/j in 1 to comp.inputs.len)
|
||||
var/datum/integrated_io/IN = comp.inputs[j]
|
||||
ioa["[i]i[j]"] = IN
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]i[j]</span>")
|
||||
if(comp.outputs && comp.outputs.len)
|
||||
for(var/j in 1 to comp.outputs.len) //Also this block uses for setting all i/o id's
|
||||
var/datum/integrated_io/OUT = comp.outputs[j]
|
||||
ioa["[i]o[j]"] = OUT
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]o[j]</span>")
|
||||
if(comp.activators && comp.activators.len)
|
||||
for(var/j in 1 to comp.activators.len)
|
||||
var/datum/integrated_io/ACT = comp.activators[j]
|
||||
ioa["[i]a[j]"] = ACT
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]a[j]</span>")
|
||||
|
||||
else
|
||||
return
|
||||
if(!AS.contents.len)
|
||||
return
|
||||
if(chap[4] != "values") //if there is only one word,there is no values
|
||||
elements_input = splittext( chap[4] ,"^%^")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>values[elements_input.len]</span>")
|
||||
i=0
|
||||
elements = list()
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>values[elements.len]</span>")
|
||||
if(elements.len>0)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>setting values[elements.len]</span>")
|
||||
for(var/E in elements)
|
||||
element = splittext( E ,":+:")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
IO = ioa[element[1]]
|
||||
if(element[2]=="text")
|
||||
IO.write_data_to_pin(element[3])
|
||||
else if(element[2]=="num")
|
||||
IO.write_data_to_pin(text2num(element[3]))
|
||||
else if(element[2]=="list")
|
||||
IO.write_data_to_pin(params2list(element[3]))
|
||||
if(chap[5] != "wires") //if there is only one word,there is no wires
|
||||
elements_input = splittext( chap[5] ,"^%^")
|
||||
i=0
|
||||
elements = list()
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>wires[elements_input.len]</span>")
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>wires[elements.len]</span>")
|
||||
if(elements.len>0)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>setting wires[elements.len]</span>")
|
||||
for(var/E in elements)
|
||||
element = splittext( E ,"=-=")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
IO = ioa[element[1]]
|
||||
IO2 = ioa[element[2]]
|
||||
IO.linked |= IO2
|
||||
|
||||
AS.forceMove(loc)
|
||||
qdel(src)
|
||||
@@ -0,0 +1,413 @@
|
||||
/obj/item/device/integrated_circuit_printer
|
||||
name = "integrated circuit printer"
|
||||
desc = "A portable(ish) machine made to print tiny modular circuitry out of metal."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "circuit_printer"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
var/metal = 0
|
||||
var/init_max_metal = 100
|
||||
var/max_metal = 100
|
||||
var/metal_per_sheet = 10 // One sheet equals this much metal.
|
||||
var/debug = FALSE
|
||||
var/upgraded = FALSE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits.
|
||||
var/can_clone = FALSE // Same for above, but will allow the printer to duplicate a specific assembly.
|
||||
var/static/list/recipe_list //category = list(paths in category)
|
||||
var/current_category = null
|
||||
var/as_printing = FALSE
|
||||
var/as_needs = 0
|
||||
var/program ="blank"
|
||||
var/obj/item/device/integrated_electronics/prefab/PR = null
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/proc/check_interactivity(mob/user)
|
||||
return user.canUseTopic(src,be_close = TRUE)
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/upgraded
|
||||
upgraded = TRUE
|
||||
can_clone = TRUE
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/Initialize()
|
||||
. = ..()
|
||||
if(!recipe_list)
|
||||
recipe_list = SScircuit.circuit_fabricator_recipe_list
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/attackby(var/obj/item/O, var/mob/user)
|
||||
if(istype(O,/obj/item/stack/sheet/metal))
|
||||
var/obj/item/stack/sheet/metal/stack = O
|
||||
var/num = min((max_metal - metal) / metal_per_sheet, stack.amount)
|
||||
if(num < 1)
|
||||
to_chat(user, "<span class='warning'>\The [src] is too full to add more metal.</span>")
|
||||
return
|
||||
if(stack.use(num))
|
||||
to_chat(user, "<span class='notice'>You add [num] sheet\s to \the [src].</span>")
|
||||
metal += num * metal_per_sheet
|
||||
if(as_printing)
|
||||
if(as_needs <= metal)
|
||||
PR = new/obj/item/device/integrated_electronics/prefab(get_turf(loc))
|
||||
PR.program = program
|
||||
metal = metal - as_needs
|
||||
to_chat(user, "<span class='notice'>Assembly has been printed.</span>")
|
||||
as_printing = FALSE
|
||||
as_needs = 0
|
||||
max_metal = init_max_metal
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Please insert [(as_needs-metal)/10] more metal!</span>")
|
||||
interact(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/integrated_circuit))
|
||||
to_chat(user, "<span class='notice'>You insert the circuit into \the [src]. </span>")
|
||||
user.temporarilyRemoveItemFromInventory(O)
|
||||
metal = min(metal + O.w_class, max_metal)
|
||||
qdel(O)
|
||||
interact(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/disk/integrated_circuit/upgrade/advanced))
|
||||
if(upgraded)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has this upgrade. </span>")
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>You install \the [O] into \the [src]. </span>")
|
||||
upgraded = TRUE
|
||||
interact(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/disk/integrated_circuit/upgrade/clone))
|
||||
if(can_clone)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has this upgrade. </span>")
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>You install \the [O] into \the [src]. </span>")
|
||||
can_clone = TRUE
|
||||
interact(user)
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/attack_self(var/mob/user)
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/interact(mob/user)
|
||||
var/window_height = 600
|
||||
var/window_width = 500
|
||||
|
||||
if(isnull(current_category))
|
||||
current_category = recipe_list[1]
|
||||
|
||||
var/HTML = "<center><h2>Integrated Circuit Printer</h2></center><br>"
|
||||
HTML += "Metal: [metal/metal_per_sheet]/[max_metal/metal_per_sheet] sheets.<br>"
|
||||
HTML += "Circuits available: [upgraded ? "Advanced":"Regular"]."
|
||||
HTML += "Assembly Cloning: [can_clone ? "Available": "Unavailable"]."
|
||||
HTML += "Crossed out circuits mean that the printer is not sufficiently upgraded to create that circuit.<br>"
|
||||
HTML += "<hr>"
|
||||
if(can_clone)
|
||||
HTML += "Here you can load script for your assembly.<br>"
|
||||
if(as_printing)
|
||||
HTML += " {Load Program} "
|
||||
else
|
||||
HTML += " <A href='?src=[REF(src)];print=load'>{Load Program}</a> "
|
||||
if(program == "blank")
|
||||
HTML += " {Check Program} "
|
||||
else
|
||||
HTML += " <A href='?src=[REF(src)];print=check'>{Check Program}</a> "
|
||||
if((program == "blank")|as_printing)
|
||||
HTML += " {Print assembly} "
|
||||
else
|
||||
HTML += " <A href='?src=[REF(src)];print=print'>{Print assembly}</a> "
|
||||
if(as_printing)
|
||||
HTML += "<br> printing in process. Please insert more metal. "
|
||||
HTML += "<br><hr>"
|
||||
HTML += "Categories:"
|
||||
for(var/category in recipe_list)
|
||||
if(category != current_category)
|
||||
HTML += " <a href='?src=[REF(src)];category=[category]'>\[[category]\]</a> "
|
||||
else // Bold the button if it's already selected.
|
||||
HTML += " <b>\[[category]\]</b> "
|
||||
HTML += "<hr>"
|
||||
HTML += "<center><h4>[current_category]</h4></center>"
|
||||
|
||||
var/list/current_list = recipe_list[current_category]
|
||||
for(var/k in 1 to current_list.len)
|
||||
var/obj/O = current_list[k]
|
||||
var/can_build = TRUE
|
||||
if(istype(O, /obj/item/integrated_circuit))
|
||||
var/obj/item/integrated_circuit/IC = current_list[k]
|
||||
if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded)
|
||||
can_build = FALSE
|
||||
if(can_build)
|
||||
HTML += "<A href='?src=[REF(src)];build=[current_list[k]]'>\[[initial(O.name)]\]</A>: [initial(O.desc)]<br>"
|
||||
else
|
||||
HTML += "<s>\[[initial(O.name)]\]: [initial(O.desc)]</s><br>"
|
||||
|
||||
user << browse(jointext(HTML, null), "window=integrated_printer;size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/Topic(href, href_list)
|
||||
if(!check_interactivity(usr))
|
||||
return
|
||||
if(..())
|
||||
return TRUE
|
||||
var/sc = 0
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["category"])
|
||||
current_category = href_list["category"]
|
||||
|
||||
if(href_list["build"])
|
||||
var/build_type = text2path(href_list["build"])
|
||||
if(!build_type || !ispath(build_type))
|
||||
return TRUE
|
||||
|
||||
var/cost = 1
|
||||
if(ispath(build_type, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/E = build_type
|
||||
cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4)
|
||||
else if(ispath(build_type, /obj/item/integrated_circuit))
|
||||
var/obj/item/integrated_circuit/IC = build_type
|
||||
cost = initial(IC.w_class)
|
||||
|
||||
if(metal - cost < 0)
|
||||
to_chat(usr, "<span class='warning'>You need [cost] metal to build that!.</span>")
|
||||
return TRUE
|
||||
metal -= cost
|
||||
new build_type(get_turf(loc))
|
||||
|
||||
if(href_list["print"])
|
||||
if(!CONFIG_GET(flag/ic_printing))
|
||||
to_chat(usr, "<span class='warning'>CentCom has disabled printing of custom circuitry due to recent allegations of copyright infringement.</span>")
|
||||
return
|
||||
switch(href_list["print"])
|
||||
if("load")
|
||||
program = input("Put your code there:", "loading", null, null)
|
||||
if("check")
|
||||
sc = sanity_check(program,usr)
|
||||
if(sc == 0)
|
||||
to_chat(usr, "<span class='warning'>Invalid program.</span>")
|
||||
else if(sc == -1)
|
||||
to_chat(usr, "<span class='warning'>Unknown circuits found. Upgrades required to process this design.</span>")
|
||||
else if(sc == null)
|
||||
to_chat(usr, "<span class='warning'>Invalid program.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>Program is correct.You'll need [sc/10] sheets of metal</span>")
|
||||
if("print")
|
||||
sc = sanity_check(program,usr)
|
||||
if(sc == 0 || sc == null)
|
||||
to_chat(usr, "<span class='warning'>Invalid program.</span>")
|
||||
else if(sc == -1)
|
||||
to_chat(usr, "<span class='warning'>Unknown circuits found. Upgrades required to process this design.</span>")
|
||||
else
|
||||
as_printing = TRUE
|
||||
if(sc <= metal)
|
||||
PR = new/obj/item/device/integrated_electronics/prefab(get_turf(loc))
|
||||
PR.program = program
|
||||
metal = metal - sc
|
||||
to_chat(usr, "<span class='notice'>Assembly has been printed.</span>")
|
||||
as_printing = FALSE
|
||||
as_needs = 0
|
||||
max_metal=init_max_metal
|
||||
else
|
||||
max_metal = sc + metal_per_sheet
|
||||
as_needs = sc
|
||||
to_chat(usr, "<span class='notice'>Please insert [(as_needs-metal)/10] more metal!</span>")
|
||||
interact(usr)
|
||||
|
||||
// FUKKEN UPGRADE DISKS
|
||||
/obj/item/disk/integrated_circuit/upgrade
|
||||
name = "integrated circuit printer upgrade disk"
|
||||
desc = "Install this into your integrated circuit printer to enhance it."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "upgrade_disk"
|
||||
item_state = "card-id"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4)
|
||||
|
||||
/obj/item/disk/integrated_circuit/upgrade/advanced
|
||||
name = "integrated circuit printer upgrade disk - advanced designs"
|
||||
desc = "Install this into your integrated circuit printer to enhance it. This one adds new, advanced designs to the printer."
|
||||
|
||||
// To be implemented later.
|
||||
/obj/item/disk/integrated_circuit/upgrade/clone
|
||||
name = "integrated circuit printer upgrade disk - circuit cloner"
|
||||
desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies."
|
||||
icon_state = "upgrade_disk_clone"
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5)
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/proc/sanity_check(var/program,var/mob/user)
|
||||
var/list/chap = splittext( program ,"{{*}}")
|
||||
if(chap.len != 6)
|
||||
return 0 //splitting incorrect
|
||||
var/list/elements = list()
|
||||
var/list/elements_input = list()
|
||||
var/list/element = list()
|
||||
var/obj/item/PA
|
||||
var/obj/item/device/electronic_assembly/PF
|
||||
var/datum/integrated_io/IO
|
||||
var/datum/integrated_io/IO2
|
||||
var/i = 0
|
||||
var/obj/item/integrated_circuit/comp
|
||||
var/list/ioa = list()
|
||||
var/list/as_samp = list()
|
||||
var/list/all_circuits = SScircuit.all_circuits // It's free. Performance. We're giving you cpu time. It's free. We're giving you time. It's performance, free. It's free cpu time for you jim!
|
||||
var/list/assembly_list = list(
|
||||
/obj/item/device/electronic_assembly,
|
||||
/obj/item/device/electronic_assembly/medium,
|
||||
/obj/item/device/electronic_assembly/large,
|
||||
/obj/item/device/electronic_assembly/drone,
|
||||
)
|
||||
var/compl = 0
|
||||
var/maxcomp = 0
|
||||
var/cap = 0
|
||||
var/maxcap = 0
|
||||
var/metalcost = 0
|
||||
for(var/k in 1 to assembly_list.len)
|
||||
var/obj/item/I = assembly_list[k]
|
||||
as_samp[initial(I.name)] = I
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>started successful</span>")
|
||||
if(chap[2] != "")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>assembly</span>")
|
||||
element = splittext( chap[2] ,"=-=")
|
||||
PA = as_samp[element[1]]
|
||||
if(ispath(PA,/obj/item/device/electronic_assembly))
|
||||
PF = PA
|
||||
maxcap = initial(PF.max_components)
|
||||
maxcomp = initial(PF.max_complexity)
|
||||
metalcost = metalcost + round( (initial(PF.max_complexity) + initial(PF.max_components) ) / 4)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>maxcap[maxcap]maxcomp[maxcomp]</span>")
|
||||
else
|
||||
return 0
|
||||
to_chat(usr, "<span class='notice'>This is program for [element[2]]</span>")
|
||||
/*
|
||||
else if(istype(PA,/obj/item/weapon/implant/integrated_circuit))
|
||||
var/obj/item/weapon/implant/integrated_circuit/PI = PA
|
||||
var/obj/item/device/electronic_assembly/implant/PIC = PI.IC
|
||||
maxcap = PIC.max_components
|
||||
maxcomp = PIC.max_complexity
|
||||
metalcost = metalcost + round( (initial(PIC.max_complexity) + initial(PIC.max_components) ) / 4)*/
|
||||
else
|
||||
return 0 //what's the point if there is no assembly?
|
||||
if(chap[3] != "components") //if there is only one word,there is no components.
|
||||
elements_input = splittext( chap[3] ,"^%^")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>components[elements_input.len]</span>")
|
||||
i = 0
|
||||
elements = list()
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>components[elements.len]</span>")
|
||||
if(elements_input.len<1)
|
||||
return 0
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>inserting components[elements.len]</span>")
|
||||
i=0
|
||||
for(var/E in elements)
|
||||
i=i+1
|
||||
element = splittext( E ,"=-=")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
comp = all_circuits[element[1]]
|
||||
if(!comp)
|
||||
break
|
||||
if(!upgraded)
|
||||
var/obj/item/integrated_circuit/IC = comp
|
||||
if(!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT))
|
||||
return -1
|
||||
compl = compl + initial(comp.complexity)
|
||||
cap = cap + initial(comp.size)
|
||||
metalcost = metalcost + initial(initial(comp.w_class))
|
||||
var/obj/item/integrated_circuit/circuit = new comp
|
||||
var/list/ini = circuit.inputs
|
||||
if(length(ini))
|
||||
for(var/j in 1 to ini.len)
|
||||
var/datum/integrated_io/IN = ini[j]
|
||||
ioa["[i]i[j]"] = IN
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]i[j]</span>")
|
||||
ini = circuit.outputs
|
||||
if(length(ini))
|
||||
for(var/j in 1 to ini.len) //Also this block uses for setting all i/o id's
|
||||
var/datum/integrated_io/OUT = ini[j]
|
||||
ioa["[i]o[j]"] = OUT
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]o[j]</span>")
|
||||
ini = circuit.activators
|
||||
if(length(ini))
|
||||
for(var/j in 1 to ini.len)
|
||||
var/datum/integrated_io/ACT = ini.[j]
|
||||
ioa["[i]a[j]"] = ACT
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]a[j]</span>")
|
||||
if(i<elements.len)
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>cap[cap]compl[compl]maxcompl[maxcomp]maxcap[maxcap]</span>")
|
||||
if(cap == 0)
|
||||
return 0
|
||||
if(cap>maxcap)
|
||||
return 0
|
||||
if(compl>maxcomp)
|
||||
return 0
|
||||
if(chap[4] != "values") //if there is only one word,there is no values
|
||||
elements_input = splittext( chap[4] ,"^%^")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>values[elements_input.len]</span>")
|
||||
i=0
|
||||
elements = list()
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>values[elements.len]</span>")
|
||||
if(elements.len>0)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>setting values[elements.len]</span>")
|
||||
for(var/E in elements)
|
||||
element = splittext( E ,":+:")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
if(!ioa[element[1]])
|
||||
return 0
|
||||
if(element[2]=="text")
|
||||
continue
|
||||
else if(element[2]=="num")
|
||||
continue
|
||||
else if(element[2]=="list")
|
||||
continue
|
||||
else
|
||||
return 0
|
||||
|
||||
if(chap[5] != "wires") //if there is only one word,there is no wires
|
||||
elements_input = splittext( chap[5] ,"^%^")
|
||||
i=0
|
||||
elements = list()
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>wires[elements_input.len]</span>")
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>wires[elements.len]</span>")
|
||||
if(elements.len>0)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>setting wires[elements.len]</span>")
|
||||
for(var/E in elements)
|
||||
element = splittext( E ,"=-=")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
IO = ioa[element[1]]
|
||||
IO2 = ioa[element[2]]
|
||||
if(!((element[2]+"=-="+element[1]) in elements))
|
||||
return 0
|
||||
if(!IO)
|
||||
return 0
|
||||
if(!IO2)
|
||||
return 0
|
||||
if(initial(IO.io_type) != initial(IO2.io_type))
|
||||
return 0
|
||||
return metalcost
|
||||
@@ -0,0 +1,26 @@
|
||||
// These pins only contain 0 or 1. Null is not allowed.
|
||||
/datum/integrated_io/boolean
|
||||
name = "boolean pin"
|
||||
data = FALSE
|
||||
|
||||
/datum/integrated_io/boolean/ask_for_pin_data(mob/user) // 'Ask' is a bit misleading, acts more like a toggle.
|
||||
var/new_data = !data
|
||||
to_chat(user, "<span class='notice'>You switch the data bit to [data? "true" : "false"].</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/boolean/write_data_to_pin(var/new_data)
|
||||
if(new_data == FALSE || new_data == TRUE)
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/boolean/scramble()
|
||||
write_data_to_pin(rand(FALSE,TRUE))
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/boolean/display_pin_type()
|
||||
return IC_FORMAT_BOOLEAN
|
||||
|
||||
/datum/integrated_io/boolean/display_data(var/input)
|
||||
if(data == TRUE)
|
||||
return "(True)"
|
||||
return "(False)"
|
||||
@@ -0,0 +1,27 @@
|
||||
// These pins can only contain a 1 character string or null.
|
||||
/datum/integrated_io/char
|
||||
name = "char pin"
|
||||
|
||||
/datum/integrated_io/char/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please type in one character.","[src] char writing") as null|text
|
||||
if(holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data ? "new_data" : "NULL"] into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/char/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || istext(new_data))
|
||||
if(length(new_data) > 1)
|
||||
return
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
// This makes the text go from "A" to "%".
|
||||
/datum/integrated_io/char/scramble()
|
||||
if(!is_valid())
|
||||
return
|
||||
var/list/options = list("!","@","#","$","%","^","&","*","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
|
||||
data = pick(options)
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/char/display_pin_type()
|
||||
return IC_FORMAT_CHAR
|
||||
@@ -0,0 +1,49 @@
|
||||
// These pins can only contain a color (in the form of #FFFFFF) or null.
|
||||
/datum/integrated_io/color
|
||||
name = "color pin"
|
||||
|
||||
/datum/integrated_io/color/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please select a color.","[src] color writing") as null|color
|
||||
if(holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input a <font color='[new_data]'>new color</font> into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/color/write_data_to_pin(var/new_data)
|
||||
// Since this is storing the color as a string hex color code, we need to make sure it's actually one.
|
||||
if(isnull(new_data) || istext(new_data))
|
||||
if(istext(new_data))
|
||||
new_data = uppertext(new_data)
|
||||
if(length(new_data) != 7) // We can hex if we want to, we can leave your strings behind
|
||||
return // Cause your strings don't hex and if they don't hex
|
||||
var/friends = copytext(new_data, 2, 8) // Well they're are no strings of mine
|
||||
// I say, we can go where we want to, a place where they will never find
|
||||
var/safety_dance = 1
|
||||
while(safety_dance >= 7) // And we can act like we come from out of this world.log
|
||||
var/hex = copytext(friends, safety_dance, safety_dance+1)
|
||||
if(!(hex in list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")))
|
||||
return // Leave the fake one far behind,
|
||||
safety_dance++
|
||||
|
||||
data = new_data // And we can hex
|
||||
holder.on_data_written()
|
||||
|
||||
// This randomizes the color.
|
||||
/datum/integrated_io/color/scramble()
|
||||
if(!is_valid())
|
||||
return
|
||||
var/new_data
|
||||
for(var/i=1;i<=3;i++)
|
||||
var/temp_col = "[num2hex(rand(0,255))]"
|
||||
if(length(temp_col )<2)
|
||||
temp_col = "0[temp_col]"
|
||||
new_data += temp_col
|
||||
data = new_data
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/color/display_pin_type()
|
||||
return IC_FORMAT_COLOR
|
||||
|
||||
/datum/integrated_io/color/display_data(var/input)
|
||||
if(!isnull(data))
|
||||
return "(<font color='[data]'>[data]</font>)"
|
||||
return ..()
|
||||
@@ -0,0 +1,31 @@
|
||||
// These pins can only contain directions (1,2,4,8...) or null.
|
||||
/datum/integrated_io/dir
|
||||
name = "dir pin"
|
||||
|
||||
/datum/integrated_io/dir/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please type in a valid dir number. \
|
||||
Valid dirs are;\n\
|
||||
North/Fore = [NORTH],\n\
|
||||
South/Aft = [SOUTH],\n\
|
||||
East/Starboard = [EAST],\n\
|
||||
West/Port = [WEST],\n\
|
||||
Northeast = [NORTHEAST],\n\
|
||||
Northwest = [NORTHWEST],\n\
|
||||
Southeast = [SOUTHEAST],\n\
|
||||
Southwest = [SOUTHWEST]","[src] dir writing") as null|num
|
||||
if(isnum(new_data) && holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/dir/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || new_data in list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)/* + list(UP, DOWN)*/)
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/dir/display_pin_type()
|
||||
return IC_FORMAT_DIR
|
||||
|
||||
/datum/integrated_io/dir/display_data(var/input)
|
||||
if(!isnull(data))
|
||||
return "([dir2text(data)])"
|
||||
return ..()
|
||||
@@ -0,0 +1,148 @@
|
||||
// These pins contain a list. Null is not allowed.
|
||||
/datum/integrated_io/lists
|
||||
name = "list pin"
|
||||
data = list()
|
||||
|
||||
/datum/integrated_io/lists/ask_for_pin_data(mob/user)
|
||||
interact(user)
|
||||
|
||||
/datum/integrated_io/lists/proc/interact(mob/user)
|
||||
var/list/my_list = data
|
||||
var/t = "<h2>[src]</h2><br>"
|
||||
t += "List length: [my_list.len]<br>"
|
||||
t += "<a href='?src=[REF(src)]'>\[Refresh\]</a> | "
|
||||
t += "<a href='?src=[REF(src)];add=1'>\[Add\]</a> | "
|
||||
t += "<a href='?src=[REF(src)];swap=1'>\[Swap\]</a> | "
|
||||
t += "<a href='?src=[REF(src)];clear=1'>\[Clear\]</a><br>"
|
||||
t += "<hr>"
|
||||
var/i = 0
|
||||
for(var/line in my_list)
|
||||
i++
|
||||
t += "#[i] | [display_data(line)] | "
|
||||
t += "<a href='?src=[REF(src)];edit=1;pos=[i]'>\[Edit\]</a> | "
|
||||
t += "<a href='?src=[REF(src)];remove=1;pos=[i]'>\[Remove\]</a><br>"
|
||||
user << browse(t, "window=list_pin_[REF(src)];size=500x400")
|
||||
|
||||
/datum/integrated_io/lists/proc/add_to_list(mob/user, var/new_entry)
|
||||
if(!new_entry && user)
|
||||
new_entry = ask_for_data_type(user)
|
||||
if(is_valid(new_entry))
|
||||
Add(new_entry)
|
||||
|
||||
/datum/integrated_io/lists/proc/Add(var/new_entry)
|
||||
var/list/my_list = data
|
||||
if(my_list.len > IC_MAX_LIST_LENGTH)
|
||||
my_list.Cut(Start=1,End=2)
|
||||
my_list.Add(new_entry)
|
||||
|
||||
/datum/integrated_io/lists/proc/remove_from_list_by_position(mob/user, var/position)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
to_chat(user, "<span class='warning'>The list is empty, there's nothing to remove.</span>")
|
||||
return
|
||||
if(!position)
|
||||
return
|
||||
var/target_entry = my_list.Find(position)
|
||||
if(target_entry)
|
||||
my_list.Remove(target_entry)
|
||||
|
||||
/datum/integrated_io/lists/proc/remove_from_list(mob/user, var/target_entry)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
to_chat(user, "<span class='warning'>The list is empty, there's nothing to remove.</span>")
|
||||
return
|
||||
if(!target_entry)
|
||||
target_entry = input(user, "Which piece of data do you want to remove?", "Remove") as null|anything in my_list
|
||||
if(holder.check_interactivity(user) && target_entry)
|
||||
my_list.Remove(target_entry)
|
||||
|
||||
/datum/integrated_io/lists/proc/edit_in_list(mob/user, var/target_entry)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
to_chat(user, "<span class='warning'>The list is empty, there's nothing to modify.</span>")
|
||||
return
|
||||
if(!target_entry)
|
||||
target_entry = input(user, "Which piece of data do you want to edit?", "Edit") as null|anything in my_list
|
||||
if(holder.check_interactivity(user) && target_entry)
|
||||
var/edited_entry = ask_for_data_type(user, target_entry)
|
||||
if(edited_entry)
|
||||
target_entry = edited_entry
|
||||
|
||||
/datum/integrated_io/lists/proc/edit_in_list_by_position(mob/user, var/position)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
to_chat(user, "<span class='warning'>The list is empty, there's nothing to modify.</span>")
|
||||
return
|
||||
if(!position)
|
||||
return
|
||||
var/target_entry = my_list.Find(position)
|
||||
if(target_entry)
|
||||
var/edited_entry = ask_for_data_type(user, target_entry)
|
||||
if(edited_entry)
|
||||
target_entry = edited_entry
|
||||
|
||||
/datum/integrated_io/lists/proc/swap_inside_list(mob/user, var/first_target, var/second_target)
|
||||
var/list/my_list = data
|
||||
if(my_list.len <= 1)
|
||||
to_chat(user, "<span class='warning'>The list is empty, or too small to do any meaningful swapping.</span>")
|
||||
return
|
||||
if(!first_target)
|
||||
first_target = input(user, "Which piece of data do you want to swap? (1)", "Swap") as null|anything in my_list
|
||||
|
||||
if(holder.check_interactivity(user) && first_target)
|
||||
if(!second_target)
|
||||
second_target = input(user, "Which piece of data do you want to swap? (2)", "Swap") as null|anything in my_list - first_target
|
||||
|
||||
if(holder.check_interactivity(user) && second_target)
|
||||
var/first_pos = my_list.Find(first_target)
|
||||
var/second_pos = my_list.Find(second_target)
|
||||
my_list.Swap(first_pos, second_pos)
|
||||
|
||||
/datum/integrated_io/lists/proc/clear_list(mob/user)
|
||||
var/list/my_list = data
|
||||
my_list.Cut()
|
||||
|
||||
/datum/integrated_io/lists/scramble()
|
||||
var/list/my_list = data
|
||||
my_list = shuffle(my_list)
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/lists/write_data_to_pin(var/new_data)
|
||||
if(islist(new_data))
|
||||
var/list/new_list = new_data
|
||||
data = new_list.Copy(1,min( IC_MAX_LIST_LENGTH+1, new_list.len ))
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/lists/display_pin_type()
|
||||
return IC_FORMAT_LIST
|
||||
|
||||
/datum/integrated_io/lists/Topic(href, href_list)
|
||||
if(!holder.check_interactivity(usr))
|
||||
return
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(href_list["add"])
|
||||
add_to_list(usr)
|
||||
|
||||
if(href_list["swap"])
|
||||
swap_inside_list(usr)
|
||||
|
||||
if(href_list["clear"])
|
||||
clear_list(usr)
|
||||
|
||||
if(href_list["remove"])
|
||||
if(href_list["pos"])
|
||||
remove_from_list_by_position(usr, text2num(href_list["pos"]))
|
||||
else
|
||||
remove_from_list(usr)
|
||||
|
||||
if(href_list["edit"])
|
||||
if(href_list["pos"])
|
||||
edit_in_list_by_position(usr, text2num(href_list["pos"]))
|
||||
else
|
||||
edit_in_list(usr)
|
||||
|
||||
holder.interact(usr) // Refresh the main UI,
|
||||
interact(usr) // and the list UI.
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// These pins can only contain numbers (int and floating point) or null.
|
||||
/datum/integrated_io/number
|
||||
name = "number pin"
|
||||
// data = 0
|
||||
|
||||
/datum/integrated_io/number/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/number/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || isnum(new_data))
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/number/display_pin_type()
|
||||
return IC_FORMAT_NUMBER
|
||||
@@ -0,0 +1,14 @@
|
||||
// These pins only contain weakrefs or null.
|
||||
/datum/integrated_io/ref
|
||||
name = "ref pin"
|
||||
|
||||
/datum/integrated_io/ref/ask_for_pin_data(mob/user) // This clears the pin.
|
||||
write_data_to_pin(null)
|
||||
|
||||
/datum/integrated_io/ref/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || isweakref(new_data))
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/ref/display_pin_type()
|
||||
return IC_FORMAT_REF
|
||||
@@ -0,0 +1,27 @@
|
||||
// These pins can only contain text and null.
|
||||
/datum/integrated_io/string
|
||||
name = "string pin"
|
||||
|
||||
/datum/integrated_io/string/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please type in a string.","[src] string writing") as null|text
|
||||
if(holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data ? "[new_data]" : "NULL"] into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/string/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || istext(new_data))
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
// This makes the text go "from this" to "#G&*!HD$%L"
|
||||
/datum/integrated_io/string/scramble()
|
||||
if(!is_valid())
|
||||
return
|
||||
var/list/options = list("!","@","#","$","%","^","&","*","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
|
||||
var/new_data = ""
|
||||
for(var/i in 1 to length(data))
|
||||
new_data += pick(options)
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/string/display_pin_type()
|
||||
return IC_FORMAT_STRING
|
||||
@@ -0,0 +1,102 @@
|
||||
#define WIRE "wire"
|
||||
#define WIRING "wiring"
|
||||
#define UNWIRE "unwire"
|
||||
#define UNWIRING "unwiring"
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer
|
||||
name = "circuit wirer"
|
||||
desc = "It's a small wiring tool, with a wire roll, electric soldering iron, wire cutter, and more in one package. \
|
||||
The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \
|
||||
used for power or data transmission."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "wirer-wire"
|
||||
flags_1 = CONDUCT_1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/datum/integrated_io/selected_io = null
|
||||
var/mode = WIRE
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer/update_icon()
|
||||
icon_state = "wirer-[mode]"
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user)
|
||||
if(!io.holder.assembly)
|
||||
to_chat(user, "<span class='warning'>\The [io.holder] needs to be secured inside an assembly first.</span>")
|
||||
return
|
||||
if(mode == WIRE)
|
||||
selected_io = io
|
||||
to_chat(user, "<span class='notice'>You attach a data wire to \the [selected_io.holder]'s [selected_io.name] data channel.</span>")
|
||||
mode = WIRING
|
||||
update_icon()
|
||||
else if(mode == WIRING)
|
||||
if(io == selected_io)
|
||||
to_chat(user, "<span class='warning'>Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless.</span>")
|
||||
return
|
||||
if(io.io_type != selected_io.io_type)
|
||||
to_chat(user, "<span class='warning'>Those two types of channels are incompatable. The first is a [selected_io.io_type], \
|
||||
while the second is a [io.io_type].</span>")
|
||||
return
|
||||
if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly)
|
||||
to_chat(user, "<span class='warning'>Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.</span>")
|
||||
return
|
||||
selected_io.linked |= io
|
||||
io.linked |= selected_io
|
||||
|
||||
to_chat(user, "<span class='notice'>You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].</span>")
|
||||
mode = WIRE
|
||||
update_icon()
|
||||
selected_io.holder.interact(user) // This is to update the UI.
|
||||
selected_io = null
|
||||
|
||||
else if(mode == UNWIRE)
|
||||
selected_io = io
|
||||
if(!io.linked.len)
|
||||
to_chat(user, "<span class='warning'>There is nothing connected to \the [selected_io] data channel.</span>")
|
||||
selected_io = null
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You prepare to detach a data wire from \the [selected_io.holder]'s [selected_io.name] data channel.</span>")
|
||||
mode = UNWIRING
|
||||
update_icon()
|
||||
return
|
||||
|
||||
else if(mode == UNWIRING)
|
||||
if(io == selected_io)
|
||||
to_chat(user, "<span class='warning'>You can't wire a pin into each other, so unwiring \the [selected_io.holder] from \
|
||||
the same pin is rather moot.</span>")
|
||||
return
|
||||
if(selected_io in io.linked)
|
||||
io.linked.Remove(selected_io)
|
||||
selected_io.linked.Remove(io)
|
||||
to_chat(user, "<span class='notice'>You disconnect \the [selected_io.holder]'s [selected_io.name] from \
|
||||
\the [io.holder]'s [io.name].</span>")
|
||||
selected_io.holder.interact(user) // This is to update the UI.
|
||||
selected_io = null
|
||||
mode = UNWIRE
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [selected_io.holder]'s [selected_io.name] and \the [io.holder]'s \
|
||||
[io.name] are not connected.</span>")
|
||||
return
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer/attack_self(mob/user)
|
||||
switch(mode)
|
||||
if(WIRE)
|
||||
mode = UNWIRE
|
||||
if(WIRING)
|
||||
if(selected_io)
|
||||
to_chat(user, "<span class='notice'>You decide not to wire the data channel.</span>")
|
||||
selected_io = null
|
||||
mode = WIRE
|
||||
if(UNWIRE)
|
||||
mode = WIRE
|
||||
if(UNWIRING)
|
||||
if(selected_io)
|
||||
to_chat(user, "<span class='notice'>You decide not to disconnect the data channel.</span>")
|
||||
selected_io = null
|
||||
mode = UNWIRE
|
||||
update_icon()
|
||||
to_chat(user, "<span class='notice'>You set \the [src] to [mode].</span>")
|
||||
|
||||
#undef WIRE
|
||||
#undef WIRING
|
||||
#undef UNWIRE
|
||||
#undef UNWIRING
|
||||
@@ -0,0 +1,7 @@
|
||||
// 'Passive' components do not have any pins, and instead contribute in some form to the assembly holding them.
|
||||
/obj/item/integrated_circuit/passive
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
activators = list()
|
||||
power_draw_idle = 0
|
||||
power_draw_per_use = 0
|
||||
@@ -0,0 +1,126 @@
|
||||
|
||||
/obj/item/integrated_circuit/passive/power
|
||||
name = "power thingy"
|
||||
desc = "Does power stuff."
|
||||
complexity = 5
|
||||
origin_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2, TECH_DATA = 2)
|
||||
category_text = "Power - Passive"
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/proc/make_energy()
|
||||
return
|
||||
|
||||
// For calculators.
|
||||
/obj/item/integrated_circuit/passive/power/solar_cell
|
||||
name = "tiny photovoltaic cell"
|
||||
desc = "It's a very tiny solar cell, generally used in calculators."
|
||||
extended_desc = "The cell generates 1W of energy per second in optimal lighting conditions. Less light will result in less power being generated."
|
||||
icon_state = "solar_cell"
|
||||
complexity = 8
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/max_power = 30
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/solar_cell/make_energy()
|
||||
var/turf/T = get_turf(src)
|
||||
var/light_amount = T ? T.get_lumcount() : 0
|
||||
var/adjusted_power = max(max_power * light_amount, 0)
|
||||
adjusted_power = round(adjusted_power, 0.1)
|
||||
if(adjusted_power)
|
||||
if(assembly)
|
||||
assembly.give_power(adjusted_power)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/starter
|
||||
name = "starter"
|
||||
desc = "This tiny circuit will send pulse right after device is turned on. Or when power is restored."
|
||||
icon_state = "led"
|
||||
complexity = 1
|
||||
activators = list("pulse out" = IC_PINTYPE_PULSE_OUT)
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/is_charge = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/starter/make_energy()
|
||||
if(assembly.battery)
|
||||
if(assembly.battery.charge)
|
||||
if(!is_charge)
|
||||
activate_pin(1)
|
||||
is_charge = TRUE
|
||||
else
|
||||
is_charge = FALSE
|
||||
else
|
||||
is_charge=FALSE
|
||||
return FALSE
|
||||
|
||||
// For fat machines that need fat power, like drones.
|
||||
/obj/item/integrated_circuit/passive/power/relay
|
||||
name = "tesla power relay"
|
||||
desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
extended_desc = "The siphon generates 250W of energy, so long as an APC is in the same room, with a cell that has energy. It will always drain \
|
||||
from the 'equipment' power channel."
|
||||
icon_state = "power_relay"
|
||||
complexity = 7
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
var/power_amount = 150
|
||||
//fuel cell
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell
|
||||
name = "fuel cell"
|
||||
desc = "Produces electricity from chemicals."
|
||||
icon_state = "chemical_cell"
|
||||
extended_desc = "This is effectively an internal beaker.It will consume and produce power from phoron, slime jelly, welding fuel, carbon,\
|
||||
ethanol, nutriments and blood , in order of decreasing efficiency. It will consume fuel only if the battery can take more energy."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/volume = 60
|
||||
var/list/fuel = list("plasma" = 10000, "welding_fuel" = 3000, "carbon" = 2000, "ethanol"= 2000, "nutriment" =1600, "blood" = 1000)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/New()
|
||||
..()
|
||||
create_reagents(volume)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/make_energy()
|
||||
if(assembly)
|
||||
if(assembly.battery)
|
||||
for(var/I in fuel)
|
||||
if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > fuel[I])
|
||||
if(reagents.remove_reagent(I, 1))
|
||||
assembly.give_power(fuel[I])
|
||||
|
||||
|
||||
// For really fat machines.
|
||||
/obj/item/integrated_circuit/passive/power/relay/large
|
||||
name = "large tesla power relay"
|
||||
desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them, now in industiral size!"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
extended_desc = "The siphon generates 2 kW of energy, so long as an APC is in the same room, with a cell that has energy. It will always drain \
|
||||
from the 'equipment' power channel."
|
||||
icon_state = "power_relay"
|
||||
complexity = 15
|
||||
origin_tech = list(TECH_POWER = 6, TECH_ENGINEERING = 5, TECH_DATA = 4)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_amount = 1000
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/relay/make_energy()
|
||||
if(!assembly)
|
||||
return
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
if(A.powered(EQUIP) && assembly.give_power(power_amount))
|
||||
A.use_power(power_amount, EQUIP)
|
||||
// give_power() handles CELLRATE on its own.
|
||||
@@ -0,0 +1,319 @@
|
||||
//These circuits do simple math.
|
||||
/obj/item/integrated_circuit/arithmetic
|
||||
complexity = 1
|
||||
inputs = list(
|
||||
"A" = IC_PINTYPE_NUMBER,
|
||||
"B" = IC_PINTYPE_NUMBER,
|
||||
"C" = IC_PINTYPE_NUMBER,
|
||||
"D" = IC_PINTYPE_NUMBER,
|
||||
"E" = IC_PINTYPE_NUMBER,
|
||||
"F" = IC_PINTYPE_NUMBER,
|
||||
"G" = IC_PINTYPE_NUMBER,
|
||||
"H" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list("result" = IC_PINTYPE_NUMBER)
|
||||
activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Arithmetic"
|
||||
power_draw_per_use = 5 // Math is pretty cheap.
|
||||
|
||||
// +Adding+ //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/addition
|
||||
name = "addition circuit"
|
||||
desc = "This circuit can add numbers together."
|
||||
extended_desc = "The order that the calculation goes is;<br>\
|
||||
result = ((((A + B) + C) + D) ... ) and so on, until all pins have been added. \
|
||||
Null pins are ignored."
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/addition/do_work()
|
||||
var/result = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result + I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// -Subtracting- //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/subtraction
|
||||
name = "subtraction circuit"
|
||||
desc = "This circuit can subtract numbers."
|
||||
extended_desc = "The order that the calculation goes is;<br>\
|
||||
result = ((((A - B) - C) - D) ... ) and so on, until all pins have been subtracted. \
|
||||
Null pins are ignored. Pin A <b>must</b> be a number or the circuit will not function."
|
||||
icon_state = "subtraction"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/subtraction/do_work()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
if(!isnum(A.data))
|
||||
return
|
||||
var/result = A.data
|
||||
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I == A)
|
||||
continue
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result - I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// *Multiply* //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/multiplication
|
||||
name = "multiplication circuit"
|
||||
desc = "This circuit can multiply numbers."
|
||||
extended_desc = "The order that the calculation goes is;<br>\
|
||||
result = ((((A * B) * C) * D) ... ) and so on, until all pins have been multiplied. \
|
||||
Null pins are ignored. Pin A <b>must</b> be a number or the circuit will not function."
|
||||
icon_state = "multiplication"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/multiplication/do_work()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
if(!isnum(A.data))
|
||||
return
|
||||
var/result = A.data
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I == A)
|
||||
continue
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result * I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// /Division/ //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/division
|
||||
name = "division circuit"
|
||||
desc = "This circuit can divide numbers, just don't think about trying to divide by zero!"
|
||||
extended_desc = "The order that the calculation goes is;<br>\
|
||||
result = ((((A / B) / C) / D) ... ) and so on, until all pins have been divided. \
|
||||
Null pins, and pins containing 0, are ignored. Pin A <b>must</b> be a number or the circuit will not function."
|
||||
icon_state = "division"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/division/do_work()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
if(!isnum(A.data))
|
||||
return
|
||||
var/result = A.data
|
||||
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I == A)
|
||||
continue
|
||||
I.pull_data()
|
||||
if(isnum(I.data) && I.data != 0) //No runtimes here.
|
||||
result = result / I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
//^ Exponent ^//
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/exponent
|
||||
name = "exponent circuit"
|
||||
desc = "Outputs A to the power of B."
|
||||
icon_state = "exponent"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/exponent/do_work()
|
||||
var/result = 0
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
if(isnum(A.data) && isnum(B.data))
|
||||
result = A.data ** B.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// +-Sign-+ //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/sign
|
||||
name = "sign circuit"
|
||||
desc = "This will say if a number is positive, negative, or zero."
|
||||
extended_desc = "Will output 1, -1, or 0, depending on if A is a postive number, a negative number, or zero, respectively."
|
||||
icon_state = "sign"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/sign/do_work()
|
||||
var/result = 0
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
if(isnum(A.data))
|
||||
if(A.data > 0)
|
||||
result = 1
|
||||
else if (A.data < 0)
|
||||
result = -1
|
||||
else
|
||||
result = 0
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Round //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/round
|
||||
name = "round circuit"
|
||||
desc = "Rounds A to the nearest B multiple of A."
|
||||
extended_desc = "If B is not given a number, it will output the floor of A instead."
|
||||
icon_state = "round"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/round/do_work()
|
||||
var/result = 0
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
if(isnum(A.data))
|
||||
if(isnum(B.data) && B.data != 0)
|
||||
result = round(A.data, B.data)
|
||||
else
|
||||
result = round(A.data)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Absolute //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/absolute
|
||||
name = "absolute circuit"
|
||||
desc = "This outputs a non-negative version of the number you put in. This may also be thought of as its distance from zero."
|
||||
icon_state = "absolute"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/absolute/do_work()
|
||||
var/result = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = abs(I.data)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Averaging //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/average
|
||||
name = "average circuit"
|
||||
desc = "This circuit is of average quality, however it will compute the average for numbers you give it."
|
||||
extended_desc = "Note that null pins are ignored, where as a pin containing 0 is included in the averaging calculation."
|
||||
icon_state = "average"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/average/do_work()
|
||||
var/result = 0
|
||||
var/inputs_used = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
inputs_used++
|
||||
result = result + I.data
|
||||
|
||||
if(inputs_used)
|
||||
result = result / inputs_used
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Pi, because why the hell not? //
|
||||
/obj/item/integrated_circuit/arithmetic/pi
|
||||
name = "pi constant circuit"
|
||||
desc = "Not recommended for cooking. Outputs '3.14159' when it receives a pulse."
|
||||
icon_state = "pi"
|
||||
inputs = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/pi/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, 3.14159)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Random //
|
||||
/obj/item/integrated_circuit/arithmetic/random
|
||||
name = "random number generator circuit"
|
||||
desc = "This gives a random (integer) number between values A and B inclusive."
|
||||
extended_desc = "'Inclusive' means that the upper bound is included in the range of numbers, e.g. L = 1 and H = 3 will allow \
|
||||
for outputs of 1, 2, or 3. H being the higher number is not <i>strictly</i> required."
|
||||
icon_state = "random"
|
||||
inputs = list("L" = IC_PINTYPE_NUMBER,"H" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/random/do_work()
|
||||
var/result = 0
|
||||
var/L = get_pin_data(IC_INPUT, 1)
|
||||
var/H = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(isnum(L) && isnum(H))
|
||||
result = rand(L, H)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Square Root //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/square_root
|
||||
name = "square root circuit"
|
||||
desc = "This outputs the square root of a number you put in."
|
||||
icon_state = "square_root"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/square_root/do_work()
|
||||
var/result = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = sqrt(I.data)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// % Modulo % //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/modulo
|
||||
name = "modulo circuit"
|
||||
desc = "Gets the remainder of A / B."
|
||||
icon_state = "modulo"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/modulo/do_work()
|
||||
var/result = 0
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
var/B = get_pin_data(IC_INPUT, 2)
|
||||
if(isnum(A) && isnum(B) && B != 0)
|
||||
result = A % B
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -0,0 +1,320 @@
|
||||
//These circuits convert one variable to another.
|
||||
/obj/item/integrated_circuit/converter
|
||||
complexity = 2
|
||||
inputs = list("input")
|
||||
outputs = list("output")
|
||||
activators = list("convert" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Converter"
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/converter/num2text
|
||||
name = "number to string"
|
||||
desc = "This circuit can convert a number variable into a string."
|
||||
extended_desc = "Because of game limitations null/false variables will output a '0' string."
|
||||
icon_state = "num-string"
|
||||
inputs = list("input" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/num2text/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = num2text(incoming)
|
||||
else if(!incoming)
|
||||
result = "0"
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/text2num
|
||||
name = "string to number"
|
||||
desc = "This circuit can convert a string variable into a number."
|
||||
icon_state = "string-num"
|
||||
inputs = list("input" = IC_PINTYPE_STRING)
|
||||
outputs = list("output" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/text2num/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = text2num(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/ref2text
|
||||
name = "reference to string"
|
||||
desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference."
|
||||
icon_state = "ref-string"
|
||||
inputs = list("input" = IC_PINTYPE_REF)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/ref2text/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/atom/A = get_pin_data(IC_INPUT, 1)
|
||||
if(A && istype(A))
|
||||
result = A.name
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/refcode
|
||||
name = "reference encoder"
|
||||
desc = "This circuit can encode a reference into a string, which can then be read by an EPV2 circuit."
|
||||
icon_state = "ref-string"
|
||||
inputs = list("input" = IC_PINTYPE_REF)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/refcode/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/atom/A = get_pin_data(IC_INPUT, 1)
|
||||
if(A && istype(A))
|
||||
result = strtohex(XorEncrypt(REF(A),SScircuit.cipherkey))
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/refdecode
|
||||
name = "reference decoder"
|
||||
desc = "This circuit can convert a encoded reference to actual reference."
|
||||
icon_state = "ref-string"
|
||||
inputs = list("input" = IC_PINTYPE_STRING)
|
||||
outputs = list("output" = IC_PINTYPE_REF)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/dec
|
||||
|
||||
/obj/item/integrated_circuit/converter/refdecode/do_work()
|
||||
pull_data()
|
||||
dec=XorEncrypt(hextostr(get_pin_data(IC_INPUT, 1)),SScircuit.cipherkey)
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(locate( dec )))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/lowercase
|
||||
name = "lowercase string converter"
|
||||
desc = "this will cause a string to come out in all lowercase."
|
||||
icon_state = "lowercase"
|
||||
inputs = list("input" = IC_PINTYPE_STRING)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/lowercase/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = lowertext(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/uppercase
|
||||
name = "uppercase string converter"
|
||||
desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE."
|
||||
icon_state = "uppercase"
|
||||
inputs = list("input" = IC_PINTYPE_STRING)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/uppercase/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = uppertext(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator
|
||||
name = "concatenator"
|
||||
desc = "This joins many strings together to get one big string."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"A" = IC_PINTYPE_STRING,
|
||||
"B" = IC_PINTYPE_STRING,
|
||||
"C" = IC_PINTYPE_STRING,
|
||||
"D" = IC_PINTYPE_STRING,
|
||||
"E" = IC_PINTYPE_STRING,
|
||||
"F" = IC_PINTYPE_STRING,
|
||||
"G" = IC_PINTYPE_STRING,
|
||||
"H" = IC_PINTYPE_STRING
|
||||
)
|
||||
outputs = list("result" = IC_PINTYPE_STRING)
|
||||
activators = list("concatenate" = IC_PINTYPE_PULSE_IN, "on concatenated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator/do_work()
|
||||
var/result = null
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
I.pull_data()
|
||||
if(!isnull(I.data))
|
||||
result = result + I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/separator
|
||||
name = "separator"
|
||||
desc = "This splits as single string into two at the relative split point."
|
||||
extended_desc = "This circuits splits a given string into two, based on the string, and the index value. \
|
||||
The index splits the string <b>after</b> the given index, including spaces. So 'a person' with an index of '3' \
|
||||
will split into 'a p' and 'erson'."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"string to split" = IC_PINTYPE_STRING,
|
||||
"index" = IC_PINTYPE_NUMBER,
|
||||
)
|
||||
outputs = list(
|
||||
"before split" = IC_PINTYPE_STRING,
|
||||
"after split" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/separator/do_work()
|
||||
var/text = get_pin_data(IC_INPUT, 1)
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
var/split = min(index+1, length(text))
|
||||
|
||||
var/before_text = copytext(text, 1, split)
|
||||
var/after_text = copytext(text, split, 0)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, before_text)
|
||||
set_pin_data(IC_OUTPUT, 2, after_text)
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/findstring
|
||||
name = "find text"
|
||||
desc = "This gives position of sample in the string. Or returns 0."
|
||||
extended_desc = "The first pin is the string to be examined. The second pin is the sample to be found. \
|
||||
For example, 'eat this burger',' ' will give you position 4. This circuit isn't case sensitive."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"string" = IC_PINTYPE_STRING,
|
||||
"sample" = IC_PINTYPE_STRING,
|
||||
)
|
||||
outputs = list(
|
||||
"position" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/converter/findstring/do_work()
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2)) )
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/exploders
|
||||
name = "string exploder"
|
||||
desc = "This splits a single string into a list of strings."
|
||||
extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \
|
||||
For example, 'eat this burger',' ' will be converted to list('eat','this','burger')."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"string to split" = IC_PINTYPE_STRING,
|
||||
"delimiter" = IC_PINTYPE_STRING,
|
||||
)
|
||||
outputs = list(
|
||||
"list" = IC_PINTYPE_LIST
|
||||
)
|
||||
activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/exploders/do_work()
|
||||
var/strin = get_pin_data(IC_INPUT, 1)
|
||||
var/sample = get_pin_data(IC_INPUT, 2)
|
||||
set_pin_data(IC_OUTPUT, 1, splittext( strin ,sample ))
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/radians2degrees
|
||||
name = "radians to degrees converter"
|
||||
desc = "Converts radians to degrees."
|
||||
inputs = list("radian" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("degrees" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/radians2degrees/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = ToDegrees(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/degrees2radians
|
||||
name = "degrees to radians converter"
|
||||
desc = "Converts degrees to radians."
|
||||
inputs = list("degrees" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("radians" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/degrees2radians/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = ToRadians(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/converter/abs_to_rel_coords
|
||||
name = "abs to rel coordinate converter"
|
||||
desc = "Easily convert absolute coordinates to relative coordinates with this."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"X1" = IC_PINTYPE_NUMBER,
|
||||
"Y1" = IC_PINTYPE_NUMBER,
|
||||
"X2" = IC_PINTYPE_NUMBER,
|
||||
"Y2" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list(
|
||||
"X" = IC_PINTYPE_NUMBER,
|
||||
"Y" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("compute rel coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work()
|
||||
var/x1 = get_pin_data(IC_INPUT, 1)
|
||||
var/y1 = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
var/x2 = get_pin_data(IC_INPUT, 3)
|
||||
var/y2 = get_pin_data(IC_INPUT, 4)
|
||||
|
||||
if(!isnull(x1) && !isnull(y1) && !isnull(x2) && !isnull(y2))
|
||||
set_pin_data(IC_OUTPUT, 1, x1 - x2)
|
||||
set_pin_data(IC_OUTPUT, 2, y1 - y2)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -0,0 +1,146 @@
|
||||
/obj/item/integrated_circuit/transfer
|
||||
category_text = "Data Transfer"
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer
|
||||
name = "two multiplexer"
|
||||
desc = "This is what those in the business tend to refer to as a 'mux' or data selector. It moves data from one of the selected inputs to the output."
|
||||
extended_desc = "The first input pin is used to select which of the other input pins which has its data moved to the output. \
|
||||
If the input selection is outside the valid range then no output is given."
|
||||
complexity = 2
|
||||
icon_state = "mux2"
|
||||
inputs = list("input selection" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("output" = IC_PINTYPE_ANY)
|
||||
activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
var/number_of_inputs = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/New()
|
||||
for(var/i = 1 to number_of_inputs)
|
||||
inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called.
|
||||
// inputs += "input [i]"
|
||||
complexity = number_of_inputs
|
||||
..()
|
||||
desc += " It has [number_of_inputs] input pins."
|
||||
extended_desc += " This multiplexer has a range from 1 to [inputs.len - 1]."
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/do_work()
|
||||
var/input_index = get_pin_data(IC_INPUT, 1)
|
||||
|
||||
if(!isnull(input_index) && (input_index >= 1 && input_index < inputs.len))
|
||||
set_pin_data(IC_OUTPUT, 1,get_pin_data(IC_INPUT, input_index + 1))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/medium
|
||||
name = "four multiplexer"
|
||||
number_of_inputs = 4
|
||||
icon_state = "mux4"
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/large
|
||||
name = "eight multiplexer"
|
||||
number_of_inputs = 8
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon_state = "mux8"
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/huge
|
||||
name = "sixteen multiplexer"
|
||||
icon_state = "mux16"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_inputs = 16
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer
|
||||
name = "two demultiplexer"
|
||||
desc = "This is what those in the business tend to refer to as a 'demux'. It moves data from the input to one of the selected outputs."
|
||||
extended_desc = "The first input pin is used to select which of the output pins is given the data from the second input pin. \
|
||||
If the output selection is outside the valid range then no output is given."
|
||||
complexity = 2
|
||||
icon_state = "dmux2"
|
||||
inputs = list("output selection" = IC_PINTYPE_NUMBER, "input" = IC_PINTYPE_ANY)
|
||||
outputs = list()
|
||||
activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
var/number_of_outputs = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/New()
|
||||
for(var/i = 1 to number_of_outputs)
|
||||
// outputs += "output [i]"
|
||||
outputs["output [i]"] = IC_PINTYPE_ANY
|
||||
complexity = number_of_outputs
|
||||
|
||||
..()
|
||||
desc += " It has [number_of_outputs] output pins."
|
||||
extended_desc += " This demultiplexer has a range from 1 to [outputs.len]."
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/do_work()
|
||||
var/output_index = get_pin_data(IC_INPUT, 1)
|
||||
for(var/i = 1 to outputs.len)
|
||||
set_pin_data(IC_OUTPUT, i, i == output_index ? get_pin_data(IC_INPUT, 2) : null)
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/medium
|
||||
name = "four demultiplexer"
|
||||
icon_state = "dmux4"
|
||||
number_of_outputs = 4
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/large
|
||||
name = "eight demultiplexer"
|
||||
icon_state = "dmux8"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_outputs = 8
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/huge
|
||||
name = "sixteen demultiplexer"
|
||||
icon_state = "dmux16"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_outputs = 16
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer
|
||||
name = "two pulse demultiplexer"
|
||||
desc = "Selector switch to choose the pin to be activated by number."
|
||||
extended_desc = "The first input pin is used to select which of the pulse out pins will be activated after activation of the circuit. \
|
||||
If the output selection is outside the valid range then no output is given."
|
||||
complexity = 2
|
||||
icon_state = "dmux2"
|
||||
inputs = list("output selection" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("select" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
var/number_of_outputs = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/New()
|
||||
for(var/i = 1 to number_of_outputs)
|
||||
// outputs += "output [i]"
|
||||
activators["output [i]"] = IC_PINTYPE_PULSE_OUT
|
||||
complexity = number_of_outputs
|
||||
|
||||
..()
|
||||
desc += " It has [number_of_outputs] output pins."
|
||||
extended_desc += " This pulse demultiplexer has a range from 1 to [activators.len - 1]."
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work()
|
||||
var/output_index = get_pin_data(IC_INPUT, 1)
|
||||
|
||||
if(output_index == Clamp(output_index, 1, number_of_outputs))
|
||||
activate_pin(round(output_index + 1 ,1))
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium
|
||||
name = "four pulse demultiplexer"
|
||||
icon_state = "dmux4"
|
||||
number_of_outputs = 4
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/large
|
||||
name = "eight pulse demultiplexer"
|
||||
icon_state = "dmux8"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_outputs = 8
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/huge
|
||||
name = "sixteen pulse demultiplexer"
|
||||
icon_state = "dmux16"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_outputs = 16
|
||||
@@ -0,0 +1,806 @@
|
||||
/obj/item/integrated_circuit/input
|
||||
var/can_be_asked_input = 0
|
||||
category_text = "Input"
|
||||
power_draw_per_use = 5
|
||||
|
||||
/obj/item/integrated_circuit/input/proc/ask_for_input(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/input/button
|
||||
name = "button"
|
||||
desc = "This tiny button must do something, right?"
|
||||
icon_state = "button"
|
||||
complexity = 1
|
||||
can_be_asked_input = 1
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
activators = list("on pressed" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use.
|
||||
to_chat(user, "<span class='notice'>You press the button labeled '[src]'.</span>")
|
||||
activate_pin(1)
|
||||
|
||||
/obj/item/integrated_circuit/input/toggle_button
|
||||
name = "toggle button"
|
||||
desc = "It toggles on, off, on, off..."
|
||||
icon_state = "toggle_button"
|
||||
complexity = 1
|
||||
can_be_asked_input = 1
|
||||
inputs = list()
|
||||
outputs = list("on" = IC_PINTYPE_BOOLEAN)
|
||||
activators = list("on toggle" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto.
|
||||
set_pin_data(IC_OUTPUT, 1, !get_pin_data(IC_OUTPUT, 1))
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
to_chat(user, "<span class='notice'>You toggle the button labeled '[src]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].</span>")
|
||||
|
||||
/obj/item/integrated_circuit/input/numberpad
|
||||
name = "number pad"
|
||||
desc = "This small number pad allows someone to input a number into the system."
|
||||
icon_state = "numberpad"
|
||||
complexity = 2
|
||||
can_be_asked_input = 1
|
||||
inputs = list()
|
||||
outputs = list("number entered" = IC_PINTYPE_NUMBER)
|
||||
activators = list("on entered" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user)
|
||||
var/new_input = input(user, "Enter a number, please.","Number pad") as null|num
|
||||
if(isnum(new_input) && user.IsAdvancedToolUser())
|
||||
set_pin_data(IC_OUTPUT, 1, new_input)
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
|
||||
/obj/item/integrated_circuit/input/textpad
|
||||
name = "text pad"
|
||||
desc = "This small text pad allows someone to input a string into the system."
|
||||
icon_state = "textpad"
|
||||
complexity = 2
|
||||
can_be_asked_input = 1
|
||||
inputs = list()
|
||||
outputs = list("string entered" = IC_PINTYPE_STRING)
|
||||
activators = list("on entered" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user)
|
||||
var/new_input = input(user, "Enter some words, please.","Number pad") as null|text
|
||||
if(istext(new_input) && user.IsAdvancedToolUser())
|
||||
set_pin_data(IC_OUTPUT, 1, new_input)
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
|
||||
/obj/item/integrated_circuit/input/med_scanner
|
||||
name = "integrated medical analyser"
|
||||
desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is."
|
||||
icon_state = "medscan"
|
||||
complexity = 4
|
||||
inputs = list("\<REF\> target")
|
||||
outputs = list(
|
||||
"total health %" = IC_PINTYPE_NUMBER,
|
||||
"total missing health" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
power_draw_per_use = 40
|
||||
|
||||
/obj/item/integrated_circuit/input/med_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.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)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
/*
|
||||
/obj/item/integrated_circuit/input/pressure_plate
|
||||
name = "pressure plate"
|
||||
desc = "Electronic plate with a scanner, that could retrieve references to things,that was put onto the machine"
|
||||
icon_state = "pressure_plate"
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("laid" = IC_PINTYPE_REF, "removed" = IC_PINTYPE_REF)
|
||||
activators = list("laid" = IC_PINTYPE_PULSE_OUT, "removed" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
power_draw_per_use = 40
|
||||
var/list/cont
|
||||
|
||||
/obj/item/integrated_circuit/input/pressure_plate/New()
|
||||
..()
|
||||
processing_objects |= src
|
||||
|
||||
/obj/item/integrated_circuit/input/pressure_plate/Destroy()
|
||||
processing_objects -= src
|
||||
|
||||
/obj/item/integrated_circuit/input/pressure_plate/process()
|
||||
var/list/newcont
|
||||
var/turf/T = get_turf(src)
|
||||
newcont = T.contents
|
||||
var/list/U = cont & newcont
|
||||
for(var/laid in U)
|
||||
if(!(laid in cont))
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = WEAKREF(laid)
|
||||
O.push_data()
|
||||
activate_pin(1)
|
||||
break
|
||||
for(var/removed in U)
|
||||
if(!(removed in newcont))
|
||||
var/datum/integrated_io/O = outputs[2]
|
||||
O.data = WEAKREF(removed)
|
||||
O.push_data()
|
||||
activate_pin(2)
|
||||
break
|
||||
cont = newcont
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/adv_med_scanner
|
||||
name = "integrated advanced medical analyser"
|
||||
desc = "A very small version of the medbot's medical analyser. This allows the machine to know how healthy someone is. \
|
||||
This type is much more precise, allowing the machine to know much more about the target than a normal analyzer."
|
||||
icon_state = "medscan_adv"
|
||||
complexity = 12
|
||||
inputs = list("\<REF\> target")
|
||||
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
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4)
|
||||
power_draw_per_use = 80
|
||||
|
||||
/obj/item/integrated_circuit/input/adv_med_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(H))) // Like medbot's analyzer it can be used in 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())
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/plant_scanner
|
||||
name = "integrated plant analyzer"
|
||||
desc = "A very small version of the plant analyser. This allows the machine to know all valuable params of plants in trays. \
|
||||
it can't scan seeds and fruits.only plants."
|
||||
icon_state = "medscan_adv"
|
||||
complexity = 12
|
||||
inputs = list("\<REF\> target")
|
||||
outputs = list(
|
||||
"plant type" = IC_PINTYPE_STRING,
|
||||
"age" = IC_PINTYPE_NUMBER,
|
||||
"potency" = IC_PINTYPE_NUMBER,
|
||||
"yield" = IC_PINTYPE_NUMBER,
|
||||
"Maturation speed" = IC_PINTYPE_NUMBER,
|
||||
"Production speed" = IC_PINTYPE_NUMBER,
|
||||
"Endurance" = IC_PINTYPE_NUMBER,
|
||||
"Lifespan" = IC_PINTYPE_NUMBER,
|
||||
"Weed Growth Rate" = IC_PINTYPE_NUMBER,
|
||||
"Weed Vulnerability" = IC_PINTYPE_NUMBER,
|
||||
"Weed level" = IC_PINTYPE_NUMBER,
|
||||
"Pest level" = IC_PINTYPE_NUMBER,
|
||||
"Toxicity level" = IC_PINTYPE_NUMBER,
|
||||
"Water level" = IC_PINTYPE_NUMBER,
|
||||
"Nutrition level" = IC_PINTYPE_NUMBER,
|
||||
"harvest" = IC_PINTYPE_NUMBER,
|
||||
"dead" = IC_PINTYPE_NUMBER ,
|
||||
"plant health" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4)
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/input/plant_scanner/do_work()
|
||||
var/obj/machinery/hydroponics/H = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
for(var/i=1, i<=outputs.len, i++)
|
||||
set_pin_data(IC_OUTPUT, i, null)
|
||||
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
|
||||
if(H.myseed)
|
||||
set_pin_data(IC_OUTPUT, 1, H.myseed.plantname)
|
||||
set_pin_data(IC_OUTPUT, 2, H.age)
|
||||
set_pin_data(IC_OUTPUT, 3, H.myseed.potency)
|
||||
set_pin_data(IC_OUTPUT, 4, H.myseed.yield)
|
||||
set_pin_data(IC_OUTPUT, 5, H.myseed.maturation)
|
||||
set_pin_data(IC_OUTPUT, 6, H.myseed.production)
|
||||
set_pin_data(IC_OUTPUT, 7, H.myseed.endurance)
|
||||
set_pin_data(IC_OUTPUT, 8, H.myseed.lifespan)
|
||||
set_pin_data(IC_OUTPUT, 9, H.myseed.weed_rate)
|
||||
set_pin_data(IC_OUTPUT, 10, H.myseed.weed_chance)
|
||||
set_pin_data(IC_OUTPUT, 11, H.weedlevel)
|
||||
set_pin_data(IC_OUTPUT, 12, H.pestlevel)
|
||||
set_pin_data(IC_OUTPUT, 13, H.toxic)
|
||||
set_pin_data(IC_OUTPUT, 14, H.waterlevel)
|
||||
set_pin_data(IC_OUTPUT, 15, H.nutrilevel)
|
||||
set_pin_data(IC_OUTPUT, 16, H.harvest)
|
||||
set_pin_data(IC_OUTPUT, 17, H.dead)
|
||||
set_pin_data(IC_OUTPUT, 18, H.plant_health)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/gene_scanner
|
||||
name = "gene scanner"
|
||||
desc = "This circuit will scan plant for traits and reagent genes."
|
||||
extended_desc = "This allows the machine to scan plants in trays for reagent and trait genes. \
|
||||
it can't scan seeds and fruits.only plants."
|
||||
inputs = list(
|
||||
"\<REF\> target" = IC_PINTYPE_REF
|
||||
)
|
||||
outputs = list(
|
||||
"traits" = IC_PINTYPE_LIST,
|
||||
"reagents" = IC_PINTYPE_LIST
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
icon_state = "medscan_adv"
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/input/gene_scanner/do_work()
|
||||
var/list/gtraits = list()
|
||||
var/list/greagents = list()
|
||||
var/obj/machinery/hydroponics/H = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
for(var/i=1, i<=outputs.len, i++)
|
||||
set_pin_data(IC_OUTPUT, i, null)
|
||||
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
|
||||
if(H.myseed)
|
||||
for(var/datum/plant_gene/reagent/G in H.myseed.genes)
|
||||
greagents.Add(G.get_name())
|
||||
|
||||
for(var/datum/plant_gene/trait/G in H.myseed.genes)
|
||||
gtraits.Add(G.get_name())
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, gtraits)
|
||||
set_pin_data(IC_OUTPUT, 2, greagents)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/examiner
|
||||
name = "examiner"
|
||||
desc = "It' s a little machine vision system. It can return the name, description, distance, \
|
||||
relative coordinates, total amount of reagents, and maximum amount of reagents of the referenced object."
|
||||
icon_state = "video_camera"
|
||||
complexity = 6
|
||||
inputs = list("\<REF\> target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"name" = IC_PINTYPE_STRING,
|
||||
"description" = IC_PINTYPE_STRING,
|
||||
"X" = IC_PINTYPE_NUMBER,
|
||||
"Y" = IC_PINTYPE_NUMBER,
|
||||
"distance" = IC_PINTYPE_NUMBER,
|
||||
"max reagents" = IC_PINTYPE_NUMBER,
|
||||
"amount of reagents" = IC_PINTYPE_NUMBER,
|
||||
)
|
||||
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 = 4)
|
||||
power_draw_per_use = 80
|
||||
|
||||
/obj/item/integrated_circuit/input/examiner/do_work()
|
||||
var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
|
||||
if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see.
|
||||
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, H.name)
|
||||
set_pin_data(IC_OUTPUT, 2, H.desc)
|
||||
set_pin_data(IC_OUTPUT, 3, H.x-T.x)
|
||||
set_pin_data(IC_OUTPUT, 4, H.y-T.y)
|
||||
set_pin_data(IC_OUTPUT, 5, sqrt((H.x-T.x)*(H.x-T.x)+ (H.y-T.y)*(H.y-T.y)))
|
||||
var/mr = 0
|
||||
var/tr = 0
|
||||
if(H.reagents)
|
||||
mr = H.reagents.maximum_volume
|
||||
tr = H.reagents.total_volume
|
||||
set_pin_data(IC_OUTPUT, 6, mr)
|
||||
set_pin_data(IC_OUTPUT, 7, tr)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
|
||||
/obj/item/integrated_circuit/input/local_locator
|
||||
name = "local locator"
|
||||
desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \
|
||||
that is holding the machine containing it."
|
||||
inputs = list()
|
||||
outputs = list("located ref")
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/input/local_locator/do_work()
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
if(assembly)
|
||||
if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us.
|
||||
O.data = WEAKREF(assembly.loc)
|
||||
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/input/adjacent_locator
|
||||
name = "adjacent locator"
|
||||
desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \
|
||||
that is standing a meter away from the machine."
|
||||
extended_desc = "The first pin requires a ref to a kind of object that you want the locator to acquire. This means that it will \
|
||||
give refs to nearby objects that are similar. If more than one valid object is found nearby, it will choose one of them at \
|
||||
random."
|
||||
inputs = list("desired type ref")
|
||||
outputs = list("located ref")
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,
|
||||
"not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
|
||||
/obj/item/integrated_circuit/input/adjacent_locator/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
|
||||
if(!isweakref(I.data))
|
||||
return
|
||||
var/atom/A = I.data.resolve()
|
||||
if(!A)
|
||||
return
|
||||
var/desired_type = A.type
|
||||
|
||||
var/list/nearby_things = range(1, get_turf(src))
|
||||
var/list/valid_things = list()
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(thing.type != desired_type)
|
||||
continue
|
||||
valid_things.Add(thing)
|
||||
if(valid_things.len)
|
||||
O.data = WEAKREF(pick(valid_things))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list
|
||||
complexity = 6
|
||||
name = "list advanced locator"
|
||||
desc = "This is needed for certain devices that demand list of names for a targets to act upon. This type locates something \
|
||||
that is standing in given radius up to 8 meters"
|
||||
extended_desc = "The first pin requires list a kinds of object that you want the locator to acquire. If This means that it will \
|
||||
give refs to nearby objects that are similar. It will locate objects by given names and description,given in list. It will give list of all found objects.\
|
||||
.The second pin is a radius"
|
||||
inputs = list("desired type ref" = IC_PINTYPE_LIST, "radius" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("located ref" = IC_PINTYPE_LIST)
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
var/radius = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list/on_data_written()
|
||||
var/rad = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(isnum(rad))
|
||||
rad = Clamp(rad, 0, 8)
|
||||
radius = rad
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/nearby_things = view(radius,T)
|
||||
var/list/valid_things = list()
|
||||
var/list/GI = list()
|
||||
GI = I.data
|
||||
for(var/G in GI)
|
||||
if(isweakref(G)) //It should search by refs. But don't want.will fix it later.
|
||||
var/datum/integrated_io/G1
|
||||
G1.data = G
|
||||
var/atom/A = G1.data.resolve()
|
||||
var/desired_type = A.type
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(thing.type != desired_type)
|
||||
continue
|
||||
valid_things.Add(WEAKREF(thing))
|
||||
else if(istext(G))
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(findtext(addtext(thing.name," ",thing.desc), G, 1, 0) )
|
||||
valid_things.Add(WEAKREF(thing))
|
||||
if(valid_things.len)
|
||||
O.data = valid_things
|
||||
O.push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
O.push_data()
|
||||
activate_pin(3)
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator
|
||||
complexity = 6
|
||||
name = "advanced locator"
|
||||
desc = "This is needed for certain devices that demand a reference for a target to act upon. This type locates something \
|
||||
that is standing in given radius up to 8 meters"
|
||||
extended_desc = "The first pin requires a ref to a kind of object that you want the locator to acquire. If This means that it will \
|
||||
give refs to nearby objects that are similar. If this pin is string, locator will search\
|
||||
item by matching desired text in name + description. If more than one valid object is found nearby, it will choose one of them at \
|
||||
random. The second pin is a radius."
|
||||
inputs = list("desired type" = IC_PINTYPE_ANY, "radius" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("located ref")
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
var/radius = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator/on_data_written()
|
||||
var/rad = get_pin_data(IC_INPUT, 2)
|
||||
if(isnum(rad))
|
||||
rad = Clamp(rad, 0, 8)
|
||||
radius = rad
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/nearby_things = view(radius,T)
|
||||
var/list/valid_things = list()
|
||||
if(isweakref(I.data))
|
||||
var/atom/A = I.data.resolve()
|
||||
var/desired_type = A.type
|
||||
if(desired_type)
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(thing.type == desired_type)
|
||||
valid_things.Add(thing)
|
||||
else if(istext(I.data))
|
||||
var/DT = I.data
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(findtext(addtext(thing.name," ",thing.desc), DT, 1, 0) )
|
||||
valid_things.Add(thing)
|
||||
if(valid_things.len)
|
||||
O.data = WEAKREF(pick(valid_things))
|
||||
O.push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
O.push_data()
|
||||
activate_pin(3)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler
|
||||
name = "integrated signaler"
|
||||
desc = "Signals from a signaler can be received with this, allowing for remote control. Additionally, it can send signals as well."
|
||||
extended_desc = "When a signal is received from another signaler, the 'on signal received' activator pin will be pulsed. \
|
||||
The two input pins are to configure the integrated signaler's settings. Note that the frequency should not have a decimal in it. \
|
||||
Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin."
|
||||
icon_state = "signal"
|
||||
complexity = 4
|
||||
inputs = list("frequency" = IC_PINTYPE_NUMBER,"code" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list(
|
||||
"send signal" = IC_PINTYPE_PULSE_IN,
|
||||
"on signal sent" = IC_PINTYPE_PULSE_OUT,
|
||||
"on signal received" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2)
|
||||
power_draw_idle = 5
|
||||
power_draw_per_use = 40
|
||||
|
||||
var/frequency = 1457
|
||||
var/code = 30
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/Initialize()
|
||||
..()
|
||||
spawn(40)
|
||||
set_frequency(frequency)
|
||||
// Set the pins so when someone sees them, they won't show as null
|
||||
set_pin_data(IC_INPUT, 1, frequency)
|
||||
set_pin_data(IC_INPUT, 2, code)
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/Destroy()
|
||||
SSradio.remove_object(src,frequency)
|
||||
|
||||
frequency = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/on_data_written()
|
||||
var/new_freq = get_pin_data(IC_INPUT, 1)
|
||||
var/new_code = get_pin_data(IC_INPUT, 2)
|
||||
if(isnum(new_freq) && new_freq > 0)
|
||||
set_frequency(new_freq)
|
||||
if(isnum(new_code))
|
||||
code = new_code
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/do_work() // Sends a signal.
|
||||
if(!radio_connection)
|
||||
return
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.source = src
|
||||
signal.encryption = code
|
||||
signal.data["message"] = "ACTIVATE"
|
||||
radio_connection.post_signal(src, signal)
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency)
|
||||
if(!frequency)
|
||||
return
|
||||
if(!SSradio)
|
||||
sleep(20)
|
||||
if(!SSradio)
|
||||
return
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_CHAT)
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal)
|
||||
var/new_code = get_pin_data(IC_INPUT, 2)
|
||||
var/code = 0
|
||||
|
||||
if(isnum(new_code))
|
||||
code = new_code
|
||||
if(!signal)
|
||||
return 0
|
||||
if(signal.encryption != code)
|
||||
return 0
|
||||
if(signal.source == src) // Don't trigger ourselves.
|
||||
return 0
|
||||
|
||||
activate_pin(3)
|
||||
|
||||
for(var/mob/O in hearers(1, get_turf(src)))
|
||||
audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 1)
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2
|
||||
name = "EPv2 circuit"
|
||||
desc = "Enables the sending and receiving of messages on the Exonet with the EPv2 protocol."
|
||||
extended_desc = "An EPv2 address is a string with the format of XXXX:XXXX:XXXX:XXXX. Data can be send or received using the \
|
||||
second pin on each side, with additonal data reserved for the third pin. When a message is received, the second activation pin \
|
||||
will pulse whatever's connected to it. Pulsing the first activation pin will send a message."
|
||||
icon_state = "signal"
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"target EPv2 address" = IC_PINTYPE_STRING,
|
||||
"data to send" = IC_PINTYPE_STRING,
|
||||
"secondary text" = IC_PINTYPE_STRING
|
||||
)
|
||||
outputs = list(
|
||||
"address received" = IC_PINTYPE_STRING,
|
||||
"data received" = IC_PINTYPE_STRING,
|
||||
"secondary text received" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2)
|
||||
power_draw_per_use = 50
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/New()
|
||||
..()
|
||||
exonet = new(src)
|
||||
exonet.make_address("EPv2_circuit-[REF(src)]")
|
||||
desc += "<br>This circuit's EPv2 address is: [exonet.address]"
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/Destroy()
|
||||
if(exonet)
|
||||
exonet.remove_address()
|
||||
qdel(exonet)
|
||||
exonet = null
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/do_work()
|
||||
var/target_address = get_pin_data(IC_INPUT, 1)
|
||||
var/message = get_pin_data(IC_INPUT, 2)
|
||||
var/text = get_pin_data(IC_INPUT, 3)
|
||||
|
||||
if(target_address && istext(target_address))
|
||||
exonet.send_message(target_address, message, text)
|
||||
|
||||
/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
|
||||
set_pin_data(IC_OUTPUT, 1, origin_address)
|
||||
set_pin_data(IC_OUTPUT, 2, message)
|
||||
set_pin_data(IC_OUTPUT, 3, text)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
//This circuit gives information on where the machine is.
|
||||
/obj/item/integrated_circuit/input/gps
|
||||
name = "global positioning system"
|
||||
desc = "This allows you to easily know the position of a machine containing this device."
|
||||
extended_desc = "The GPS's coordinates it gives is absolute, not relative."
|
||||
icon_state = "gps"
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("X"= IC_PINTYPE_NUMBER, "Y" = IC_PINTYPE_NUMBER, "Z" = IC_PINTYPE_NUMBER)
|
||||
activators = list("get coordinates" = IC_PINTYPE_PULSE_IN, "on get coordinates" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
|
||||
/obj/item/integrated_circuit/input/gps/do_work()
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
if(!T)
|
||||
return
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, T.x)
|
||||
set_pin_data(IC_OUTPUT, 2, T.y)
|
||||
set_pin_data(IC_OUTPUT, 3, T.z)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/microphone
|
||||
name = "microphone"
|
||||
desc = "Useful for spying on people or for voice activated machines."
|
||||
extended_desc = "This will automatically translate most languages it hears to Galactic Common. \
|
||||
The first activation pin is always pulsed when the circuit hears someone talk, while the second one \
|
||||
is only triggered if it hears someone speaking a language other than Galactic Common."
|
||||
icon_state = "recorder"
|
||||
complexity = 8
|
||||
inputs = list()
|
||||
flags_1 = CONDUCT_1 | HEAR_1
|
||||
outputs = list(
|
||||
"speaker" = IC_PINTYPE_STRING,
|
||||
"message" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list("on message received" = IC_PINTYPE_PULSE_OUT, "on translation" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 5
|
||||
|
||||
/obj/item/integrated_circuit/input/microphone/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
|
||||
var/translated = FALSE
|
||||
if(speaker && message)
|
||||
if(raw_message)
|
||||
if(message_langs != get_default_language())
|
||||
translated = TRUE
|
||||
set_pin_data(IC_OUTPUT, 1, speaker.GetVoice())
|
||||
set_pin_data(IC_OUTPUT, 2, raw_message)
|
||||
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
if(translated)
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor
|
||||
name = "sensor"
|
||||
desc = "Scans and obtains a reference for any objects or persons near you. All you need to do is shove the machine in their face."
|
||||
extended_desc = "If 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks."
|
||||
icon_state = "recorder"
|
||||
complexity = 12
|
||||
inputs = list("ignore storage" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list("scanned" = IC_PINTYPE_REF)
|
||||
activators = list("on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 120
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A)
|
||||
var/ignore_bags = get_pin_data(IC_INPUT, 1)
|
||||
if(ignore_bags)
|
||||
if(istype(A, /obj/item/storage))
|
||||
return FALSE
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/ranged
|
||||
name = "Ranged sensor"
|
||||
desc = "Scans and obtains a reference for any objects or persons in range. All you need to do is point the machine towards target."
|
||||
extended_desc = "If 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks."
|
||||
icon_state = "recorder"
|
||||
complexity = 36
|
||||
inputs = list("ignore storage" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list("scanned" = IC_PINTYPE_REF)
|
||||
activators = list("on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 120
|
||||
|
||||
/obj/item/integrated_circuit/input/internalbm
|
||||
name = "internal battery monitor"
|
||||
desc = "This monitors the charge level of an internal battery."
|
||||
icon_state = "internalbm"
|
||||
extended_desc = "This circuit will give you values of charge, max charge and percentage of the internal battery on demand."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 1
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"cell charge" = IC_PINTYPE_NUMBER,
|
||||
"max charge" = IC_PINTYPE_NUMBER,
|
||||
"percentage" = IC_PINTYPE_NUMBER,
|
||||
"refference to assembly" = IC_PINTYPE_REF
|
||||
)
|
||||
activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/internalbm/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
set_pin_data(IC_OUTPUT, 4, WEAKREF(assembly))
|
||||
if(assembly)
|
||||
if(assembly.battery)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, assembly.battery.charge)
|
||||
set_pin_data(IC_OUTPUT, 2, assembly.battery.maxcharge)
|
||||
set_pin_data(IC_OUTPUT, 3, 100*assembly.battery.charge/assembly.battery.maxcharge)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/externalbm
|
||||
name = "external battery monitor"
|
||||
desc = "This can help to watch battery state of any device in view"
|
||||
icon_state = "externalbm"
|
||||
extended_desc = "This circuit will give you values of charge, max charge and percentage of any device or battery in view"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 2
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"cell charge" = IC_PINTYPE_NUMBER,
|
||||
"max charge" = IC_PINTYPE_NUMBER,
|
||||
"percentage" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/externalbm/do_work()
|
||||
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
if(AM)
|
||||
var/obj/item/stock_parts/cell/cell = get_cell(AM)
|
||||
if(cell)
|
||||
var/turf/A = get_turf(src)
|
||||
if(AM in view(A))
|
||||
push_data()
|
||||
set_pin_data(IC_OUTPUT, 1, cell.charge)
|
||||
set_pin_data(IC_OUTPUT, 2, cell.maxcharge)
|
||||
set_pin_data(IC_OUTPUT, 3, cell.percent())
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -0,0 +1,200 @@
|
||||
//These circuits do things with lists, and use special list pins for stability.
|
||||
/obj/item/integrated_circuit/lists
|
||||
complexity = 1
|
||||
inputs = list(
|
||||
"input" = IC_PINTYPE_LIST
|
||||
)
|
||||
outputs = list("result" = IC_PINTYPE_STRING)
|
||||
activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Lists"
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/lists/pick
|
||||
name = "pick circuit"
|
||||
desc = "This circuit will randomly 'pick' an element from a list that is inputted."
|
||||
extended_desc = "Will output null if the list is empty. Input list is unmodified."
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/pick/do_work()
|
||||
var/result = null
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1) // List pins guarantee that there is a list inside, even if just an empty one.
|
||||
if(input_list.len)
|
||||
result = pick(input_list)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/lists/append
|
||||
name = "append circuit"
|
||||
desc = "This circuit will add an element to a list."
|
||||
extended_desc = "The new element will always be at the bottom of the list."
|
||||
inputs = list(
|
||||
"list to append" = IC_PINTYPE_LIST,
|
||||
"input" = IC_PINTYPE_ANY
|
||||
)
|
||||
outputs = list(
|
||||
"appended list" = IC_PINTYPE_LIST
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/append/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/list/output_list = list()
|
||||
var/new_entry = get_pin_data(IC_INPUT, 2)
|
||||
output_list = input_list.Copy()
|
||||
output_list.Add(new_entry)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, output_list)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/lists/search
|
||||
name = "search circuit"
|
||||
desc = "This circuit will give index of desired element in the list."
|
||||
extended_desc = "Search will start at 1 position and will return first matching position."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"item" = IC_PINTYPE_ANY
|
||||
)
|
||||
outputs = list(
|
||||
"index" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/search/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/item = get_pin_data(IC_INPUT, 2)
|
||||
set_pin_data(IC_OUTPUT, 1, input_list.Find(item))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/lists/at
|
||||
name = "at circuit"
|
||||
desc = "This circuit will pick an element from a list by index."
|
||||
extended_desc = "If there is no element with such index, result will be null."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"index" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list("item" = IC_PINTYPE_ANY)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/at/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
var/item = input_list[index]
|
||||
set_pin_data(IC_OUTPUT, 1, item)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/lists/delete
|
||||
name = "delete circuit"
|
||||
desc = "This circuit will delete the element from a list by index."
|
||||
extended_desc = "If there is no element with such index, result list will be unchanged."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"index" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list(
|
||||
"item" = IC_PINTYPE_LIST
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/delete/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/list/red_list = list()
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
for(var/j in 1 to input_list.len)
|
||||
var/I = input_list[j]
|
||||
if(j != index)
|
||||
red_list.Add(I)
|
||||
set_pin_data(IC_OUTPUT, 1, red_list)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/lists/write
|
||||
name = "write circuit"
|
||||
desc = "This circuit will write element in list with given index."
|
||||
extended_desc = "If there is no element with such index, it will give the same list, as before."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"index" = IC_PINTYPE_NUMBER,
|
||||
"item" = IC_PINTYPE_ANY
|
||||
)
|
||||
outputs = list(
|
||||
"redacted list" = IC_PINTYPE_LIST
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/write/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
var/item = get_pin_data(IC_INPUT, 3)
|
||||
if(!islist(item)) //crh proof
|
||||
input_list[index] = item
|
||||
set_pin_data(IC_OUTPUT, 1, input_list)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
obj/item/integrated_circuit/lists/len
|
||||
name = "len circuit"
|
||||
desc = "This circuit will give lenght of the list."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
)
|
||||
outputs = list(
|
||||
"item" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/len/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
set_pin_data(IC_OUTPUT, 1, input_list.len)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/lists/jointext
|
||||
name = "join text circuit"
|
||||
desc = "This circuit will add all elements of a list into one string, seperated by a character."
|
||||
extended_desc = "Default settings will encode the entire list into a string."
|
||||
inputs = list(
|
||||
"list to join" = IC_PINTYPE_LIST,//
|
||||
"delimiter" = IC_PINTYPE_CHAR,
|
||||
"start" = IC_PINTYPE_NUMBER,
|
||||
"end" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
inputs_default = list(
|
||||
"2" = ",",
|
||||
"3" = 1,
|
||||
"4" = 0
|
||||
)
|
||||
outputs = list(
|
||||
"joined text" = IC_PINTYPE_STRING
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/jointext/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/delimiter = get_pin_data(IC_INPUT, 2)
|
||||
var/start = get_pin_data(IC_INPUT, 3)
|
||||
var/end = get_pin_data(IC_INPUT, 4)
|
||||
|
||||
var/result = null
|
||||
|
||||
if(input_list.len && delimiter && !isnull(start) && !isnull(end))
|
||||
result = jointext(input_list, delimiter, start, end)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -0,0 +1,221 @@
|
||||
/obj/item/integrated_circuit/logic
|
||||
name = "logic gate"
|
||||
desc = "This tiny chip will decide for you!"
|
||||
extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE."
|
||||
complexity = 3
|
||||
outputs = list("result")
|
||||
activators = list("compare" = IC_PINTYPE_PULSE_IN)
|
||||
category_text = "Logic"
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/logic/do_work()
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary
|
||||
inputs = list("A","B")
|
||||
activators = list("compare" = IC_PINTYPE_PULSE_IN, "on true result" = IC_PINTYPE_PULSE_OUT, "on false result" = IC_PINTYPE_PULSE_OUT)
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = do_compare(A, B) ? TRUE : FALSE
|
||||
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/proc/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary
|
||||
inputs = list("A")
|
||||
activators = list("compare" = IC_PINTYPE_PULSE_IN, "on compare" = IC_PINTYPE_PULSE_OUT)
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = do_check(A) ? TRUE : FALSE
|
||||
..()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary/proc/do_check(var/datum/integrated_io/A)
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/equals
|
||||
name = "equal gate"
|
||||
desc = "This gate compares two values, and outputs the number one if both are the same."
|
||||
icon_state = "equal"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data == B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/jklatch
|
||||
name = "JK latch"
|
||||
desc = "This gate is synchronysed JK latch."
|
||||
icon_state = "jklatch"
|
||||
inputs = list("J","K")
|
||||
outputs = list("Q","!Q")
|
||||
activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/lstate=FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/jklatch/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
var/datum/integrated_io/Q = outputs[2]
|
||||
if(A.data)
|
||||
if(B.data)
|
||||
lstate=!lstate
|
||||
else
|
||||
lstate = TRUE
|
||||
else
|
||||
if(B.data)
|
||||
lstate=FALSE
|
||||
O.data = lstate ? TRUE : FALSE
|
||||
Q.data = !lstate ? TRUE : FALSE
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/rslatch
|
||||
name = "RS latch"
|
||||
desc = "This gate is synchronysed RS latch. If both R and S are true, state will not change."
|
||||
icon_state = "sr_nor"
|
||||
inputs = list("S","R")
|
||||
outputs = list("Q","!Q")
|
||||
activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/lstate=FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/rslatch/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
var/datum/integrated_io/Q = outputs[2]
|
||||
if(A.data)
|
||||
if(!B.data)
|
||||
lstate=TRUE
|
||||
else
|
||||
if(B.data)
|
||||
lstate=FALSE
|
||||
O.data = lstate ? TRUE : FALSE
|
||||
Q.data = !lstate ? TRUE : FALSE
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/gdlatch
|
||||
name = "gated D latch"
|
||||
desc = "This gate is synchronysed gated D latch."
|
||||
icon_state = "gated_d"
|
||||
inputs = list("D","E")
|
||||
outputs = list("Q","!Q")
|
||||
activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/lstate=FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/gdlatch/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
var/datum/integrated_io/Q = outputs[2]
|
||||
if(B.data)
|
||||
if(A.data)
|
||||
lstate=TRUE
|
||||
else
|
||||
lstate=FALSE
|
||||
|
||||
O.data = lstate ? TRUE : FALSE
|
||||
Q.data = !lstate ? TRUE : FALSE
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/not_equals
|
||||
name = "not equal gate"
|
||||
desc = "This gate compares two values, and outputs the number one if both are different."
|
||||
icon_state = "not_equal"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/not_equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data != B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/and
|
||||
name = "and gate"
|
||||
desc = "This gate will output 'one' if both inputs evaluate to true."
|
||||
icon_state = "and"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/and/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data && B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/or
|
||||
name = "or gate"
|
||||
desc = "This gate will output 'one' if one of the inputs evaluate to true."
|
||||
icon_state = "or"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/or/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data || B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/less_than
|
||||
name = "less than gate"
|
||||
desc = "This will output 'one' if the first input is less than the second input."
|
||||
icon_state = "less_than"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/less_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data < B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/less_than_or_equal
|
||||
name = "less than or equal gate"
|
||||
desc = "This will output 'one' if the first input is less than, or equal to the second input."
|
||||
icon_state = "less_than_or_equal"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/less_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data <= B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/greater_than
|
||||
name = "greater than gate"
|
||||
desc = "This will output 'one' if the first input is greater than the second input."
|
||||
icon_state = "greater_than"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/greater_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data > B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/greater_than_or_equal
|
||||
name = "greater_than or equal gate"
|
||||
desc = "This will output 'one' if the first input is greater than, or equal to the second input."
|
||||
icon_state = "greater_than_or_equal"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/greater_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data >= B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary/not
|
||||
name = "not gate"
|
||||
desc = "This gate inverts what's fed into it."
|
||||
icon_state = "not"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
activators = list("invert" = IC_PINTYPE_PULSE_IN, "on inverted" = IC_PINTYPE_PULSE_OUT)
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary/not/do_check(var/datum/integrated_io/A)
|
||||
return !A.data
|
||||
@@ -0,0 +1,443 @@
|
||||
/obj/item/integrated_circuit/manipulation
|
||||
category_text = "Manipulation"
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing
|
||||
name = "weapon firing mechanism"
|
||||
desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it."
|
||||
extended_desc = "The firing mechanism can slot in any energy weapon. \
|
||||
The first and second inputs need to be numbers. They are coordinates for the gun to fire at, relative to the machine itself. \
|
||||
The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Mode is switch between\
|
||||
letal(TRUE) or stun(FALSE) modes.It uses internal battery of weapon."
|
||||
complexity = 20
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
size = 3
|
||||
inputs = list(
|
||||
"target X rel" = IC_PINTYPE_NUMBER,
|
||||
"target Y rel" = IC_PINTYPE_NUMBER,
|
||||
"mode" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
outputs = list("reference to gun" = IC_PINTYPE_REF)
|
||||
activators = list(
|
||||
"fire" = IC_PINTYPE_PULSE_IN
|
||||
|
||||
)
|
||||
var/obj/item/gun/energy/installed_gun = null
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4)
|
||||
power_draw_per_use = 0
|
||||
var/mode = FALSE
|
||||
|
||||
var/stun_projectile = null //stun mode projectile type
|
||||
var/stun_projectile_sound
|
||||
var/lethal_projectile = null //lethal mode projectile type
|
||||
var/lethal_projectile_sound
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/Destroy()
|
||||
qdel(installed_gun)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/attackby(var/obj/O, var/mob/user)
|
||||
if(istype(O, /obj/item/gun/energy))
|
||||
var/obj/item/gun/gun = O
|
||||
if(installed_gun)
|
||||
to_chat(user, "<span class='warning'>There's already a weapon installed.</span>")
|
||||
return
|
||||
|
||||
user.transferItemToLoc(gun,src)
|
||||
installed_gun = gun
|
||||
var/list/gun_properties = gun.get_turret_properties()
|
||||
to_chat(user, "<span class='notice'>You slide \the [gun] into the firing mechanism.</span>")
|
||||
playsound(src, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
stun_projectile = gun_properties["stun_projectile"]
|
||||
stun_projectile_sound = gun_properties["stun_projectile_sound"]
|
||||
lethal_projectile = gun_properties["lethal_projectile"]
|
||||
lethal_projectile_sound = gun_properties["lethal_projectile_sound"]
|
||||
if(gun_properties["shot_delay"])
|
||||
cooldown_per_use = gun_properties["shot_delay"]*10
|
||||
if(cooldown_per_use<30)
|
||||
cooldown_per_use = 40
|
||||
if(gun_properties["reqpower"])
|
||||
power_draw_per_use = gun_properties["reqpower"]
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun))
|
||||
push_data()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/attack_self(var/mob/user)
|
||||
if(installed_gun)
|
||||
installed_gun.forceMove(drop_location())
|
||||
to_chat(user, "<span class='notice'>You slide \the [installed_gun] out of the firing mechanism.</span>")
|
||||
size = initial(size)
|
||||
playsound(src, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
installed_gun = null
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(null))
|
||||
push_data()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There's no weapon to remove from the mechanism.</span>")
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/do_work()
|
||||
if(!installed_gun)
|
||||
return
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun))
|
||||
push_data()
|
||||
var/datum/integrated_io/xo = inputs[1]
|
||||
var/datum/integrated_io/yo = inputs[2]
|
||||
var/datum/integrated_io/mode1 = inputs[3]
|
||||
|
||||
mode = mode1.data
|
||||
if(assembly)
|
||||
if(isnum(xo.data))
|
||||
xo.data = round(xo.data, 1)
|
||||
if(isnum(yo.data))
|
||||
yo.data = round(yo.data, 1)
|
||||
|
||||
var/turf/T = get_turf(assembly)
|
||||
var/target_x = Clamp(T.x + xo.data, 0, world.maxx)
|
||||
var/target_y = Clamp(T.y + yo.data, 0, world.maxy)
|
||||
|
||||
shootAt(locate(target_x, target_y, T.z))
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/proc/shootAt(turf/target)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/U = target
|
||||
if(!istype(T) || !istype(U))
|
||||
return
|
||||
if(!installed_gun.cell)
|
||||
return
|
||||
if(!installed_gun.cell.charge)
|
||||
return
|
||||
var/obj/item/ammo_casing/energy/shot = installed_gun.ammo_type[mode?2:1]
|
||||
if(installed_gun.cell.charge < shot.e_cost)
|
||||
return
|
||||
if(!shot)
|
||||
return
|
||||
update_icon()
|
||||
var/obj/item/projectile/A
|
||||
if(!mode)
|
||||
A = new stun_projectile(T)
|
||||
playsound(loc, stun_projectile_sound, 75, 1)
|
||||
else
|
||||
A = new lethal_projectile(T)
|
||||
playsound(loc, lethal_projectile_sound, 75, 1)
|
||||
|
||||
|
||||
installed_gun.cell.use(shot.e_cost)
|
||||
//Shooting Code:
|
||||
A.preparePixelProjectile(target, src)
|
||||
A.fire()
|
||||
return A
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/locomotion
|
||||
name = "locomotion circuit"
|
||||
desc = "This allows a machine to move in a given direction."
|
||||
icon_state = "locomotion"
|
||||
extended_desc = "The circuit accepts a 'dir' number as a direction to move towards.<br>\
|
||||
Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \
|
||||
being held, or anchored in some way. It should be noted that the ability to move is dependant on the type of assembly that this circuit inhabits."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
complexity = 20
|
||||
// size = 5
|
||||
inputs = list("direction" = IC_PINTYPE_DIR)
|
||||
outputs = list()
|
||||
activators = list("step towards dir" = IC_PINTYPE_PULSE_IN,"on step"=IC_PINTYPE_PULSE_OUT,"blocked"=IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 100
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/locomotion/do_work()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && assembly)
|
||||
if(assembly.anchored || !assembly.can_move())
|
||||
return
|
||||
if(assembly.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held.
|
||||
var/datum/integrated_io/wanted_dir = inputs[1]
|
||||
if(isnum(wanted_dir.data))
|
||||
if(step(assembly, wanted_dir.data))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade
|
||||
name = "grenade primer"
|
||||
desc = "This circuit comes with the ability to attach most types of grenades at prime them at will."
|
||||
extended_desc = "Time between priming and detonation is limited to between 1 to 12 seconds but is optional. \
|
||||
If unset, not a number, or a number less than 1 then the grenade's built-in timing will be used. \
|
||||
Beware: Once primed there is no aborting the process!"
|
||||
icon_state = "grenade"
|
||||
complexity = 30
|
||||
inputs = list("detonation time" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("prime grenade" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4)
|
||||
var/obj/item/grenade/attached_grenade
|
||||
var/pre_attached_grenade_type
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/Initialize()
|
||||
. = ..()
|
||||
if(pre_attached_grenade_type)
|
||||
var/grenade = new pre_attached_grenade_type(src)
|
||||
attach_grenade(grenade)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/Destroy()
|
||||
if(attached_grenade && !attached_grenade.active)
|
||||
attached_grenade.forceMove(loc)
|
||||
detach_grenade()
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/attackby(var/obj/item/grenade/G, var/mob/user)
|
||||
if(istype(G))
|
||||
if(attached_grenade)
|
||||
to_chat(user, "<span class='warning'>There is already a grenade attached!</span>")
|
||||
else if(user.transferItemToLoc(G,src))
|
||||
user.visible_message("<span class='warning'>\The [user] attaches \a [G] to \the [src]!</span>", "<span class='notice'>You attach \the [G] to \the [src].</span>")
|
||||
attach_grenade(G)
|
||||
G.forceMove(src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/attack_self(var/mob/user)
|
||||
if(attached_grenade)
|
||||
user.visible_message("<span class='warning'>\The [user] removes \an [attached_grenade] from \the [src]!</span>", "<span class='notice'>You remove \the [attached_grenade] from \the [src].</span>")
|
||||
user.put_in_hands(attached_grenade)
|
||||
detach_grenade()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/do_work()
|
||||
if(attached_grenade && !attached_grenade.active)
|
||||
var/datum/integrated_io/detonation_time = inputs[1]
|
||||
var/dt
|
||||
if(isnum(detonation_time.data) && detonation_time.data > 0)
|
||||
dt = Clamp(detonation_time.data, 1, 12)*10
|
||||
else
|
||||
dt = 15
|
||||
addtimer(CALLBACK(attached_grenade, /obj/item/grenade.proc/prime), dt)
|
||||
var/atom/holder = loc
|
||||
message_admins("activated a grenade assembly. Last touches: Assembly: [holder.fingerprintslast] Circuit: [fingerprintslast] Grenade: [attached_grenade.fingerprintslast]")
|
||||
|
||||
// These procs do not relocate the grenade, that's the callers responsibility
|
||||
/obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/grenade/G)
|
||||
attached_grenade = G
|
||||
G.forceMove(src)
|
||||
desc += " \An [attached_grenade] is attached to it!"
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade()
|
||||
if(!attached_grenade)
|
||||
return
|
||||
attached_grenade.forceMove(drop_location())
|
||||
attached_grenade = null
|
||||
desc = initial(desc)
|
||||
/*
|
||||
/obj/item/integrated_circuit/manipulation/grenade/frag
|
||||
pre_attached_grenade_type = /obj/item/weapon/grenade/explosive
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 10)
|
||||
spawn_flags = null // Used for world initializing, see the #defines above.
|
||||
*/
|
||||
/obj/item/integrated_circuit/manipulation/shocker
|
||||
name = "shocker circuit"
|
||||
desc = "Used to shock adjacent creatures with electricity."
|
||||
icon_state = "shocker"
|
||||
extended_desc = "The circuit accepts a reference to creature,who needs to be shocked. It can shock target on adjacent tiles. \
|
||||
Severity determines hardness of shock and it's power consumption. It's given between 0 and 60."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 10
|
||||
inputs = list("target" = IC_PINTYPE_REF,"severity" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("shock" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 0
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/shocker/on_data_written()
|
||||
var/s = get_pin_data(IC_INPUT, 2)
|
||||
power_draw_per_use = Clamp(s,0,60)*1200/60
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/shocker/do_work()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /mob/living)
|
||||
if(!istype(AM,/mob/living)) //Invalid input
|
||||
return
|
||||
var/mob/living/M = AM
|
||||
if(!M.Adjacent(T))
|
||||
return //Can't reach
|
||||
to_chat(M, "<span class='danger'>You feel a sharp shock!</span>")
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(12, 1, src)
|
||||
s.start()
|
||||
var/stf=Clamp(get_pin_data(IC_INPUT, 2),0,60)
|
||||
M.Knockdown(stf)
|
||||
M.apply_effect(STUTTER, stf)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/plant_module
|
||||
name = "plant manipulation module"
|
||||
desc = "Used to uproot weeds or harvest plants in trays."
|
||||
icon_state = "plant_m"
|
||||
extended_desc = "The circuit accepts a reference to hydroponic tray. It work from adjacent tiles. \
|
||||
Mode(0- harvest, 1-uproot weeds, 2-uproot plant) determinies action."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 10
|
||||
inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out"=IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 50
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/plant_module/do_work()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/machinery/hydroponics/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
|
||||
if(!istype(AM)) //Invalid input
|
||||
return
|
||||
var/mob/living/M = get_turf(AM)
|
||||
if(!M.Adjacent(T))
|
||||
return //Can't reach
|
||||
switch(get_pin_data(IC_INPUT, 2))
|
||||
if(0)
|
||||
if(AM.myseed)
|
||||
if(AM.harvest)
|
||||
AM.myseed.harvest()
|
||||
AM.harvest = 0
|
||||
AM.lastproduce = AM.age
|
||||
if(!AM.myseed.get_gene(/datum/plant_gene/trait/repeated_harvest))
|
||||
qdel(AM.myseed)
|
||||
AM.myseed = null
|
||||
AM.dead = 0
|
||||
AM.update_icon()
|
||||
if(1)
|
||||
AM.weedlevel = 0
|
||||
if(2)
|
||||
if(AM.myseed) //Could be that they're just using it as a de-weeder
|
||||
AM.age = 0
|
||||
AM.plant_health = 0
|
||||
if(AM.harvest)
|
||||
AM.harvest = FALSE //To make sure they can't just put in another seed and insta-harvest it
|
||||
qdel(AM.myseed)
|
||||
AM.myseed = null
|
||||
AM.weedlevel = 0 //Has a side effect of cleaning up those nasty weeds
|
||||
AM.update_icon()
|
||||
else
|
||||
activate_pin(2)
|
||||
return FALSE
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber
|
||||
name = "grabber"
|
||||
desc = "A circuit with it's own inventory for small/medium items, used to grab and store things."
|
||||
icon_state = "grabber"
|
||||
extended_desc = "The circuit accepts a reference to thing to be grabbed. It can store up to 10 things. Modes: 1 for grab. 0 for eject the first thing. -1 for eject all."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
size = 3
|
||||
|
||||
complexity = 10
|
||||
inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("first" = IC_PINTYPE_REF, "last" = IC_PINTYPE_REF, "amount" = IC_PINTYPE_NUMBER,"contents" = IC_PINTYPE_LIST)
|
||||
activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 50
|
||||
var/max_w_class = WEIGHT_CLASS_NORMAL
|
||||
var/max_items = 10
|
||||
/*
|
||||
/obj/item/integrated_circuit/manipulation/thrower/New()
|
||||
processing_objects |= src
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower/Destroy()
|
||||
processing_objects -= src
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower/process()
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(contents[1]))
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(contents[contents.len]))
|
||||
set_pin_data(IC_OUTPUT, 3, contents.len)
|
||||
push_data()
|
||||
*/
|
||||
/obj/item/integrated_circuit/manipulation/grabber/do_work()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
|
||||
if(AM)
|
||||
var/turf/P = get_turf(AM)
|
||||
var/mode = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(mode == 1)
|
||||
if(P.Adjacent(T))
|
||||
if((contents.len < max_items) && AM && (AM.w_class <= max_w_class))
|
||||
AM.forceMove(src)
|
||||
if(mode == 0)
|
||||
if(contents.len)
|
||||
var/obj/item/U = contents[1]
|
||||
U.forceMove(T)
|
||||
if(mode == -1)
|
||||
if(contents.len)
|
||||
var/obj/item/U
|
||||
for(U in contents)
|
||||
U.forceMove(T)
|
||||
if(contents.len)
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(contents[1]))
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(contents[contents.len]))
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, contents.len)
|
||||
set_pin_data(IC_OUTPUT, 4, contents)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber/attack_self(var/mob/user)
|
||||
if(contents.len)
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/U
|
||||
for(U in contents)
|
||||
U.forceMove(T)
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, contents.len)
|
||||
push_data()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower
|
||||
name = "thrower"
|
||||
desc = "A compact launcher to throw things from inside or nearby tiles"
|
||||
extended_desc = "The first and second inputs need to be numbers. They are coordinates to throw thing at, relative to the machine itself. \
|
||||
The 'fire' activator will cause the mechanism to attempt to throw thing at the coordinates, if possible. Note that the \
|
||||
projectile need to be inside the machine, or to be on an adjacent tile, and to be up to medium size."
|
||||
complexity = 15
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
size = 2
|
||||
inputs = list(
|
||||
"target X rel" = IC_PINTYPE_NUMBER,
|
||||
"target Y rel" = IC_PINTYPE_NUMBER,
|
||||
"projectile" = IC_PINTYPE_REF
|
||||
)
|
||||
outputs = list()
|
||||
activators = list(
|
||||
"fire" = IC_PINTYPE_PULSE_IN
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4)
|
||||
power_draw_per_use = 50
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower/do_work()
|
||||
var/datum/integrated_io/target_x = inputs[1]
|
||||
var/datum/integrated_io/target_y = inputs[2]
|
||||
var/datum/integrated_io/projectile = inputs[3]
|
||||
if(!isweakref(projectile.data))
|
||||
return
|
||||
var/obj/item/A = projectile.data.resolve()
|
||||
if(A.anchored || (A.w_class > WEIGHT_CLASS_NORMAL))
|
||||
return
|
||||
var/turf/T = get_turf(assembly)
|
||||
if(!(A.Adjacent(T) || (A in assembly.GetAllContents())))
|
||||
return
|
||||
if(assembly)
|
||||
if(isnum(target_x.data))
|
||||
target_x.data = round(target_x.data, 1)
|
||||
if(isnum(target_y.data))
|
||||
target_y.data = round(target_y.data, 1)
|
||||
var/_x = Clamp(T.x + target_x.data, 0, world.maxx)
|
||||
var/_y = Clamp(T.y + target_y.data, 0, world.maxy)
|
||||
|
||||
A.forceMove(drop_location())
|
||||
A.throw_at(locate(_x, _y, T.z), round(Clamp(sqrt(target_x.data*target_x.data+target_y.data*target_y.data),0,8),1), 3)
|
||||
@@ -0,0 +1,124 @@
|
||||
/obj/item/integrated_circuit/memory
|
||||
name = "memory chip"
|
||||
desc = "This tiny chip can store one piece of data."
|
||||
icon_state = "memory"
|
||||
complexity = 1
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
activators = list("set" = IC_PINTYPE_PULSE_IN, "on set" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Memory"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 1
|
||||
var/number_of_pins = 1
|
||||
|
||||
/obj/item/integrated_circuit/memory/New()
|
||||
for(var/i = 1 to number_of_pins)
|
||||
inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called.
|
||||
outputs["output [i]"] = IC_PINTYPE_ANY
|
||||
complexity = number_of_pins
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/memory/examine(mob/user)
|
||||
..()
|
||||
var/i
|
||||
for(i = 1, i <= outputs.len, i++)
|
||||
var/datum/integrated_io/O = outputs[i]
|
||||
var/data = "nothing"
|
||||
if(isweakref(O.data))
|
||||
var/datum/d = O.data_as_type(/datum)
|
||||
if(d)
|
||||
data = "[d]"
|
||||
else if(!isnull(O.data))
|
||||
data = O.data
|
||||
to_chat(user, "\The [src] has [data] saved to address [i].")
|
||||
|
||||
/obj/item/integrated_circuit/memory/do_work()
|
||||
for(var/i = 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[i]
|
||||
var/datum/integrated_io/O = outputs[i]
|
||||
O.data = I.data
|
||||
O.push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/memory/tiny
|
||||
name = "small memory circuit"
|
||||
desc = "This circuit can store two pieces of data."
|
||||
icon_state = "memory4"
|
||||
power_draw_per_use = 2
|
||||
number_of_pins = 2
|
||||
|
||||
/obj/item/integrated_circuit/memory/medium
|
||||
name = "medium memory circuit"
|
||||
desc = "This circuit can store four pieces of data."
|
||||
icon_state = "memory4"
|
||||
power_draw_per_use = 2
|
||||
number_of_pins = 4
|
||||
|
||||
/obj/item/integrated_circuit/memory/large
|
||||
name = "large memory circuit"
|
||||
desc = "This big circuit can hold eight pieces of data."
|
||||
icon_state = "memory8"
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3)
|
||||
power_draw_per_use = 4
|
||||
number_of_pins = 8
|
||||
|
||||
/obj/item/integrated_circuit/memory/huge
|
||||
name = "large memory stick"
|
||||
desc = "This stick of memory can hold up up to sixteen pieces of data."
|
||||
icon_state = "memory16"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4)
|
||||
power_draw_per_use = 8
|
||||
number_of_pins = 16
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant
|
||||
name = "constant chip"
|
||||
desc = "This tiny chip can store one piece of data, which cannot be overwritten without disassembly."
|
||||
icon_state = "memory"
|
||||
inputs = list()
|
||||
outputs = list("output pin" = IC_PINTYPE_ANY)
|
||||
activators = list("push data" = IC_PINTYPE_PULSE_IN)
|
||||
var/accepting_refs = FALSE
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant/do_work()
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant/attack_self(mob/user)
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null")
|
||||
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
accepting_refs = FALSE
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
if(istext(new_data) && user.IsAdvancedToolUser())
|
||||
O.data = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to [O.display_data(O.data)].</span>")
|
||||
if("number")
|
||||
accepting_refs = FALSE
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && user.IsAdvancedToolUser())
|
||||
O.data = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to [O.display_data(O.data)].</span>")
|
||||
if("ref")
|
||||
accepting_refs = TRUE
|
||||
to_chat(user, "<span class='notice'>You turn \the [src]'s ref scanner on. Slide it across \
|
||||
an object for a ref of that object to save it in memory.</span>")
|
||||
if("null")
|
||||
O.data = null
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to absolutely nothing.</span>")
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant/afterattack(atom/target, mob/living/user, proximity)
|
||||
if(accepting_refs && proximity)
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = WEAKREF(target)
|
||||
visible_message("<span class='notice'>[user] slides \a [src]'s over \the [target].</span>")
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to a reference to [O.display_data(O.data)]. The ref scanner is \
|
||||
now off.</span>")
|
||||
accepting_refs = FALSE
|
||||
@@ -0,0 +1,359 @@
|
||||
/obj/item/integrated_circuit/output
|
||||
category_text = "Output"
|
||||
|
||||
/obj/item/integrated_circuit/output/screen
|
||||
name = "small screen"
|
||||
desc = "This small screen can display a single piece of data, when the machine is examined closely."
|
||||
icon_state = "screen"
|
||||
inputs = list("displayed data" = IC_PINTYPE_ANY)
|
||||
outputs = list()
|
||||
activators = list("load data" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 10
|
||||
var/stuff_to_display = null
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/disconnect_all()
|
||||
..()
|
||||
stuff_to_display = null
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/any_examine(mob/user)
|
||||
to_chat(user, "There is a little screen labeled '[name]', which displays [!isnull(stuff_to_display) ? "'[stuff_to_display]'" : "nothing"].")
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
if(isweakref(I.data))
|
||||
var/datum/d = I.data_as_type(/datum)
|
||||
if(d)
|
||||
stuff_to_display = "[d]"
|
||||
else
|
||||
stuff_to_display = I.data
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/medium
|
||||
name = "screen"
|
||||
desc = "This screen allows for people holding the device to see a piece of data."
|
||||
icon_state = "screen_medium"
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/medium/do_work()
|
||||
..()
|
||||
var/list/nearby_things = range(0, get_turf(src))
|
||||
for(var/mob/M in nearby_things)
|
||||
var/obj/O = assembly ? assembly : src
|
||||
to_chat(M, "<span class='notice'>[icon2html(O.icon, world, O.icon_state)] [stuff_to_display]</span>")
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/large
|
||||
name = "large screen"
|
||||
desc = "This screen allows for people able to see the device to see a piece of data."
|
||||
icon_state = "screen_large"
|
||||
power_draw_per_use = 40
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/large/do_work()
|
||||
..()
|
||||
var/obj/O = assembly ? loc : assembly
|
||||
O.visible_message("<span class='notice'>[icon2html(O.icon, world, O.icon_state)] [stuff_to_display]</span>")
|
||||
|
||||
/obj/item/integrated_circuit/output/light
|
||||
name = "light"
|
||||
desc = "This light can turn on and off on command."
|
||||
icon_state = "light"
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
activators = list("toggle light" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/light_toggled = 0
|
||||
var/light_brightness = 3
|
||||
var/light_rgb = "#FFFFFF"
|
||||
power_draw_idle = 0 // Adjusted based on brightness.
|
||||
|
||||
/obj/item/integrated_circuit/output/light/do_work()
|
||||
light_toggled = !light_toggled
|
||||
update_lighting()
|
||||
|
||||
/obj/item/integrated_circuit/output/light/proc/update_lighting()
|
||||
if(light_toggled)
|
||||
if(assembly)
|
||||
assembly.set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb)
|
||||
else
|
||||
if(assembly)
|
||||
assembly.set_light(0)
|
||||
power_draw_idle = light_toggled ? light_brightness * 2 : 0
|
||||
|
||||
/obj/item/integrated_circuit/output/light/advanced/update_lighting()
|
||||
var/new_color = get_pin_data(IC_INPUT, 1)
|
||||
var/brightness = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(new_color && isnum(brightness))
|
||||
brightness = Clamp(brightness, 0, 6)
|
||||
light_rgb = new_color
|
||||
light_brightness = brightness
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/output/light/power_fail() // Turns off the flashlight if there's no power left.
|
||||
light_toggled = FALSE
|
||||
update_lighting()
|
||||
|
||||
/obj/item/integrated_circuit/output/light/advanced
|
||||
name = "advanced light"
|
||||
desc = "This light can turn on and off on command, in any color, and in various brightness levels."
|
||||
icon_state = "light_adv"
|
||||
complexity = 8
|
||||
inputs = list(
|
||||
"color" = IC_PINTYPE_COLOR,
|
||||
"brightness" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3)
|
||||
|
||||
/obj/item/integrated_circuit/output/light/advanced/on_data_written()
|
||||
update_lighting()
|
||||
|
||||
/obj/item/integrated_circuit/output/sound
|
||||
name = "speaker circuit"
|
||||
desc = "A miniature speaker is attached to this component."
|
||||
icon_state = "speaker"
|
||||
complexity = 8
|
||||
cooldown_per_use = 4 SECONDS
|
||||
inputs = list(
|
||||
"sound ID" = IC_PINTYPE_STRING,
|
||||
"volume" = IC_PINTYPE_NUMBER,
|
||||
"frequency" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
outputs = list()
|
||||
activators = list("play sound" = IC_PINTYPE_PULSE_IN)
|
||||
power_draw_per_use = 10
|
||||
var/list/sounds = list()
|
||||
|
||||
/obj/item/integrated_circuit/output/text_to_speech
|
||||
name = "text-to-speech circuit"
|
||||
desc = "A miniature speaker is attached to this component."
|
||||
extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech."
|
||||
icon_state = "speaker"
|
||||
complexity = 12
|
||||
inputs = list("text" = IC_PINTYPE_STRING)
|
||||
outputs = list()
|
||||
activators = list("to speech" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 60
|
||||
|
||||
/obj/item/integrated_circuit/output/text_to_speech/do_work()
|
||||
text = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(text))
|
||||
var/obj/O = assembly ? loc : assembly
|
||||
O.say(strip_html_simple(text))
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/Initialize()
|
||||
.= ..()
|
||||
extended_desc = list()
|
||||
extended_desc += "The first input pin determines which sound is used. The choices are; "
|
||||
extended_desc += jointext(sounds, ", ")
|
||||
extended_desc += ". The second pin determines the volume of sound that is played"
|
||||
extended_desc += ", and the third determines if the frequency of the sound will vary with each activation."
|
||||
extended_desc = jointext(extended_desc, null)
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/do_work()
|
||||
var/ID = get_pin_data(IC_INPUT, 1)
|
||||
var/vol = get_pin_data(IC_INPUT, 2)
|
||||
var/freq = get_pin_data(IC_INPUT, 3)
|
||||
if(!isnull(ID) && !isnull(vol))
|
||||
var/selected_sound = sounds[ID]
|
||||
if(!selected_sound)
|
||||
return
|
||||
vol = Clamp(vol ,0 , 100)
|
||||
playsound(get_turf(src), selected_sound, vol, freq, -1)
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/on_data_written()
|
||||
power_draw_per_use = get_pin_data(IC_INPUT, 2) * 15
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/beeper
|
||||
name = "beeper circuit"
|
||||
desc = "A miniature speaker is attached to this component. This is often used in the construction of motherboards, which use \
|
||||
the speaker to tell the user if something goes very wrong when booting up. It can also do other similar synthetic sounds such \
|
||||
as buzzing, pinging, chiming, and more."
|
||||
sounds = list(
|
||||
"beep" = 'sound/machines/twobeep.ogg',
|
||||
"chime" = 'sound/machines/chime.ogg',
|
||||
"buzz sigh" = 'sound/machines/buzz-sigh.ogg',
|
||||
"buzz twice" = 'sound/machines/buzz-two.ogg',
|
||||
"ping" = 'sound/machines/ping.ogg',
|
||||
"synth yes" = 'sound/machines/synth_yes.ogg',
|
||||
"synth no" = 'sound/machines/synth_no.ogg',
|
||||
"warning buzz" = 'sound/machines/warning-buzzer.ogg'
|
||||
)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/beepsky
|
||||
name = "securitron sound circuit"
|
||||
desc = "A miniature speaker is attached to this component. Considered by some to be the essential component for a securitron."
|
||||
sounds = list(
|
||||
"creep" = 'sound/voice/bcreep.ogg',
|
||||
"criminal" = 'sound/voice/bcriminal.ogg',
|
||||
"freeze" = 'sound/voice/bfreeze.ogg',
|
||||
"god" = 'sound/voice/bgod.ogg',
|
||||
"i am the law" = 'sound/voice/biamthelaw.ogg',
|
||||
"insult" = 'sound/voice/binsult.ogg',
|
||||
"radio" = 'sound/voice/bradio.ogg',
|
||||
"secure day" = 'sound/voice/bsecureday.ogg',
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1)
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/medbot
|
||||
name = "medbot sound circuit"
|
||||
desc = "A miniature speaker is attached to this component, used to annoy patients while they get pricked by a medbot."
|
||||
sounds = list(
|
||||
"surgeon" = 'sound/voice/msurgeon.ogg',
|
||||
"radar" = 'sound/voice/mradar.ogg',
|
||||
"feel better" = 'sound/voice/mfeelbetter.ogg',
|
||||
"patched up" = 'sound/voice/mpatchedup.ogg',
|
||||
"injured" = 'sound/voice/minjured.ogg',
|
||||
"insult" = 'sound/voice/minsult.ogg',
|
||||
"coming" = 'sound/voice/mcoming.ogg',
|
||||
"help" = 'sound/voice/mhelp.ogg',
|
||||
"live" = 'sound/voice/mlive.ogg',
|
||||
"lost" = 'sound/voice/mlost.ogg',
|
||||
"flies" = 'sound/voice/mflies.ogg',
|
||||
"catch" = 'sound/voice/mcatch.ogg',
|
||||
"delicious" = 'sound/voice/mdelicious.ogg',
|
||||
"apple" = 'sound/voice/mapple.ogg',
|
||||
"no" = 'sound/voice/mno.ogg',
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 1)
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera
|
||||
name = "video camera circuit"
|
||||
desc = "This small camera allows a remote viewer to see what it sees."
|
||||
extended_desc = "The camera is linked to the Research camera network."
|
||||
icon_state = "video_camera"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
complexity = 10
|
||||
inputs = list(
|
||||
"camera name" = IC_PINTYPE_STRING,
|
||||
"camera active" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
inputs_default = list("1" = "video camera circuit")
|
||||
outputs = list()
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_idle = 0 // Raises to 20 when on.
|
||||
var/obj/machinery/camera/camera
|
||||
var/updating = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/New()
|
||||
..()
|
||||
camera = new(src)
|
||||
camera.network = list("RD")
|
||||
on_data_written()
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/Destroy()
|
||||
QDEL_NULL(camera)
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/proc/set_camera_status(var/status)
|
||||
if(camera)
|
||||
camera.status = status
|
||||
GLOB.cameranet.updatePortableCamera(camera)
|
||||
power_draw_idle = camera.status ? 20 : 0
|
||||
if(camera.status) // Ensure that there's actually power.
|
||||
if(!draw_idle_power())
|
||||
power_fail()
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/on_data_written()
|
||||
if(camera)
|
||||
var/cam_name = get_pin_data(IC_INPUT, 1)
|
||||
var/cam_active = get_pin_data(IC_INPUT, 2)
|
||||
if(!isnull(cam_name))
|
||||
camera.c_tag = cam_name
|
||||
set_camera_status(cam_active)
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/power_fail()
|
||||
if(camera)
|
||||
set_camera_status(0)
|
||||
set_pin_data(IC_INPUT, 2, FALSE)
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/ext_moved(oldLoc, dir)
|
||||
. = ..()
|
||||
update_camera_location(oldLoc)
|
||||
|
||||
#define VIDEO_CAMERA_BUFFER 10
|
||||
/obj/item/integrated_circuit/output/video_camera/proc/update_camera_location(oldLoc)
|
||||
oldLoc = get_turf(oldLoc)
|
||||
if(!QDELETED(camera) && !updating && oldLoc != get_turf(src))
|
||||
updating = TRUE
|
||||
addtimer(CALLBACK(src, .proc/do_camera_update, oldLoc), VIDEO_CAMERA_BUFFER)
|
||||
#undef VIDEO_CAMERA_BUFFER
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/proc/do_camera_update(oldLoc)
|
||||
if(!QDELETED(camera) && oldLoc != get_turf(src))
|
||||
GLOB.cameranet.updatePortableCamera(camera)
|
||||
updating = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/output/led
|
||||
name = "light-emitting diode"
|
||||
desc = "This a LED that is lit whenever there is TRUE-equivalent data on its input."
|
||||
extended_desc = "TRUE-equivalent values are: Non-empty strings, non-zero numbers, and valid refs."
|
||||
complexity = 0.1
|
||||
icon_state = "led"
|
||||
inputs = list("lit" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list()
|
||||
activators = list()
|
||||
power_draw_idle = 0 // Raises to 1 when lit.
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/led_color
|
||||
|
||||
/obj/item/integrated_circuit/output/led/on_data_written()
|
||||
power_draw_idle = get_pin_data(IC_INPUT, 1) ? 1 : 0
|
||||
|
||||
/obj/item/integrated_circuit/output/led/power_fail()
|
||||
set_pin_data(IC_INPUT, 1, FALSE)
|
||||
|
||||
/obj/item/integrated_circuit/output/led/external_examine(mob/user)
|
||||
var/text_output = list()
|
||||
|
||||
// Doing all this work just to have a color-blind friendly output.
|
||||
text_output += "There is "
|
||||
if(name == displayed_name )
|
||||
text_output += "\an [name]"
|
||||
else
|
||||
text_output += "\an ["\improper[name]"] labeled '[displayed_name ]'"
|
||||
text_output += " which is currently [(get_pin_data(IC_INPUT, 1)==1) ? "lit <font color=[led_color]>*</font>" : "unlit."]"
|
||||
to_chat(user,jointext(text_output,null))
|
||||
|
||||
/obj/item/integrated_circuit/output/led/red
|
||||
name = "red LED"
|
||||
led_color = "#FF0000"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/orange
|
||||
name = "orange LED"
|
||||
led_color = "#FF9900"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/yellow
|
||||
name = "yellow LED"
|
||||
led_color = "#FFFF00"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/green
|
||||
name = "green LED"
|
||||
led_color = "#008000"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/blue
|
||||
name = "blue LED"
|
||||
led_color = "#0000FF"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/purple
|
||||
name = "purple LED"
|
||||
led_color = "#800080"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/cyan
|
||||
name = "cyan LED"
|
||||
led_color = "#00FFFF"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/white
|
||||
name = "white LED"
|
||||
led_color = "#FFFFFF"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/pink
|
||||
name = "pink LED"
|
||||
led_color = "#FF00FF"
|
||||
@@ -0,0 +1,81 @@
|
||||
/obj/item/integrated_circuit/power/
|
||||
category_text = "Power - Active"
|
||||
|
||||
/obj/item/integrated_circuit/power/transmitter
|
||||
name = "power transmission circuit"
|
||||
desc = "This can wirelessly transmit electricity from an assembly's battery towards a nearby machine."
|
||||
icon_state = "power_transmitter"
|
||||
extended_desc = "This circuit transmits 5 kJ of electricity every time the activator pin is pulsed. The input pin must be \
|
||||
a reference to a machine to send electricity to. This can be a battery, or anything containing a battery. The machine can exist \
|
||||
inside the assembly, or adjacent to it. The power is sourced from the assembly's power cell. If the target is outside of the assembly, \
|
||||
some power is lost due to ineffiency."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
complexity = 16
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"target cell charge" = IC_PINTYPE_NUMBER,
|
||||
"target cell max charge" = IC_PINTYPE_NUMBER,
|
||||
"target cell percentage" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("transmit" = IC_PINTYPE_PULSE_IN, "on transmit" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
|
||||
power_draw_per_use = 500 // Inefficency has to come from somewhere.
|
||||
var/amount_to_move = 5000
|
||||
|
||||
/obj/item/integrated_circuit/power/transmitter/large
|
||||
name = "large power transmission circuit"
|
||||
desc = "This can wirelessly transmit a lot of electricity from an assembly's battery towards a nearby machine. Warning: Do not operate in flammable enviroments."
|
||||
extended_desc = "This circuit transmits 20 kJ of electricity every time the activator pin is pulsed. The input pin must be \
|
||||
a reference to a machine to send electricity to. This can be a battery, or anything containing a battery. The machine can exist \
|
||||
inside the assembly, or adjacent to it. The power is sourced from the assembly's power cell. If the target is outside of the assembly, \
|
||||
some power is lost due to ineffiency."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
complexity = 32
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 6, TECH_MAGNET = 5)
|
||||
power_draw_per_use = 2000
|
||||
amount_to_move = 20000
|
||||
|
||||
/obj/item/integrated_circuit/power/transmitter/do_work()
|
||||
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
if(AM)
|
||||
if(!assembly)
|
||||
return FALSE // Pointless to do everything else if there's no battery to draw from.
|
||||
|
||||
var/obj/item/stock_parts/cell/cell = AM.get_cell()
|
||||
if(cell)
|
||||
var/transfer_amount = amount_to_move
|
||||
var/turf/A = get_turf(src)
|
||||
var/turf/B = get_turf(AM)
|
||||
if(A.Adjacent(B))
|
||||
if(AM.loc != assembly)
|
||||
transfer_amount *= 0.8 // Losses due to distance.
|
||||
|
||||
if(cell.charge == cell.maxcharge)
|
||||
return FALSE
|
||||
|
||||
if(transfer_amount && assembly.draw_power(amount_to_move)) // CELLRATE is already handled in draw_power()
|
||||
cell.give(transfer_amount * GLOB.CELLRATE)
|
||||
set_pin_data(IC_OUTPUT, 1, cell.charge)
|
||||
set_pin_data(IC_OUTPUT, 2, cell.maxcharge)
|
||||
set_pin_data(IC_OUTPUT, 3, cell.percent())
|
||||
activate_pin(2)
|
||||
push_data()
|
||||
return TRUE
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
activate_pin(2)
|
||||
push_data()
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/power/transmitter/large/do_work()
|
||||
if(..()) // If the above code succeeds, do this below.
|
||||
if(prob(20))
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(12, 1, src)
|
||||
s.start()
|
||||
visible_message("<span class='warning'>\The [assembly] makes some sparks!</span>")
|
||||
@@ -0,0 +1,365 @@
|
||||
/obj/item/integrated_circuit/reagent
|
||||
category_text = "Reagent"
|
||||
var/volume = 0
|
||||
resistance_flags = UNACIDABLE | FIRE_PROOF
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/New()
|
||||
..()
|
||||
if(volume)
|
||||
create_reagents(volume)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke
|
||||
name = "smoke generator"
|
||||
desc = "Unlike most electronics, creating smoke is completely intentional."
|
||||
icon_state = "smoke"
|
||||
extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \
|
||||
into the smoke clouds when activated. The reagents are consumed when smoke is made."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 20
|
||||
cooldown_per_use = 1 SECONDS
|
||||
inputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list("create smoke" = IC_PINTYPE_PULSE_IN,"on smoked" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3)
|
||||
volume = 100
|
||||
power_draw_per_use = 20
|
||||
var/smoke_radius = 5
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/do_work()
|
||||
var/location = get_turf(src)
|
||||
var/datum/effect_system/smoke_spread/chem/S = new
|
||||
S.attach(location)
|
||||
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
if(S)
|
||||
S.set_up(reagents, smoke_radius, location, 0)
|
||||
S.start()
|
||||
if(reagents)
|
||||
reagents.clear_reagents()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector
|
||||
name = "integrated hypo-injector"
|
||||
desc = "This scary looking thing is able to pump liquids into whatever it's pointed at."
|
||||
icon_state = "injector"
|
||||
extended_desc = "This autoinjector can push reagents into another container or someone else outside of the machine. The target \
|
||||
must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing. Negative given amount makes injector suck out reagents."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 20
|
||||
cooldown_per_use = 6 SECONDS
|
||||
inputs = list("target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER)
|
||||
inputs_default = list("2" = 5)
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list("inject" = IC_PINTYPE_PULSE_IN, "on injected" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
volume = 30
|
||||
power_draw_per_use = 15
|
||||
var/direction_mode = SYRINGE_INJECT
|
||||
var/transfer_amount = 10
|
||||
var/busy = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 2)
|
||||
if(new_amount < 0)
|
||||
new_amount = -new_amount
|
||||
direction_mode = SYRINGE_DRAW
|
||||
else
|
||||
direction_mode = SYRINGE_INJECT
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, volume)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/proc/inject_tray(var/obj/machinery/hydroponics/H,var/atom/movable/SO,var/A)
|
||||
var/datum/reagents/S = new /datum/reagents() //This is a strange way, but I don't know of a better one so I can't fix it at the moment...
|
||||
S.my_atom = H
|
||||
SO.reagents.trans_to(S,A)
|
||||
H.applyChemicals(S)
|
||||
S.clear_reagents()
|
||||
qdel(S)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/do_work()
|
||||
set waitfor = FALSE // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
if(!istype(AM)||!Adjacent(AM)||busy)
|
||||
activate_pin(3)
|
||||
return
|
||||
if(istype(AM,/obj/machinery/hydroponics)&&(direction_mode==SYRINGE_INJECT)&&(reagents.total_volume))//injection into tray.
|
||||
inject_tray(AM,src,transfer_amount)
|
||||
activate_pin(2)
|
||||
return
|
||||
if(!AM.reagents)
|
||||
activate_pin(3)
|
||||
return
|
||||
if(direction_mode == SYRINGE_INJECT)
|
||||
if(!reagents.total_volume) // Empty
|
||||
activate_pin(3)
|
||||
return
|
||||
if(AM.is_injectable())
|
||||
if(AM.reagents.total_volume>=AM.reagents.maximum_volume)
|
||||
activate_pin(3)
|
||||
return
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!L.can_inject(null, 0))
|
||||
activate_pin(3)
|
||||
return
|
||||
//Always log attemped injections for admins
|
||||
var/list/rinject = list()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
rinject += R.name
|
||||
var/contained = english_list(rinject)
|
||||
add_logs(src, L, "attemped to inject", addition="which had [contained]") //TODO: proper logging (maybe last touched and assembled)
|
||||
L.visible_message("<span class='danger'>[src] is trying to inject [L]!</span>", \
|
||||
"<span class='userdanger'>[src] is trying to inject you!</span>")
|
||||
busy = TRUE
|
||||
if(do_atom(src, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,null,0)))
|
||||
var/fraction = min(transfer_amount/reagents.total_volume, 1)
|
||||
reagents.reaction(L, INJECT, fraction)
|
||||
reagents.trans_to(L, transfer_amount)
|
||||
L.visible_message("<span class='danger'>[src] injects [L] with it's needle!</span>", \
|
||||
"<span class='userdanger'>[src] injects you with it's needle!</span>")
|
||||
else
|
||||
busy = FALSE
|
||||
activate_pin(3)
|
||||
return
|
||||
busy = FALSE
|
||||
else
|
||||
reagents.trans_to(AM, transfer_amount)
|
||||
else
|
||||
activate_pin(3)
|
||||
return
|
||||
else
|
||||
if(reagents.total_volume >= reagents.maximum_volume) // Full
|
||||
activate_pin(3)
|
||||
return
|
||||
var/tramount = Clamp(min(transfer_amount, reagents.maximum_volume - reagents.total_volume), 0, reagents.maximum_volume)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
L.visible_message("<span class='danger'>[src] is trying to take a blood sample from [L]!</span>", \
|
||||
"<span class='userdanger'>[src] is trying to take a blood sample from you!</span>")
|
||||
busy = TRUE
|
||||
if(do_atom(src, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,null,0)))
|
||||
if(L.transfer_blood_to(src, tramount))
|
||||
L.visible_message("[src] takes a blood sample from [L].")
|
||||
else
|
||||
busy = FALSE
|
||||
activate_pin(3)
|
||||
return
|
||||
busy = FALSE
|
||||
else
|
||||
if(!AM.reagents.total_volume || !AM.is_drawable())
|
||||
activate_pin(3)
|
||||
return
|
||||
AM.reagents.trans_to(src, tramount)
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump
|
||||
name = "reagent pump"
|
||||
desc = "Moves liquids safely inside a machine, or even nearby it."
|
||||
icon_state = "reagent_pump"
|
||||
extended_desc = "This is a pump, which will move liquids from the source ref to the target ref. The third pin determines \
|
||||
how much liquid is moved per pulse, between 0 and 50. The pump can move reagents to any open container inside the machine, or \
|
||||
outside the machine if it is next to the machine. Note that this cannot be used on entities."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 8
|
||||
inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER)
|
||||
inputs_default = list("3" = 5)
|
||||
outputs = list()
|
||||
activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/transfer_amount = 10
|
||||
var/direction_mode = SYRINGE_INJECT
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 3)
|
||||
if(new_amount < 0)
|
||||
new_amount = -new_amount
|
||||
direction_mode = SYRINGE_DRAW
|
||||
else
|
||||
direction_mode = SYRINGE_INJECT
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, 50)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump/do_work()
|
||||
var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable)
|
||||
|
||||
if(!istype(source) || !istype(target) || !source.reagents) //Invalid input
|
||||
return
|
||||
if(Adjacent(source) && Adjacent(target))
|
||||
if(istype(target,/obj/machinery/hydroponics)&&(source.reagents.total_volume))//injection into tray.
|
||||
inject_tray(target,source,transfer_amount)
|
||||
activate_pin(2)
|
||||
return
|
||||
|
||||
if(!target.reagents)
|
||||
return
|
||||
if(ismob(source) || ismob(target))
|
||||
return
|
||||
if(!source.is_open_container() || !target.is_open_container())
|
||||
return
|
||||
if(direction_mode)
|
||||
if(target.reagents.maximum_volume - target.reagents.total_volume <= 0) //full
|
||||
return
|
||||
source.reagents.trans_to(target, transfer_amount)
|
||||
else
|
||||
if(source.reagents.maximum_volume - source.reagents.total_volume <= 0)
|
||||
return
|
||||
target.reagents.trans_to(source, transfer_amount)
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage
|
||||
name = "reagent storage"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u."
|
||||
icon_state = "reagent_storage"
|
||||
extended_desc = "This is effectively an internal beaker."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
volume = 60
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/cryo
|
||||
name = "cryo reagent storage"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. This will also suppress reactions."
|
||||
icon_state = "reagent_storage_cryo"
|
||||
extended_desc = "This is effectively an internal cryo beaker."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 8
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_MATERIALS = 4, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/cryo/New()
|
||||
. = ..()
|
||||
reagents.set_reacting(FALSE)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/big
|
||||
name = "big reagent storage"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 180u."
|
||||
icon_state = "reagent_storage_big"
|
||||
extended_desc = "This is effectively an internal beaker."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 16
|
||||
volume = 180
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/scan
|
||||
name = "reagent scanner"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents."
|
||||
icon_state = "reagent_scan"
|
||||
extended_desc = "Mostly useful for reagent filter."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 8
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF,"list of reagents" = IC_PINTYPE_LIST)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/scan/do_work()
|
||||
var/cont[0]
|
||||
for(var/datum/reagent/RE in reagents.reagent_list)
|
||||
cont += RE.id
|
||||
set_pin_data(IC_OUTPUT, 3, cont)
|
||||
push_data()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter
|
||||
name = "reagent filter"
|
||||
desc = "Filtering liquids by list of desired or unwanted reagents."
|
||||
icon_state = "reagent_filter"
|
||||
extended_desc = "This is a filter, which will move liquids from the source ref to the target ref. \
|
||||
It will move all reagents, except list, given in fourth pin if amount value is positive.\
|
||||
Or it will move only desired reagents if amount is negative, The third pin determines \
|
||||
how much reagent is moved per pulse, between 0 and 50. Amount is given for each separate reagent."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 8
|
||||
inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER, "list of reagents" = IC_PINTYPE_LIST)
|
||||
inputs_default = list("3" = 5)
|
||||
outputs = list()
|
||||
activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/transfer_amount = 10
|
||||
var/direction_mode = SYRINGE_INJECT
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 3)
|
||||
if(new_amount < 0)
|
||||
new_amount = -new_amount
|
||||
direction_mode = SYRINGE_DRAW
|
||||
else
|
||||
direction_mode = SYRINGE_INJECT
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, 50)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter/do_work()
|
||||
var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable)
|
||||
var/list/demand = get_pin_data(IC_INPUT, 4)
|
||||
if(!istype(source) || !istype(target)) //Invalid input
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
if(source.Adjacent(T) && target.Adjacent(T))
|
||||
if(!source.reagents || !target.reagents)
|
||||
return
|
||||
if(ismob(source) || ismob(target))
|
||||
return
|
||||
if(!source.is_open_container() || !target.is_open_container())
|
||||
return
|
||||
if(target.reagents.maximum_volume - target.reagents.total_volume <= 0)
|
||||
return
|
||||
for(var/datum/reagent/G in source.reagents.reagent_list)
|
||||
if (!direction_mode)
|
||||
if(G.id in demand)
|
||||
source.reagents.trans_id_to(target, G.id, transfer_amount)
|
||||
else
|
||||
if(!(G.id in demand))
|
||||
source.reagents.trans_id_to(target, G.id, transfer_amount)
|
||||
activate_pin(2)
|
||||
push_data()
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/obj/item/integrated_circuit/smart
|
||||
category_text = "Smart"
|
||||
|
||||
/obj/item/integrated_circuit/smart/basic_pathfinder
|
||||
name = "basic pathfinder"
|
||||
desc = "This complex circuit is able to determine what direction a given target is."
|
||||
extended_desc = "This circuit uses a miniturized, integrated camera to determine where the target is. If the machine \
|
||||
cannot see the target, it will not be able to calculate the correct direction."
|
||||
icon_state = "numberpad"
|
||||
complexity = 25
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list("dir" = IC_PINTYPE_DIR)
|
||||
activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5)
|
||||
power_draw_per_use = 40
|
||||
|
||||
/obj/item/integrated_circuit/smart/basic_pathfinder/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
|
||||
if(!isweakref(I.data))
|
||||
return
|
||||
var/atom/A = I.data.resolve()
|
||||
if(!A)
|
||||
return
|
||||
if(!(A in view(get_turf(src))))
|
||||
push_data()
|
||||
return // Can't see the target.
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A)))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -0,0 +1,145 @@
|
||||
/obj/item/integrated_circuit/time
|
||||
name = "time circuit"
|
||||
desc = "Now you can build your own clock!"
|
||||
complexity = 2
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
category_text = "Time"
|
||||
|
||||
/obj/item/integrated_circuit/time/delay
|
||||
name = "two-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of two seconds."
|
||||
icon_state = "delay-20"
|
||||
var/delay = 20
|
||||
activators = list("incoming"= IC_PINTYPE_PULSE_IN,"outgoing" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/do_work()
|
||||
addtimer(CALLBACK(src, .proc/activate_pin, 2), delay)
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/five_sec
|
||||
name = "five-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of five seconds."
|
||||
icon_state = "delay-50"
|
||||
delay = 50
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/one_sec
|
||||
name = "one-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of one second."
|
||||
icon_state = "delay-10"
|
||||
delay = 10
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/half_sec
|
||||
name = "half-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of half a second."
|
||||
icon_state = "delay-5"
|
||||
delay = 5
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/tenth_sec
|
||||
name = "tenth-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of 1/10th of a second."
|
||||
icon_state = "delay-1"
|
||||
delay = 1
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/custom
|
||||
name = "custom delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse."
|
||||
icon_state = "delay"
|
||||
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 = Clamp(delay_input ,1 ,36000) //An hour.
|
||||
delay = new_delay
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker
|
||||
name = "ticker circuit"
|
||||
desc = "This circuit sends an automatic pulse every four seconds."
|
||||
icon_state = "tick-m"
|
||||
complexity = 8
|
||||
var/delay = 4 SECONDS
|
||||
var/next_fire = 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
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/Destroy()
|
||||
if(is_running)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/on_data_written()
|
||||
var/do_tick = get_pin_data(IC_INPUT, 1)
|
||||
if(do_tick && !is_running)
|
||||
is_running = TRUE
|
||||
tick()
|
||||
else if(is_running)
|
||||
is_running = FALSE
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/proc/tick()
|
||||
if(is_running)
|
||||
addtimer(CALLBACK(src, .proc/tick), delay)
|
||||
if(world.time > next_fire)
|
||||
next_fire = world.time + delay
|
||||
activate_pin(1)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/fast
|
||||
name = "fast ticker"
|
||||
desc = "This advanced circuit sends an automatic pulse every two seconds."
|
||||
icon_state = "tick-f"
|
||||
complexity = 12
|
||||
delay = 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."
|
||||
icon_state = "tick-s"
|
||||
complexity = 4
|
||||
delay = 6 SECONDS
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/time/clock
|
||||
name = "integrated clock"
|
||||
desc = "Tells you what the local time is, specific to your station or planet."
|
||||
icon_state = "clock"
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"time" = IC_PINTYPE_STRING,
|
||||
"hours" = IC_PINTYPE_NUMBER,
|
||||
"minutes" = IC_PINTYPE_NUMBER,
|
||||
"seconds" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("get time" = IC_PINTYPE_PULSE_IN, "on time got" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/time/clock/do_work()
|
||||
var/wtime = world.time
|
||||
set_pin_data(IC_OUTPUT, 1, time2text(wtime, "hh:mm:ss") )
|
||||
set_pin_data(IC_OUTPUT, 2, text2num(time2text(wtime, "hh") ) )
|
||||
set_pin_data(IC_OUTPUT, 3, text2num(time2text(wtime, "mm") ) )
|
||||
set_pin_data(IC_OUTPUT, 4, text2num(time2text(wtime, "ss") ) )
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -0,0 +1,138 @@
|
||||
//These circuits do not-so-simple math.
|
||||
/obj/item/integrated_circuit/trig
|
||||
complexity = 1
|
||||
inputs = list(
|
||||
"A" = IC_PINTYPE_NUMBER,
|
||||
"B" = IC_PINTYPE_NUMBER,
|
||||
"C" = IC_PINTYPE_NUMBER,
|
||||
"D" = IC_PINTYPE_NUMBER,
|
||||
"E" = IC_PINTYPE_NUMBER,
|
||||
"F" = IC_PINTYPE_NUMBER,
|
||||
"G" = IC_PINTYPE_NUMBER,
|
||||
"H" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list("result" = IC_PINTYPE_NUMBER)
|
||||
activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Trig"
|
||||
extended_desc = "Input and output are in degrees."
|
||||
power_draw_per_use = 1 // Still cheap math.
|
||||
|
||||
// Sine //
|
||||
|
||||
/obj/item/integrated_circuit/trig/sine
|
||||
name = "sin circuit"
|
||||
desc = "Has nothing to do with evil, unless you consider trigonometry to be evil. Outputs the sine of A."
|
||||
icon_state = "sine"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/sine/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = sin(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Cosine //
|
||||
|
||||
/obj/item/integrated_circuit/trig/cosine
|
||||
name = "cos circuit"
|
||||
desc = "Outputs the cosine of A."
|
||||
icon_state = "cosine"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/cosine/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = cos(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Tangent //
|
||||
|
||||
/obj/item/integrated_circuit/trig/tangent
|
||||
name = "tan circuit"
|
||||
desc = "Outputs the tangent of A. Guaranteed to not go on a tangent about its existance."
|
||||
icon_state = "tangent"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/tangent/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = Tan(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Cosecant //
|
||||
|
||||
/obj/item/integrated_circuit/trig/cosecant
|
||||
name = "csc circuit"
|
||||
desc = "Outputs the cosecant of A."
|
||||
icon_state = "cosecant"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/cosecant/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = Csc(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Secant //
|
||||
|
||||
/obj/item/integrated_circuit/trig/secant
|
||||
name = "sec circuit"
|
||||
desc = "Outputs the secant of A. Has nothing to do with the security department."
|
||||
icon_state = "secant"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/secant/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = Sec(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Cotangent //
|
||||
|
||||
/obj/item/integrated_circuit/trig/cotangent
|
||||
name = "cot circuit"
|
||||
desc = "Outputs the cotangent of A."
|
||||
icon_state = "cotangent"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/cotangent/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = Cot(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -33,7 +33,7 @@ Chaplain
|
||||
H.equip_to_slot_or_del(B, slot_in_backpack)
|
||||
var/nrt = SSreligion.holy_weapon_type || /obj/item/nullrod
|
||||
var/obj/item/nullrod/N = new nrt(H)
|
||||
H.equip_to_slot_or_del(N, slot_in_backpack)
|
||||
H.put_in_hands(N)
|
||||
return
|
||||
|
||||
var/new_religion = "Christianity"
|
||||
|
||||
@@ -240,6 +240,10 @@
|
||||
name = "Devil Lock"
|
||||
icon_state = "hair_devilock"
|
||||
|
||||
/datum/sprite_accessory/hair/drillhairextended
|
||||
name = "Extended Drill Hair"
|
||||
icon_state = "hair_drillhairextended"
|
||||
|
||||
/datum/sprite_accessory/hair/dreadlocks
|
||||
name = "Dreadlocks"
|
||||
icon_state = "hair_dreads"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user