mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-01-04 22:43:24 +00:00
Merge branch 'master' into heart_damage
This commit is contained in:
@@ -192,3 +192,10 @@
|
||||
#define NOMUT 0
|
||||
#define COLORMUT 1
|
||||
#define SPECIESMUT 2
|
||||
|
||||
//carbon taste sensitivity defines, used in mob/living/carbon/proc/ingest
|
||||
#define TASTE_HYPERSENSITIVE 3 //anything below 5%
|
||||
#define TASTE_SENSITIVE 2 //anything below 7%
|
||||
#define TASTE_NORMAL 1 //anything below 15%
|
||||
#define TASTE_DULL 0.5 //anything below 30%
|
||||
#define TASTE_NUMB 0.1 //anything below 150%
|
||||
@@ -33,11 +33,14 @@
|
||||
#define LANGUAGE_SKRELLIAN "Skrellian"
|
||||
#define LANGUAGE_TRADEBAND "Tradeband"
|
||||
#define LANGUAGE_GUTTER "Gutter"
|
||||
#define LANGUAGE_SIGN "Sign Language"
|
||||
#define LANGUAGE_SCHECHI "Schechi"
|
||||
#define LANGUAGE_ROOTLOCAL "Local Rootspeak"
|
||||
#define LANGUAGE_ROOTGLOBAL "Global Rootspeak"
|
||||
#define LANGUAGE_CULT "Cult"
|
||||
#define LANGUAGE_SIGN "Sign Language"
|
||||
#define LANGUAGE_OCCULT "Occult"
|
||||
#define LANGUAGE_CHANGELING "Changeling"
|
||||
#define LANGUAGE_VOX "Vox-Pidgin"
|
||||
|
||||
// Language flags.
|
||||
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
|
||||
|
||||
@@ -573,7 +573,7 @@
|
||||
name = "subspace wavelength analyzer"
|
||||
icon_state = "wavelength_analyzer"
|
||||
desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths."
|
||||
origin_tech = list(TECH_DATA = 3, TECH_MAGNETS = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2)
|
||||
origin_tech = list(TECH_DATA = 3, TECH_MAGNET = 4, TECH_MATERIAL = 4, TECH_BLUESPACE = 2)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10)
|
||||
|
||||
/obj/item/weapon/stock_parts/subspace/crystal
|
||||
|
||||
@@ -308,7 +308,7 @@ var/datum/antagonist/raider/raiders
|
||||
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(player), slot_shoes) // REPLACE THESE WITH CODED VOX ALTERNATIVES.
|
||||
player.equip_to_slot_or_del(new /obj/item/clothing/gloves/vox(player), slot_gloves) // AS ABOVE.
|
||||
player.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat/vox(player), slot_wear_mask)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/tank/phoron/vox(player), slot_back)
|
||||
player.equip_to_slot_or_del(new /obj/item/weapon/tank/vox(player), slot_back)
|
||||
player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_r_store)
|
||||
|
||||
player.internal = locate(/obj/item/weapon/tank) in player.contents
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/clothing/gloves/regen/process()
|
||||
if(!wearer || wearer.isSynthetic() || wearer.stat == DEAD || wearer.nutrition >= 10)
|
||||
if(!wearer || wearer.isSynthetic() || wearer.stat == DEAD || wearer.nutrition <= 10)
|
||||
return // Robots and dead people don't have a metabolism.
|
||||
|
||||
if(wearer.getBruteLoss())
|
||||
|
||||
@@ -14,8 +14,12 @@
|
||||
return check_access(id)
|
||||
return 0
|
||||
|
||||
/obj/item/proc/GetAccess()
|
||||
return list()
|
||||
///obj/item/proc/GetAccess()
|
||||
// return list()
|
||||
|
||||
/atom/movable/proc/GetAccess()
|
||||
var/obj/item/weapon/card/id/id = GetIdCard()
|
||||
return id ? id.GetAccess() : list()
|
||||
|
||||
/obj/proc/GetID()
|
||||
return null
|
||||
@@ -197,7 +201,7 @@
|
||||
"Emergency Response Team",
|
||||
"Emergency Response Team Leader")
|
||||
|
||||
/mob/proc/GetIdCard()
|
||||
/atom/movable/proc/GetIdCard()
|
||||
return null
|
||||
|
||||
/mob/living/bot/GetIdCard()
|
||||
|
||||
@@ -8,7 +8,7 @@ obj/machinery/recharger
|
||||
idle_power_usage = 4
|
||||
active_power_usage = 40000 //40 kW
|
||||
var/obj/item/charging = null
|
||||
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/device/laptop, /obj/item/weapon/cell, /obj/item/device/flashlight)
|
||||
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/device/laptop, /obj/item/weapon/cell, /obj/item/device/flashlight, /obj/item/device/electronic_assembly)
|
||||
var/icon_state_charged = "recharger2"
|
||||
var/icon_state_charging = "recharger1"
|
||||
var/icon_state_idle = "recharger0" //also when unpowered
|
||||
@@ -60,6 +60,11 @@ obj/machinery/recharger
|
||||
if(!L.stored_computer.battery)
|
||||
user << "There's no battery in it!"
|
||||
return
|
||||
if(istype(G, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/assembly = G
|
||||
if(!assembly.battery)
|
||||
to_chat(user, "<span class='warning'>The assembly doesn't have a power cell.</span>")
|
||||
return
|
||||
user.drop_item()
|
||||
G.loc = src
|
||||
charging = G
|
||||
@@ -161,6 +166,21 @@ obj/machinery/recharger
|
||||
update_use_power(1)
|
||||
return
|
||||
|
||||
if(istype(charging, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/assembly = charging
|
||||
if(assembly.battery)
|
||||
if(!assembly.battery.fully_charged())
|
||||
icon_state = icon_state_charging
|
||||
assembly.battery.give(active_power_usage*CELLRATE)
|
||||
update_use_power(2)
|
||||
else
|
||||
icon_state = icon_state_charged
|
||||
update_use_power(1)
|
||||
else
|
||||
icon_state = icon_state_idle
|
||||
update_use_power(1)
|
||||
return
|
||||
|
||||
/obj/machinery/recharger/emp_act(severity)
|
||||
if(stat & (NOPOWER|BROKEN) || !anchored)
|
||||
..(severity)
|
||||
|
||||
@@ -100,14 +100,21 @@
|
||||
src.loc = F
|
||||
return
|
||||
|
||||
/obj/item/weapon/tank/phoron/vox
|
||||
/obj/item/weapon/tank/vox //Can't be a child of phoron or the gas amount gets screwey.
|
||||
name = "phoron tank"
|
||||
desc = "Contains dangerous phoron. Do not inhale. Warning: extremely flammable."
|
||||
icon_state = "oxygen_fr"
|
||||
gauge_icon = null
|
||||
flags = CONDUCT
|
||||
distribute_pressure = ONE_ATMOSPHERE*O2STANDARD
|
||||
slot_flags = SLOT_BACK //these ones have straps!
|
||||
|
||||
/obj/item/weapon/tank/vox/New()
|
||||
..()
|
||||
|
||||
air_contents.adjust_gas("phoron", (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
|
||||
return
|
||||
|
||||
/*
|
||||
* Emergency Oxygen
|
||||
*/
|
||||
|
||||
@@ -127,6 +127,7 @@
|
||||
new /obj/item/clothing/head/beret/sec/corporate/hos(src)
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/security(src)
|
||||
new /obj/item/device/flashlight/maglight(src)
|
||||
new /obj/item/clothing/mask/gas/half(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -173,6 +174,7 @@
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/security(src)
|
||||
new /obj/item/device/flashlight/maglight(src)
|
||||
new /obj/item/device/megaphone(src)
|
||||
new /obj/item/clothing/mask/gas/half(src)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -535,6 +535,7 @@
|
||||
new /obj/item/clothing/under/pants/black(src)
|
||||
new /obj/item/clothing/under/pants/tan(src)
|
||||
new /obj/item/clothing/under/pants/track(src)
|
||||
new /obj/item/clothing/suit/storage/toggle/track(src)
|
||||
new /obj/item/clothing/under/pants(src)
|
||||
new /obj/item/clothing/under/pants/khaki(src)
|
||||
new /obj/item/clothing/mask/bandana/blue(src)
|
||||
|
||||
@@ -147,8 +147,8 @@
|
||||
slip_stun = 4
|
||||
slip_dist = 2
|
||||
|
||||
if(M.slip("the [floor_type] floor",slip_stun))
|
||||
for(var/i = 0;i<slip_dist;i++)
|
||||
if(M.slip("the [floor_type] floor", slip_stun))
|
||||
for(var/i = 1 to slip_dist)
|
||||
step(M, M.dir)
|
||||
sleep(1)
|
||||
else
|
||||
|
||||
@@ -21,11 +21,17 @@
|
||||
var/savefile/F = new(NEWSFILE)
|
||||
if(F)
|
||||
var/title = F["title"]
|
||||
var/body = F["body"]
|
||||
var/body = html2paper_markup(F["body"])
|
||||
var/new_title = sanitize(input(src,"Write a good title for the news update. Note: HTML is NOT supported.","Write News", title) as null|text, extra = 0)
|
||||
if(!new_title)
|
||||
return
|
||||
var/new_body = sanitize(input(src,"Write the body of the news update here. Note: HTML is NOT supported.","Write News", body) as null|message, extra = 0)
|
||||
var/new_body = sanitize(input(src,"Write the body of the news update here. Note: HTML is NOT supported, however paper markup is supported. \n\
|
||||
Hitting enter will automatically add a line break. \n\
|
||||
Valid markup includes: \[b\], \[i\], \[u\], \[large\], \[h1\], \[h2\], \[h3\]\ \[*\], \[hr\], \[small\], \[list\], \[table\], \[grid\], \
|
||||
\[row\], \[cell\], \[logo\], \[sglogo\].","Write News", body) as null|message, extra = 0)
|
||||
|
||||
new_body = paper_markup2html(new_body)
|
||||
|
||||
if(findtext(new_body,"<script",1,0) ) // Is this needed with santize()?
|
||||
return
|
||||
F["title"] << new_title
|
||||
@@ -38,5 +44,78 @@
|
||||
var/savefile/F = new(NEWSFILE)
|
||||
if(F)
|
||||
return F
|
||||
// This is used when submitting the news input, so the safe markup can get past sanitize.
|
||||
/proc/paper_markup2html(var/text)
|
||||
text = replacetext(text, "\n", "<br>")
|
||||
text = replacetext(text, "\[center\]", "<center>")
|
||||
text = replacetext(text, "\[/center\]", "</center>")
|
||||
text = replacetext(text, "\[br\]", "<BR>")
|
||||
text = replacetext(text, "\[b\]", "<B>")
|
||||
text = replacetext(text, "\[/b\]", "</B>")
|
||||
text = replacetext(text, "\[i\]", "<I>")
|
||||
text = replacetext(text, "\[/i\]", "</I>")
|
||||
text = replacetext(text, "\[u\]", "<U>")
|
||||
text = replacetext(text, "\[/u\]", "</U>")
|
||||
text = replacetext(text, "\[large\]", "<font size=\"4\">")
|
||||
text = replacetext(text, "\[/large\]", "</font>")
|
||||
text = replacetext(text, "\[h1\]", "<H1>")
|
||||
text = replacetext(text, "\[/h1\]", "</H1>")
|
||||
text = replacetext(text, "\[h2\]", "<H2>")
|
||||
text = replacetext(text, "\[/h2\]", "</H2>")
|
||||
text = replacetext(text, "\[h3\]", "<H3>")
|
||||
text = replacetext(text, "\[/h3\]", "</H3>")
|
||||
|
||||
text = replacetext(text, "\[*\]", "<li>")
|
||||
text = replacetext(text, "\[hr\]", "<HR>")
|
||||
text = replacetext(text, "\[small\]", "<font size = \"1\">")
|
||||
text = replacetext(text, "\[/small\]", "</font>")
|
||||
text = replacetext(text, "\[list\]", "<ul>")
|
||||
text = replacetext(text, "\[/list\]", "</ul>")
|
||||
text = replacetext(text, "\[table\]", "<table border=1 cellspacing=0 cellpadding=3 style='border: 1px solid black;'>")
|
||||
text = replacetext(text, "\[/table\]", "</td></tr></table>")
|
||||
text = replacetext(text, "\[grid\]", "<table>")
|
||||
text = replacetext(text, "\[/grid\]", "</td></tr></table>")
|
||||
text = replacetext(text, "\[row\]", "</td><tr>")
|
||||
text = replacetext(text, "\[cell\]", "<td>")
|
||||
text = replacetext(text, "\[logo\]", "<img src = ntlogo.png>") // Not sure if these would get used but why not
|
||||
text = replacetext(text, "\[sglogo\]", "<img src = sglogo.png>")
|
||||
return text
|
||||
|
||||
// This is used when reading text that went through paper_markup2html(), to reverse it so that edits don't need to replace everything once more to avoid sanitization.
|
||||
/proc/html2paper_markup(var/text)
|
||||
text = replacetext(text, "<br>", "\[br\]")
|
||||
text = replacetext(text, "<center>", "\[center\]")
|
||||
text = replacetext(text, "</center>", "\[/center\]")
|
||||
text = replacetext(text, "<BR>", "\[br\]")
|
||||
text = replacetext(text, "<B>", "\[b\]")
|
||||
text = replacetext(text, "</B>", "\[/b\]")
|
||||
text = replacetext(text, "<I>", "\[i\]")
|
||||
text = replacetext(text, "</I>", "\[/i\]")
|
||||
text = replacetext(text, "<U>", "\[u\]")
|
||||
text = replacetext(text, "</U>", "\[/u\]")
|
||||
text = replacetext(text, "<font size=\"4\">", "\[large\]")
|
||||
text = replacetext(text, "</font>", "\[/large\]")
|
||||
text = replacetext(text, "<H1>", "\[h1\]")
|
||||
text = replacetext(text, "</H1>", "\[/h1\]")
|
||||
text = replacetext(text, "<H2>", "\[h2\]")
|
||||
text = replacetext(text, "</H2>", "\[/h2\]")
|
||||
text = replacetext(text, "<H3>", "\[h3\]")
|
||||
text = replacetext(text, "</H3>", "\[/h3\]")
|
||||
|
||||
text = replacetext(text, "<li>", "\[*\]")
|
||||
text = replacetext(text, "<HR>", "\[hr\]")
|
||||
text = replacetext(text, "<font size = \"1\">", "\[small\]")
|
||||
text = replacetext(text, "</font>", "\[/small\]")
|
||||
text = replacetext(text, "<ul>", "\[list\]")
|
||||
text = replacetext(text, "</ul>", "\[/list\]")
|
||||
text = replacetext(text, "<table border=1 cellspacing=0 cellpadding=3 style='border: 1px solid black;'>", "\[table\]")
|
||||
text = replacetext(text, "</td></tr></table>", "\[/table\]")
|
||||
text = replacetext(text, "<table>", "\[grid\]")
|
||||
text = replacetext(text, "</td></tr></table>", "\[/grid\]")
|
||||
text = replacetext(text, "</td><tr>", "\[row\]")
|
||||
text = replacetext(text, "<td>", "\[cell\]")
|
||||
text = replacetext(text, "<img src = ntlogo.png>", "\[logo\]") // Not sure if these would get used but why not
|
||||
text = replacetext(text, "<img src = sglogo.png>", "\[sglogo\]")
|
||||
return text
|
||||
|
||||
#undef NEWSFILE
|
||||
@@ -42,15 +42,13 @@
|
||||
display_name = "Security HUD, sunglasses (Security)"
|
||||
path = /obj/item/clothing/glasses/sunglasses/sechud
|
||||
|
||||
/datum/gear/eyes/secaviators
|
||||
display_name = "Security HUD Aviators"
|
||||
/datum/gear/eyes/security/aviator
|
||||
display_name = "Security HUD Aviators (Security)"
|
||||
path = /obj/item/clothing/glasses/sunglasses/sechud/aviator
|
||||
allowed_roles = list("Security Officer","Head of Security","Warden")
|
||||
|
||||
/datum/gear/eyes/secaviators/prescription
|
||||
display_name = "Security HUD Aviators, prescription"
|
||||
/datum/gear/eyes/security/aviator/prescription
|
||||
display_name = "Security HUD Aviators, prescription (Security)"
|
||||
path = /obj/item/clothing/glasses/sunglasses/sechud/aviator/prescription
|
||||
allowed_roles = list("Security Officer","Head of Security","Warden")
|
||||
|
||||
/datum/gear/eyes/medical
|
||||
display_name = "Medical HUD (Medical)"
|
||||
@@ -61,10 +59,32 @@
|
||||
display_name = "Medical HUD, prescription (Medical)"
|
||||
path = /obj/item/clothing/glasses/hud/health/prescription
|
||||
|
||||
/datum/gear/eyes/shades
|
||||
display_name = "Sunglasses, fat (Security/Command)"
|
||||
path = /obj/item/clothing/glasses/sunglasses/big
|
||||
allowed_roles = list("Security Officer","Head of Security","Warden","Colony Director","Head of Personnel","Quartermaster","Internal Affairs Agent","Detective")
|
||||
/datum/gear/eyes/medical/aviator
|
||||
display_name = "Medical HUD Aviators (Medical)"
|
||||
path = /obj/item/clothing/glasses/sunglasses/medhud/aviator
|
||||
|
||||
/datum/gear/eyes/medical/aviator
|
||||
display_name = "Medical HUD Aviators, prescription (Medical)"
|
||||
path = /obj/item/clothing/glasses/sunglasses/medhud/aviator/prescription
|
||||
|
||||
/datum/gear/eyes/meson
|
||||
display_name = "Optical Meson Scanners (Engineering)"
|
||||
path = /obj/item/clothing/glasses/meson
|
||||
allowed_roles = list("Station Engineer","Chief Engineer","Atmospheric Technician")
|
||||
|
||||
/datum/gear/eyes/meson/prescription
|
||||
display_name = "Optical Meson Scanners, prescription (Engineering)"
|
||||
path = /obj/item/clothing/glasses/meson/prescription
|
||||
|
||||
/datum/gear/eyes/meson/aviator
|
||||
display_name = "Optical Meson Aviators, (Engineering)"
|
||||
path = /obj/item/clothing/glasses/meson/aviator
|
||||
|
||||
/datum/gear/eyes/meson/aviator/prescription
|
||||
display_name = "Optical Meson Aviators, prescription (Engineering)"
|
||||
path = /obj/item/clothing/glasses/meson/aviator/prescription
|
||||
|
||||
/datum/gear/eyes/meson/aviator/prescription
|
||||
|
||||
/datum/gear/eyes/glasses/fakesun
|
||||
display_name = "Sunglasses, stylish"
|
||||
@@ -74,7 +94,16 @@
|
||||
display_name = "Sunglasses, stylish aviators"
|
||||
path = /obj/item/clothing/glasses/fakesunglasses/aviator
|
||||
|
||||
/datum/gear/eyes/shades/prescriptionsun
|
||||
/datum/gear/eyes/sun
|
||||
display_name = "Sunglasses (Security/Command)"
|
||||
path = /obj/item/clothing/glasses/sunglasses
|
||||
allowed_roles = list("Security Officer","Head of Security","Warden","Colony Director","Head of Personnel","Quartermaster","Internal Affairs Agent","Detective")
|
||||
|
||||
/datum/gear/eyes/sun/shades
|
||||
display_name = "Sunglasses, fat (Security/Command)"
|
||||
path = /obj/item/clothing/glasses/sunglasses/big
|
||||
|
||||
/datum/gear/eyes/sun/prescriptionsun
|
||||
display_name = "sunglasses, presciption (Security/Command)"
|
||||
path = /obj/item/clothing/glasses/sunglasses/prescription
|
||||
cost = 2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
||||
#define SAVE_RESET -1
|
||||
|
||||
var/list/preferences_datums = list()
|
||||
|
||||
@@ -199,7 +199,8 @@ datum/preferences
|
||||
dat += "Slot - "
|
||||
dat += "<a href='?src=\ref[src];load=1'>Load slot</a> - "
|
||||
dat += "<a href='?src=\ref[src];save=1'>Save slot</a> - "
|
||||
dat += "<a href='?src=\ref[src];reload=1'>Reload slot</a>"
|
||||
dat += "<a href='?src=\ref[src];reload=1'>Reload slot</a> - "
|
||||
dat += "<a href='?src=\ref[src];resetslot=1'>Reset slot</a>"
|
||||
|
||||
else
|
||||
dat += "Please create an account to save your preferences."
|
||||
@@ -248,6 +249,11 @@ datum/preferences
|
||||
load_character(text2num(href_list["changeslot"]))
|
||||
sanitize_preferences()
|
||||
close_load_dialog(usr)
|
||||
else if(href_list["resetslot"])
|
||||
if("No" == alert("This will reset the current slot. Continue?", "Reset current slot?", "No", "Yes"))
|
||||
return 0
|
||||
load_character(SAVE_RESET)
|
||||
sanitize_preferences()
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
@@ -67,11 +67,20 @@
|
||||
if(!S) return 0
|
||||
S.cd = "/"
|
||||
if(!slot) slot = default_slot
|
||||
slot = sanitize_integer(slot, 1, config.character_slots, initial(default_slot))
|
||||
if(slot != default_slot)
|
||||
default_slot = slot
|
||||
S["default_slot"] << slot
|
||||
S.cd = "/character[slot]"
|
||||
if(slot != SAVE_RESET) // SAVE_RESET will reset the slot as though it does not exist, but keep the current slot for saving purposes.
|
||||
slot = sanitize_integer(slot, 1, config.character_slots, initial(default_slot))
|
||||
if(slot != default_slot)
|
||||
default_slot = slot
|
||||
S["default_slot"] << slot
|
||||
else
|
||||
S["default_slot"] << default_slot
|
||||
|
||||
if(slot != SAVE_RESET)
|
||||
S.cd = "/character[slot]"
|
||||
player_setup.load_character(S)
|
||||
else
|
||||
player_setup.load_character(S)
|
||||
S.cd = "/character[default_slot]"
|
||||
|
||||
player_setup.load_character(S)
|
||||
return 1
|
||||
|
||||
@@ -69,6 +69,19 @@ BLIND // can't see anything
|
||||
desc = "Optical Meson Scanner with prescription lenses."
|
||||
prescription = 1
|
||||
|
||||
/obj/item/clothing/glasses/meson/aviator
|
||||
name = "Engineering Aviators"
|
||||
icon_state = "aviator_eng"
|
||||
off_state = "aviator"
|
||||
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
|
||||
action_button_name = "Toggle HUD"
|
||||
activation_sound = 'sound/effects/pop.ogg'
|
||||
|
||||
/obj/item/clothing/glasses/meson/aviator/prescription
|
||||
name = "Prescription Engineering Aviators"
|
||||
desc = "Engineering Aviators with prescription lenses."
|
||||
prescription = 1
|
||||
|
||||
/obj/item/clothing/glasses/science
|
||||
name = "Science Goggles"
|
||||
desc = "The goggles do nothing!"
|
||||
@@ -242,20 +255,20 @@ BLIND // can't see anything
|
||||
icon_state = "bigsunglasses"
|
||||
|
||||
/obj/item/clothing/glasses/fakesunglasses //Sunglasses without flash immunity
|
||||
desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes."
|
||||
name = "stylish sunglasses"
|
||||
desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes."
|
||||
icon_state = "sun"
|
||||
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
|
||||
|
||||
/obj/item/clothing/glasses/fakesunglasses/aviator
|
||||
desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes."
|
||||
name = "stylish aviators"
|
||||
icon_state = "sec_flash"
|
||||
desc = "A pair of designer sunglasses. Doesn't seem like it'll block flashes."
|
||||
icon_state = "aviator"
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/sechud
|
||||
name = "HUDSunglasses"
|
||||
desc = "Sunglasses with a HUD."
|
||||
icon_state = "sunhud"
|
||||
icon_state = "sunSecHud"
|
||||
var/obj/item/clothing/glasses/hud/security/hud = null
|
||||
|
||||
New()
|
||||
@@ -269,10 +282,10 @@ BLIND // can't see anything
|
||||
icon_state = "swatgoggles"
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/sechud/aviator
|
||||
name = "HUD aviators"
|
||||
name = "Security HUD aviators"
|
||||
desc = "Modified aviator glasses that can be switch between HUD and flash protection modes."
|
||||
icon_state = "sec_hud"
|
||||
off_state = "sec_flash"
|
||||
icon_state = "aviator_sec"
|
||||
off_state = "aviator"
|
||||
action_button_name = "Toggle Mode"
|
||||
var/on = 1
|
||||
toggleable = 1
|
||||
@@ -311,10 +324,68 @@ BLIND // can't see anything
|
||||
icon_state = off_state
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/sechud/aviator/prescription
|
||||
name = "Prescription HUD aviators"
|
||||
name = "Prescription Security HUD aviators"
|
||||
desc = "Modified aviator glasses that can be switch between HUD and flash protection modes. Comes with bonus prescription lenses."
|
||||
prescription = 6
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/medhud
|
||||
name = "HUDSunglasses"
|
||||
desc = "Sunglasses with a HUD."
|
||||
icon_state = "sunMedHud"
|
||||
var/obj/item/clothing/glasses/hud/health/hud = null
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/medhud/New()
|
||||
..()
|
||||
src.hud = new/obj/item/clothing/glasses/hud/health(src)
|
||||
return
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/medhud/aviator
|
||||
name = "Medical HUD aviators"
|
||||
desc = "Modified aviator glasses with a toggled health HUD."
|
||||
icon_state = "aviator_med"
|
||||
off_state = "aviator"
|
||||
action_button_name = "Toggle Mode"
|
||||
var/on = 1
|
||||
toggleable = 1
|
||||
activation_sound = 'sound/effects/pop.ogg'
|
||||
|
||||
var/hud_holder
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/medhud/aviator/New()
|
||||
..()
|
||||
hud_holder = hud
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/medhud/aviator/Destroy()
|
||||
qdel(hud_holder)
|
||||
hud_holder = null
|
||||
hud = null
|
||||
. = ..()
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/medhud/aviator/attack_self(mob/user)
|
||||
if(toggleable && !user.incapacitated())
|
||||
on = !on
|
||||
if(on)
|
||||
src.hud = hud_holder
|
||||
to_chat(user, "You switch the [src] to HUD mode.")
|
||||
else
|
||||
src.hud = null
|
||||
to_chat(user, "You switch \the [src] off.")
|
||||
update_icon()
|
||||
user << activation_sound
|
||||
user.update_inv_glasses()
|
||||
user.update_action_buttons()
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/medhud/aviator/update_icon()
|
||||
if(on)
|
||||
icon_state = initial(icon_state)
|
||||
else
|
||||
icon_state = off_state
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/medhud/aviator/prescription
|
||||
name = "Prescription Medical HUD aviators"
|
||||
desc = "Modified aviator glasses with a toggled health HUD. Comes with bonus prescription lenses."
|
||||
prescription = 6
|
||||
|
||||
/obj/item/clothing/glasses/thermal
|
||||
name = "Optical Thermal Scanner"
|
||||
desc = "Thermals in the shape of glasses."
|
||||
|
||||
@@ -92,4 +92,9 @@
|
||||
siemens_coefficient = 0
|
||||
phoronproof = 1
|
||||
permeability_coefficient = 0.05
|
||||
species_restricted = list("Vox")
|
||||
species_restricted = list("Vox")
|
||||
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE
|
||||
heat_protection = HANDS
|
||||
max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
magpulse = 1
|
||||
canremove = 0 //kinda hard to take off magclaws when you are gripping them tightly.
|
||||
to_chat(user, "You dig your claws deeply into the flooring, bracing yourself.")
|
||||
to_chat(user, "It would be hard to take off the [src] without relaxing your grip first.")
|
||||
user.update_action_buttons()
|
||||
|
||||
//In case they somehow come off while enabled.
|
||||
|
||||
@@ -33,17 +33,16 @@
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | PHORONGUARD
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank)
|
||||
slowdown = 1
|
||||
phoronproof = 1
|
||||
armor = list(melee = 60, bullet = 50, laser = 40,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
siemens_coefficient = 0.6
|
||||
siemens_coefficient = 0.2
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
species_restricted = list("Vox")
|
||||
|
||||
/obj/item/clothing/head/helmet/space/vox
|
||||
armor = list(melee = 60, bullet = 50, laser = 40, energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
siemens_coefficient = 0.6
|
||||
siemens_coefficient = 0.2
|
||||
item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | AIRTIGHT | PHORONGUARD
|
||||
flags_inv = 0
|
||||
phoronproof = 1
|
||||
|
||||
@@ -47,9 +47,10 @@
|
||||
icon_state = "vox_rig"
|
||||
armor = list(melee = 60, bullet = 50, laser = 40, energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
item_flags = THICKMATERIAL
|
||||
siemens_coefficient = 0.2
|
||||
phoronproof = 1
|
||||
|
||||
air_type = /obj/item/weapon/tank/phoron/vox
|
||||
air_type = /obj/item/weapon/tank/vox
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/vox
|
||||
boot_type = /obj/item/clothing/shoes/magboots/rig/vox
|
||||
@@ -58,10 +59,15 @@
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/vox
|
||||
species_restricted = list("Vox")
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
phoronproof = 1
|
||||
|
||||
/obj/item/clothing/shoes/magboots/rig/vox
|
||||
name = "talons"
|
||||
species_restricted = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/shoes.dmi'
|
||||
)
|
||||
phoronproof = 1
|
||||
|
||||
/obj/item/clothing/suit/space/rig/vox
|
||||
@@ -69,14 +75,37 @@
|
||||
phoronproof = 1
|
||||
|
||||
/obj/item/clothing/gloves/gauntlets/rig/vox
|
||||
name = "talons"
|
||||
siemens_coefficient = 0
|
||||
species_restricted = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/gloves.dmi'
|
||||
)
|
||||
phoronproof = 1
|
||||
|
||||
/obj/item/weapon/rig/vox/carapace
|
||||
name = "dense alien control module"
|
||||
suit_type = "dense alien"
|
||||
armor = list(melee = 60, bullet = 50, laser = 40, energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
emp_protection = 40 //change this to 30 if too high.
|
||||
phoronproof = 1
|
||||
|
||||
req_access = list(access_syndicate)
|
||||
|
||||
cell_type = /obj/item/weapon/cell/hyper
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/mounted/energy_blade,
|
||||
/obj/item/rig_module/sprinter,
|
||||
/obj/item/rig_module/electrowarfare_suite,
|
||||
/obj/item/rig_module/vision,
|
||||
/obj/item/rig_module/power_sink,
|
||||
/obj/item/rig_module/self_destruct
|
||||
)
|
||||
|
||||
/obj/item/weapon/rig/vox/stealth
|
||||
name = "sinister alien control module"
|
||||
suit_type = "sinister alien"
|
||||
icon_state = "voxstealth_rig"
|
||||
armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 30, bio = 100, rad = 100)
|
||||
emp_protection = 40 //change this to 30 if too high.
|
||||
slowdown = 0
|
||||
@@ -88,6 +117,7 @@
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/stealth_field,
|
||||
/obj/item/rig_module/electrowarfare_suite,
|
||||
/obj/item/rig_module/vision,
|
||||
/obj/item/rig_module/power_sink,
|
||||
/obj/item/rig_module/self_destruct
|
||||
|
||||
@@ -201,6 +201,7 @@
|
||||
req_access = list(access_medical)
|
||||
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/sprinter,
|
||||
/obj/item/rig_module/chem_dispenser/injector,
|
||||
/obj/item/rig_module/maneuvering_jets,
|
||||
/obj/item/rig_module/device/healthscanner,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/obj/item/clothing/under/vox
|
||||
has_sensor = 0
|
||||
species_restricted = list("Vox")
|
||||
valid_accessory_slots = list("vox")
|
||||
restricted_accessory_slots = list("vox")
|
||||
phoronproof = 1
|
||||
|
||||
/obj/item/clothing/under/vox/vox_casual
|
||||
@@ -14,4 +16,18 @@
|
||||
name = "alien robes"
|
||||
desc = "Weird and flowing!"
|
||||
icon_state = "vox-casual-2"
|
||||
item_state = "vox-casual-2"
|
||||
item_state = "vox-casual-2"
|
||||
|
||||
//Vox Accessories
|
||||
/obj/item/clothing/accessory/storage/vox
|
||||
name = "alien mesh"
|
||||
desc = "An alien mesh. Seems to be made up mostly of pockets and writhing flesh."
|
||||
icon_state = "webbing-vox"
|
||||
slot = "vox"
|
||||
|
||||
slots = 5
|
||||
|
||||
/obj/item/clothing/accessory/storage/vox/New()
|
||||
..()
|
||||
hold.max_storage_space = slots * ITEMSIZE_COST_NORMAL
|
||||
hold.max_w_class = ITEMSIZE_NORMAL
|
||||
@@ -52,9 +52,13 @@
|
||||
var/list/reagent_data = seed.chems[rid]
|
||||
if(reagent_data && reagent_data.len)
|
||||
var/rtotal = reagent_data[1]
|
||||
var/list/data = list()
|
||||
if(reagent_data.len > 1 && potency > 0)
|
||||
rtotal += round(potency/reagent_data[2])
|
||||
reagents.add_reagent(rid,max(1,rtotal))
|
||||
if(rid == "nutriment")
|
||||
data[seed.seed_name] = max(1,rtotal)
|
||||
|
||||
reagents.add_reagent(rid,max(1,rtotal),data)
|
||||
update_desc()
|
||||
if(reagents.total_volume > 0)
|
||||
bitesize = 1+round(reagents.total_volume / 2, 1)
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box.
|
||||
#define IC_SPAWN_RESEARCH 2 // If the circuit design will be autogenerated for RnD.
|
||||
|
||||
#define IC_FORMAT_STRING "\<STRING\>"
|
||||
#define IC_FORMAT_NUMBER "\<NUM\>"
|
||||
#define IC_FORMAT_REF "\<REF\>"
|
||||
#define IC_FORMAT_LIST "\<LIST\>"
|
||||
#define IC_FORMAT_ANY "\<ANY\>"
|
||||
#define IC_FORMAT_PULSE "\<PULSE\>"
|
||||
|
||||
var/list/all_integrated_circuits = list()
|
||||
|
||||
/proc/initialize_integrated_circuits_list()
|
||||
@@ -20,377 +27,19 @@ var/list/all_integrated_circuits = list()
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "template"
|
||||
w_class = ITEMSIZE_TINY
|
||||
var/obj/item/device/electronic_assembly/assembly = null // Reference to the assembly holding this circuit, if any.
|
||||
var/extended_desc = null
|
||||
var/list/inputs = list()
|
||||
var/list/outputs = list()
|
||||
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/cooldown_per_use = 1 SECOND
|
||||
var/spawn_flags = null // Used for world initializing, see the #defines above.
|
||||
var/category_text = "NO CATEGORY" // To show up on circuit printer, and perhaps other places.
|
||||
var/autopulse = -1 // When input is received, the circuit will pulse itself if set to 1. 0 means it won't. -1 means it is permanently off.
|
||||
|
||||
/obj/item/integrated_circuit/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "This board has [inputs.len] input pin\s and [outputs.len] output pin\s.")
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
if(I.linked.len)
|
||||
to_chat(user, "The [I] is connected to [I.get_linked_to_desc()].")
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
if(O.linked.len)
|
||||
to_chat(user, "The [O] is connected to [O.get_linked_to_desc()].")
|
||||
for(var/datum/integrated_io/activate/A in activators)
|
||||
if(A.linked.len)
|
||||
to_chat(user, "The [A] is connected to [A.get_linked_to_desc()].")
|
||||
|
||||
interact(user)
|
||||
|
||||
/obj/item/integrated_circuit/New()
|
||||
setup_io(inputs, /datum/integrated_io/input)
|
||||
setup_io(outputs, /datum/integrated_io/output)
|
||||
setup_io(activators, /datum/integrated_io/activate)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type)
|
||||
var/list/io_list_copy = io_list.Copy()
|
||||
io_list.Cut()
|
||||
for(var/io_entry in io_list_copy)
|
||||
io_list.Add(new io_type(src, io_entry, io_list_copy[io_entry]))
|
||||
|
||||
/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()
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
qdel(I)
|
||||
for(var/datum/integrated_io/O in outputs)
|
||||
qdel(O)
|
||||
for(var/datum/integrated_io/A in activators)
|
||||
qdel(A)
|
||||
. = ..()
|
||||
|
||||
/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/datum/integrated_io/io in inputs + outputs + activators)
|
||||
io.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(!CanInteract(M, physical_state))
|
||||
return
|
||||
|
||||
var/input = sanitizeSafe(input("What do you want to name the circuit?", "Rename", src.name) as null|text, MAX_NAME_LEN)
|
||||
if(src && input && CanInteract(M, physical_state))
|
||||
to_chat(M, "<span class='notice'>The circuit '[src.name]' is now labeled '[input]'.</span>")
|
||||
name = input
|
||||
|
||||
/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 null
|
||||
return inputs[pin_number]
|
||||
if(IC_OUTPUT)
|
||||
if(pin_number > outputs.len)
|
||||
return null
|
||||
return outputs[pin_number]
|
||||
if(IC_ACTIVATOR)
|
||||
if(pin_number > activators.len)
|
||||
return null
|
||||
return activators[pin_number]
|
||||
return null
|
||||
|
||||
/obj/item/integrated_circuit/interact(mob/user)
|
||||
if(!CanInteract(user, physical_state))
|
||||
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.name]</title></head><body>"
|
||||
HTML += "<div align='center'>"
|
||||
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 424px'>"
|
||||
|
||||
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];remove=1'>\[Remove\]</a><br>"
|
||||
|
||||
HTML += "<colgroup>"
|
||||
//HTML += "<col style='width: 121px'>"
|
||||
//HTML += "<col style='width: 181px'>"
|
||||
//HTML += "<col style='width: 122px'>"
|
||||
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)
|
||||
if(io.linked.len)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]><b>[io.name] [io.display_data()]</b></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder]</a><br>"
|
||||
else
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>[io.name] [io.display_data()]</a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder]</a><br>"
|
||||
if(outputs.len > inputs.len)
|
||||
height = 1
|
||||
if(2)
|
||||
if(i == 1)
|
||||
words += "[src.name]<br><br>[src.desc]"
|
||||
height = row_height
|
||||
else
|
||||
continue
|
||||
if(3)
|
||||
io = get_pin_ref(IC_OUTPUT, i)
|
||||
if(io)
|
||||
if(io.linked.len)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]><b>[io.name] [io.display_data()]</b></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
else
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>[io.name] [io.display_data()]</a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder]</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()
|
||||
if(io.linked.len)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]><font color='FF0000'><b>[io.name]</b></font></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src[src];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
else
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]><font color='FF0000'>[io.name]</font></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder]</a><br>"
|
||||
HTML += "<tr>"
|
||||
HTML += "<td colspan='3' align='center'>[jointext(words, null)]</td>"
|
||||
HTML += "</tr>"
|
||||
|
||||
HTML += "</table>"
|
||||
HTML += "</div>"
|
||||
|
||||
if(autopulse != -1)
|
||||
HTML += "<br><font color='33CC33'>Meta Variables;</font>"
|
||||
HTML += "<br><font color='33CC33'><a href='?src=\ref[src];autopulse=1'>\[Autopulse\]</a> = <b>[autopulse ? "ON" : "OFF"]</b></font>"
|
||||
HTML += "<br>"
|
||||
|
||||
HTML += "<br><font color='0000AA'>Complexity: [complexity]</font>"
|
||||
HTML += "<br><font color='0000AA'>[extended_desc]</font>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
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, "circuit-\ref[src]")
|
||||
|
||||
/obj/item/integrated_circuit/Topic(href, href_list, state = physical_state)
|
||||
if(..())
|
||||
return 1
|
||||
var/pin = locate(href_list["pin"]) in inputs + outputs + activators
|
||||
|
||||
var/obj/held_item = usr.get_active_hand()
|
||||
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(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"])
|
||||
examine(usr)
|
||||
|
||||
if(href_list["rename"])
|
||||
rename_component(usr)
|
||||
|
||||
if(href_list["autopulse"])
|
||||
if(autopulse != -1)
|
||||
autopulse = !autopulse
|
||||
|
||||
if(href_list["remove"])
|
||||
if(istype(held_item, /obj/item/weapon/screwdriver))
|
||||
disconnect_all()
|
||||
var/turf/T = get_turf(src)
|
||||
forceMove(T)
|
||||
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>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You need a screwdriver to remove components.</span>")
|
||||
var/obj/item/device/electronic_assembly/ea = loc
|
||||
if(istype(ea))
|
||||
ea.interact(usr)
|
||||
return
|
||||
|
||||
interact(usr) // To refresh the UI.
|
||||
|
||||
/datum/integrated_io
|
||||
var/name = "input/output"
|
||||
var/obj/item/integrated_circuit/holder = null
|
||||
var/weakref/data = null // 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(var/newloc, var/name, var/data)
|
||||
..()
|
||||
src.name = name
|
||||
src.data = data
|
||||
holder = newloc
|
||||
if(!istype(holder))
|
||||
message_admins("ERROR: An integrated_io ([src.name]) spawned without a valid holder! This is a bug.")
|
||||
|
||||
/datum/integrated_io/Destroy()
|
||||
disconnect()
|
||||
data = null
|
||||
holder = null
|
||||
. = ..()
|
||||
|
||||
/datum/integrated_io/nano_host()
|
||||
return holder.nano_host()
|
||||
var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'.
|
||||
var/cooldown_per_use = 1 SECOND // 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 = null // 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/autopulse = -1 // When input is received, the circuit will pulse itself if set to 1. 0 means it won't. -1 means it is permanently off.
|
||||
var/removable = TRUE // Determines if a circuit is removable from the assembly.
|
||||
|
||||
|
||||
/datum/integrated_io/proc/data_as_type(var/as_type)
|
||||
if(!isweakref(data))
|
||||
return
|
||||
var/weakref/w = data
|
||||
var/output = w.resolve()
|
||||
return istype(output, as_type) ? output : null
|
||||
|
||||
/datum/integrated_io/proc/display_data()
|
||||
if(isnull(data))
|
||||
return "(null)" // Empty data means nothing to show.
|
||||
if(istext(data))
|
||||
return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'.
|
||||
if(isweakref(data))
|
||||
var/weakref/w = data
|
||||
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 "([data])" // Nothing special needed for numbers or other stuff.
|
||||
|
||||
/datum/integrated_io/activate/display_data()
|
||||
return "(\[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)) // Anything else is a type we don't want.
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/proc/push_data()
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
io.write_data_to_pin(data)
|
||||
|
||||
/datum/integrated_io/activate/push_data()
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
io.holder.check_then_do_work()
|
||||
|
||||
/datum/integrated_io/proc/pull_data()
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
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.
|
||||
for(var/datum/integrated_io/their_io in linked)
|
||||
//While doing that, we iterate them as well, and disconnect ourselves from them.
|
||||
for(var/datum/integrated_io/their_linked_io in their_io.linked)
|
||||
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.
|
||||
src.linked.Remove(their_io)
|
||||
|
||||
/datum/integrated_io/input
|
||||
name = "input pin"
|
||||
|
||||
/datum/integrated_io/output
|
||||
name = "output pin"
|
||||
|
||||
/datum/integrated_io/activate
|
||||
name = "activation pin"
|
||||
io_type = PULSE_CHANNEL
|
||||
|
||||
/obj/item/integrated_circuit/proc/push_data()
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/pull_data()
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/check_then_do_work()
|
||||
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
|
||||
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/datum/integrated_io/input/I in inputs)
|
||||
I.disconnect()
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.disconnect()
|
||||
for(var/datum/integrated_io/activate/A in activators)
|
||||
A.disconnect()
|
||||
@@ -11,6 +11,7 @@
|
||||
var/max_components = IC_COMPONENTS_BASE
|
||||
var/max_complexity = IC_COMPLEXITY_BASE
|
||||
var/opened = 0
|
||||
var/obj/item/weapon/cell/device/battery = null // Internal cell which most circuits need to work.
|
||||
|
||||
/obj/item/device/electronic_assembly/medium
|
||||
name = "electronic mechanism"
|
||||
@@ -23,8 +24,8 @@
|
||||
name = "electronic machine"
|
||||
icon_state = "setup_large"
|
||||
w_class = ITEMSIZE_LARGE
|
||||
max_components = IC_COMPONENTS_BASE * 3
|
||||
max_complexity = IC_COMPLEXITY_BASE * 3
|
||||
max_components = IC_COMPONENTS_BASE * 4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 4
|
||||
|
||||
/obj/item/device/electronic_assembly/drone
|
||||
name = "electronic drone"
|
||||
@@ -41,6 +42,32 @@
|
||||
max_complexity = IC_COMPLEXITY_BASE / 2
|
||||
var/obj/item/weapon/implant/integrated_circuit/implant = null
|
||||
|
||||
/obj/item/device/electronic_assembly/New()
|
||||
..()
|
||||
battery = new(src)
|
||||
processing_objects |= src
|
||||
|
||||
/obj/item/device/electronic_assembly/Destroy()
|
||||
battery = null
|
||||
processing_objects -= src
|
||||
for(var/atom/movable/AM in contents)
|
||||
qdel(AM)
|
||||
..()
|
||||
|
||||
/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/implant/update_icon()
|
||||
..()
|
||||
implant.icon_state = icon_state
|
||||
@@ -70,13 +97,18 @@
|
||||
HTML += "<br><a href='?src=\ref[src]'>\[Refresh\]</a> | "
|
||||
HTML += "<a href='?src=\ref[src];rename=1'>\[Rename\]</a><br>"
|
||||
HTML += "[total_parts]/[max_components] ([round((total_parts / 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."
|
||||
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;<br>"
|
||||
for(var/obj/item/integrated_circuit/circuit in contents)
|
||||
HTML += "<a href=?src=\ref[circuit];examine=1>[circuit.name]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];rename=1>\[Rename\]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];remove=1>\[Remove\]</a>"
|
||||
if(circuit.removable)
|
||||
HTML += "<a href=?src=\ref[circuit];remove=1>\[Remove\]</a>"
|
||||
HTML += "<br>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
@@ -89,6 +121,16 @@
|
||||
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/verb/rename()
|
||||
@@ -117,39 +159,84 @@
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/device/electronic_assembly/GetAccess()
|
||||
. = list()
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
. |= part.GetAccess()
|
||||
|
||||
/obj/item/device/electronic_assembly/GetIdCard()
|
||||
. = list()
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
var/id_card = part.GetIdCard()
|
||||
if(id_card)
|
||||
return id_card
|
||||
|
||||
/obj/item/device/electronic_assembly/examine(mob/user)
|
||||
. = ..(user, 1)
|
||||
if(.)
|
||||
for(var/obj/item/integrated_circuit/output/screen/S in contents)
|
||||
if(S.stuff_to_display)
|
||||
to_chat(user, "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'.")
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
IC.external_examine(user)
|
||||
// for(var/obj/item/integrated_circuit/output/screen/S in contents)
|
||||
// if(S.stuff_to_display)
|
||||
// to_chat(user, "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'.")
|
||||
if(opened)
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/get_part_complexity()
|
||||
. = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
. += part.complexity
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/get_part_size()
|
||||
. = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
. += part.w_class
|
||||
|
||||
// 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 > src.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 = get_part_size()
|
||||
var/total_complexity = get_part_complexity()
|
||||
|
||||
if((total_part_size + IC.w_class) > max_components)
|
||||
to_chat(user, "<span class='warning'>You can't seem to add the '[IC.name]', 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.name]', since this setup's too complicated for the case.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!IC.forceMove(src))
|
||||
return FALSE
|
||||
|
||||
IC.assembly = src
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity)
|
||||
if(proximity)
|
||||
var/scanned = FALSE
|
||||
for(var/obj/item/integrated_circuit/input/sensor/S in contents)
|
||||
S.set_pin_data(IC_OUTPUT, 1, weakref(target))
|
||||
S.check_then_do_work()
|
||||
scanned = TRUE
|
||||
if(scanned)
|
||||
visible_message("<span class='notice'>\The [user] waves \the [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(!opened)
|
||||
to_chat(user, "<span class='warning'>\The [src] isn't opened, so you can't put anything inside. Try using a crowbar.</span>")
|
||||
if(!user.unEquip(I))
|
||||
return 0
|
||||
var/obj/item/integrated_circuit/IC = I
|
||||
var/total_parts = 0
|
||||
var/total_complexity = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
total_parts++
|
||||
total_complexity = total_complexity + part.complexity
|
||||
|
||||
if( (total_parts + 1) > max_components)
|
||||
to_chat(user, "<span class='warning'>You can't seem to add this [IC.name], since there's no more room.</span>")
|
||||
return 0
|
||||
if( (total_complexity + IC.complexity) > max_complexity)
|
||||
to_chat(user, "<span class='warning'>You can't seem to add this [IC.name], since this setup's too complicated for the case.</span>")
|
||||
return 0
|
||||
|
||||
to_chat(user, "<span class='notice'>You slide \the [IC] inside \the [src].</span>")
|
||||
user.drop_item()
|
||||
IC.forceMove(src)
|
||||
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
interact(user)
|
||||
if(add_circuit(I, user))
|
||||
to_chat(user, "<span class='notice'>You slide \the [I] inside \the [src].</span>")
|
||||
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
interact(user)
|
||||
else if(istype(I, /obj/item/weapon/crowbar))
|
||||
playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
|
||||
opened = !opened
|
||||
@@ -161,6 +248,21 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] isn't opened, so you can't fiddle with the internal components. \
|
||||
Try using a crowbar.</span>")
|
||||
else if(istype(I, /obj/item/weapon/cell/device))
|
||||
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(battery)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has \a [battery] inside. Remove it first if you want to replace it.</span>")
|
||||
return FALSE
|
||||
var/obj/item/weapon/cell/device/cell = I
|
||||
user.drop_item(cell)
|
||||
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)
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -179,4 +281,16 @@
|
||||
/obj/item/device/electronic_assembly/emp_act(severity)
|
||||
..()
|
||||
for(var/atom/movable/AM in contents)
|
||||
AM.emp_act(severity)
|
||||
AM.emp_act(severity)
|
||||
|
||||
// Returns true if power was successfully drawn.
|
||||
/obj/item/device/electronic_assembly/proc/draw_power(amount)
|
||||
if(battery && battery.checked_use(amount * CELLRATE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// Ditto for giving.
|
||||
/obj/item/device/electronic_assembly/proc/give_power(amount)
|
||||
if(battery && battery.give(amount * CELLRATE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
44
code/modules/integrated_electronics/core/helpers.dm
Normal file
44
code/modules/integrated_electronics/core/helpers.dm
Normal file
@@ -0,0 +1,44 @@
|
||||
/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type)
|
||||
var/list/io_list_copy = io_list.Copy()
|
||||
io_list.Cut()
|
||||
for(var/io_entry in io_list_copy)
|
||||
io_list.Add(new io_type(src, io_entry, io_list_copy[io_entry]))
|
||||
|
||||
/obj/item/integrated_circuit/proc/set_pin_data(var/pin_type, var/pin_number, var/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(isnull(data))
|
||||
return
|
||||
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 null
|
||||
return inputs[pin_number]
|
||||
if(IC_OUTPUT)
|
||||
if(pin_number > outputs.len)
|
||||
return null
|
||||
return outputs[pin_number]
|
||||
if(IC_ACTIVATOR)
|
||||
if(pin_number > activators.len)
|
||||
return null
|
||||
return activators[pin_number]
|
||||
return null
|
||||
282
code/modules/integrated_electronics/core/integrated_circuit.dm
Normal file
282
code/modules/integrated_electronics/core/integrated_circuit.dm
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
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)
|
||||
. = ..()
|
||||
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/datum/integrated_io/input/I in inputs)
|
||||
if(I.linked.len)
|
||||
to_chat(user, "The '[I]' is connected to [I.get_linked_to_desc()].")
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
if(O.linked.len)
|
||||
to_chat(user, "The '[O]' is connected to [O.get_linked_to_desc()].")
|
||||
for(var/datum/integrated_io/activate/A in activators)
|
||||
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/New()
|
||||
setup_io(inputs, /datum/integrated_io/input)
|
||||
setup_io(outputs, /datum/integrated_io/output)
|
||||
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()
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
qdel(I)
|
||||
for(var/datum/integrated_io/O in outputs)
|
||||
qdel(O)
|
||||
for(var/datum/integrated_io/A in activators)
|
||||
qdel(A)
|
||||
. = ..()
|
||||
|
||||
/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/datum/integrated_io/io in inputs + outputs + activators)
|
||||
io.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(!CanInteract(M, physical_state))
|
||||
return
|
||||
|
||||
var/input = sanitizeSafe(input("What do you want to name the circuit?", "Rename", src.name) as null|text, MAX_NAME_LEN)
|
||||
if(src && input && CanInteract(M, physical_state))
|
||||
to_chat(M, "<span class='notice'>The circuit '[src.name]' is now labeled '[input]'.</span>")
|
||||
name = input
|
||||
|
||||
/obj/item/integrated_circuit/interact(mob/user)
|
||||
if(!CanInteract(user, physical_state))
|
||||
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.name]</title></head><body>"
|
||||
HTML += "<div align='center'>"
|
||||
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 424px'>"
|
||||
|
||||
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];remove=1'>\[Remove\]</a><br>"
|
||||
|
||||
HTML += "<colgroup>"
|
||||
//HTML += "<col style='width: 121px'>"
|
||||
//HTML += "<col style='width: 181px'>"
|
||||
//HTML += "<col style='width: 122px'>"
|
||||
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)
|
||||
if(io.linked.len)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]><b>[io.name] [io.display_data()]</b></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder]</a><br>"
|
||||
else
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>[io.name] [io.display_data()]</a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder]</a><br>"
|
||||
if(outputs.len > inputs.len)
|
||||
height = 1
|
||||
if(2)
|
||||
if(i == 1)
|
||||
words += "[src.name]<br><br>[src.desc]"
|
||||
height = row_height
|
||||
else
|
||||
continue
|
||||
if(3)
|
||||
io = get_pin_ref(IC_OUTPUT, i)
|
||||
if(io)
|
||||
if(io.linked.len)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]><b>[io.name] [io.display_data()]</b></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
else
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>[io.name] [io.display_data()]</a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder]</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()
|
||||
if(io.linked.len)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]><font color='FF0000'><b>[io.name]</b></font></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src[src];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
else
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]><font color='FF0000'>[io.name]</font></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder]</a><br>"
|
||||
HTML += "<tr>"
|
||||
HTML += "<td colspan='3' align='center'>[jointext(words, null)]</td>"
|
||||
HTML += "</tr>"
|
||||
|
||||
HTML += "</table>"
|
||||
HTML += "</div>"
|
||||
|
||||
if(autopulse != -1)
|
||||
HTML += "<br><font color='33CC33'>Meta Variables;</font>"
|
||||
HTML += "<br><font color='33CC33'><a href='?src=\ref[src];autopulse=1'>\[Autopulse\]</a> = <b>[autopulse ? "ON" : "OFF"]</b></font>"
|
||||
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>"
|
||||
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, "circuit-\ref[src]")
|
||||
|
||||
/obj/item/integrated_circuit/Topic(href, href_list, state = physical_state)
|
||||
if(..())
|
||||
return 1
|
||||
var/pin = locate(href_list["pin"]) in inputs + outputs + activators
|
||||
|
||||
var/obj/held_item = usr.get_active_hand()
|
||||
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(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"])
|
||||
examine(usr)
|
||||
|
||||
if(href_list["rename"])
|
||||
rename_component(usr)
|
||||
|
||||
if(href_list["autopulse"])
|
||||
if(autopulse != -1)
|
||||
autopulse = !autopulse
|
||||
|
||||
if(href_list["remove"])
|
||||
if(istype(held_item, /obj/item/weapon/screwdriver))
|
||||
if(!removable)
|
||||
to_chat(usr, "<span class='warning'>\The [src] seems to be permanently attached to the case.</span>")
|
||||
return
|
||||
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>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You need a screwdriver to remove components.</span>")
|
||||
var/obj/item/device/electronic_assembly/ea = loc
|
||||
if(istype(ea))
|
||||
ea.interact(usr)
|
||||
return
|
||||
|
||||
interact(usr) // To refresh the UI.
|
||||
|
||||
/obj/item/integrated_circuit/proc/push_data()
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/pull_data()
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
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()
|
||||
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
|
||||
return
|
||||
if(power_draw_per_use)
|
||||
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/datum/integrated_io/input/I in inputs)
|
||||
I.disconnect()
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.disconnect()
|
||||
for(var/datum/integrated_io/activate/A in activators)
|
||||
A.disconnect()
|
||||
139
code/modules/integrated_electronics/core/pins.dm
Normal file
139
code/modules/integrated_electronics/core/pins.dm
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
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 = null
|
||||
var/weakref/data = null // 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(var/newloc, var/name, var/data)
|
||||
..()
|
||||
src.name = name
|
||||
src.data = data
|
||||
holder = newloc
|
||||
if(!istype(holder))
|
||||
message_admins("ERROR: An integrated_io ([src.name]) spawned without a valid holder! This is a bug.")
|
||||
|
||||
/datum/integrated_io/Destroy()
|
||||
disconnect()
|
||||
data = null
|
||||
holder = null
|
||||
. = ..()
|
||||
|
||||
/datum/integrated_io/nano_host()
|
||||
return holder.nano_host()
|
||||
|
||||
|
||||
/datum/integrated_io/proc/data_as_type(var/as_type)
|
||||
if(!isweakref(data))
|
||||
return
|
||||
var/weakref/w = data
|
||||
var/output = w.resolve()
|
||||
return istype(output, as_type) ? output : null
|
||||
|
||||
/datum/integrated_io/proc/display_data()
|
||||
if(isnull(data))
|
||||
return "(null)" // Empty data means nothing to show.
|
||||
if(istext(data))
|
||||
return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'.
|
||||
if(isweakref(data))
|
||||
var/weakref/w = data
|
||||
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 "([data])" // 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)) // Anything else is a type we don't want.
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/proc/push_data()
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
io.write_data_to_pin(data)
|
||||
|
||||
/datum/integrated_io/activate/push_data()
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
io.holder.check_then_do_work()
|
||||
|
||||
/datum/integrated_io/proc/pull_data()
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
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.
|
||||
for(var/datum/integrated_io/their_io in linked)
|
||||
//While doing that, we iterate them as well, and disconnect ourselves from them.
|
||||
for(var/datum/integrated_io/their_linked_io in their_io.linked)
|
||||
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.
|
||||
src.linked.Remove(their_io)
|
||||
|
||||
/datum/integrated_io/input
|
||||
name = "input pin"
|
||||
|
||||
/datum/integrated_io/output
|
||||
name = "output pin"
|
||||
|
||||
/datum/integrated_io/activate
|
||||
name = "activation pin"
|
||||
io_type = PULSE_CHANNEL
|
||||
|
||||
/datum/integrated_io/list
|
||||
name = "list pin"
|
||||
|
||||
/datum/integrated_io/list/write_data_to_pin(var/new_data)
|
||||
if(islist(new_data))
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/list/display_pin_type()
|
||||
return IC_FORMAT_LIST
|
||||
@@ -20,6 +20,9 @@
|
||||
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>")
|
||||
@@ -33,6 +36,9 @@
|
||||
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
|
||||
|
||||
@@ -191,6 +197,7 @@
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/reagents(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/transfer(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/converter(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/power(src)
|
||||
|
||||
new /obj/item/device/electronic_assembly(src)
|
||||
new /obj/item/device/integrated_electronics/wirer(src)
|
||||
@@ -202,11 +209,24 @@
|
||||
/obj/item/weapon/storage/bag/circuits/all/New()
|
||||
..()
|
||||
spawn(2 SECONDS) // So the list has time to initialize.
|
||||
for(var/obj/item/integrated_circuit/IC in all_integrated_circuits)
|
||||
for(var/i = 1 to 10)
|
||||
new IC.type(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/arithmetic/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/trig/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/input/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/output/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/memory/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/logic/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/smart/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/manipulation/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/time/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/reagents/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/transfer/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/converter/all(src)
|
||||
new /obj/item/weapon/storage/bag/circuits/mini/power/all(src)
|
||||
|
||||
new /obj/item/device/electronic_assembly(src)
|
||||
new /obj/item/device/electronic_assembly/medium(src)
|
||||
new /obj/item/device/electronic_assembly/large(src)
|
||||
new /obj/item/device/electronic_assembly/drone(src)
|
||||
new /obj/item/device/integrated_electronics/wirer(src)
|
||||
new /obj/item/device/integrated_electronics/debugger(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
@@ -219,16 +239,20 @@
|
||||
w_class = 2
|
||||
display_contents_with_number = 1
|
||||
can_hold = list(/obj/item/integrated_circuit)
|
||||
var/spawn_flags_to_use = IC_SPAWN_DEFAULT
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/arithmetic
|
||||
name = "arithmetic circuit box"
|
||||
desc = "Warning: Contains math."
|
||||
icon_state = "box_arithmetic"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/arithmetic/all // Don't believe this will ever be needed.
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/arithmetic/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/arithmetic/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
@@ -239,10 +263,13 @@
|
||||
desc = "Danger: Contains more math."
|
||||
icon_state = "box_trig"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/trig/all // Ditto
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/trig/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/trig/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
@@ -253,10 +280,13 @@
|
||||
desc = "Tell these circuits everything you know."
|
||||
icon_state = "box_input"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/input/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/input/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/input/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
@@ -267,10 +297,13 @@
|
||||
desc = "Circuits to interface with the world beyond itself."
|
||||
icon_state = "box_output"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/output/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/output/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/output/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
@@ -281,25 +314,30 @@
|
||||
desc = "Machines can be quite forgetful without these."
|
||||
icon_state = "box_memory"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/memory/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/memory/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/memory/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/logic
|
||||
name = "logic circuit box"
|
||||
desc = "May or may not be Turing complete."
|
||||
icon_state = "box_logic"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/logic/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/logic/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/logic/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
@@ -310,10 +348,13 @@
|
||||
desc = "No time machine parts, sadly."
|
||||
icon_state = "box_time"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/time/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/time/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/time/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
@@ -324,10 +365,13 @@
|
||||
desc = "Unlike most electronics, these circuits are supposed to come in contact with liquids."
|
||||
icon_state = "box_reagents"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/reagents/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/reagents/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/reagent/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
@@ -338,10 +382,13 @@
|
||||
desc = "Useful for moving data representing something arbitrary to another arbitrary virtual place."
|
||||
icon_state = "box_transfer"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/transfer/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/transfer/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/transfer/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
@@ -352,10 +399,66 @@
|
||||
desc = "Transform one piece of data to another type of data with these."
|
||||
icon_state = "box_converter"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/converter/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/converter/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/converter/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & IC_SPAWN_DEFAULT)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/smart
|
||||
name = "smart box"
|
||||
desc = "Sentience not included."
|
||||
icon_state = "box_ai"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/smart/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/smart/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/smart/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/manipulation
|
||||
name = "manipulation box"
|
||||
desc = "Make your machines actually useful with these."
|
||||
icon_state = "box_manipulation"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/manipulation/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/manipulation/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/manipulation/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/power
|
||||
name = "power circuit box"
|
||||
desc = "Electronics generally require electricity."
|
||||
icon_state = "box_power"
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/power/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/mini/power/New()
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/passive/power/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
for(var/obj/item/integrated_circuit/power/IC in all_integrated_circuits)
|
||||
if(IC.spawn_flags & spawn_flags_to_use)
|
||||
for(var/i = 1 to 3)
|
||||
new IC.type(src)
|
||||
make_exact_fit()
|
||||
@@ -1,85 +0,0 @@
|
||||
/obj/item/integrated_circuit/transfer
|
||||
category_text = "Data Transfer"
|
||||
autopulse = 1
|
||||
|
||||
/obj/item/integrated_circuit/transfer/on_data_written()
|
||||
if(autopulse == 1)
|
||||
check_then_do_work()
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter
|
||||
name = "splitter"
|
||||
desc = "Splits incoming data into all of the output pins."
|
||||
icon_state = "splitter"
|
||||
complexity = 3
|
||||
inputs = list("data to split")
|
||||
outputs = list("A","B")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter/medium
|
||||
name = "four splitter"
|
||||
icon_state = "splitter4"
|
||||
complexity = 5
|
||||
outputs = list("A","B","C","D")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter/large
|
||||
name = "eight splitter"
|
||||
icon_state = "splitter8"
|
||||
complexity = 9
|
||||
outputs = list("A","B","C","D","E","F","G","H")
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = I.data
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter
|
||||
name = "activator splitter"
|
||||
desc = "Splits incoming activation pulses into all of the output pins."
|
||||
icon_state = "splitter"
|
||||
complexity = 3
|
||||
activators = list(
|
||||
"incoming pulse",
|
||||
"outgoing pulse A",
|
||||
"outgoing pulse B"
|
||||
)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter/do_work()
|
||||
for(var/datum/integrated_io/activate/A in outputs)
|
||||
if(A == activators[1])
|
||||
continue
|
||||
if(A.linked.len)
|
||||
for(var/datum/integrated_io/activate/target in A.linked)
|
||||
target.holder.check_then_do_work()
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter/medium
|
||||
name = "four activator splitter"
|
||||
icon_state = "splitter4"
|
||||
complexity = 5
|
||||
activators = list(
|
||||
"incoming pulse",
|
||||
"outgoing pulse A",
|
||||
"outgoing pulse B",
|
||||
"outgoing pulse C",
|
||||
"outgoing pulse D"
|
||||
)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter/large
|
||||
name = "eight activator splitter"
|
||||
icon_state = "splitter4"
|
||||
complexity = 9
|
||||
activators = list(
|
||||
"incoming pulse",
|
||||
"outgoing pulse A",
|
||||
"outgoing pulse B",
|
||||
"outgoing pulse C",
|
||||
"outgoing pulse D",
|
||||
"outgoing pulse E",
|
||||
"outgoing pulse F",
|
||||
"outgoing pulse G",
|
||||
"outgoing pulse H"
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
7
code/modules/integrated_electronics/passive/passive.dm
Normal file
7
code/modules/integrated_electronics/passive/passive.dm
Normal file
@@ -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
|
||||
109
code/modules/integrated_electronics/passive/power.dm
Normal file
109
code/modules/integrated_electronics/passive/power.dm
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
/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 = 1
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/solar_cell/make_energy()
|
||||
var/atom/movable/lighting_overlay/light = locate(/atom/movable/lighting_overlay) in get_turf(src)
|
||||
var/light_amount = 1 // Unsimulated tiles are pretend-lit, so we need to be pretend too if that somehow happens.
|
||||
if(light)
|
||||
light_amount = (light.lum_r + light.lum_g + light.lum_b) / 3
|
||||
|
||||
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)
|
||||
|
||||
// For implants.
|
||||
/obj/item/integrated_circuit/passive/power/metabolic_siphon
|
||||
name = "metabolic siphon"
|
||||
desc = "A complicated piece of technology which converts bodily nutriments of a host into electricity."
|
||||
extended_desc = "The siphon generates 10W of energy, so long as the siphon exists inside a biological entity. The entity will feel an increased \
|
||||
appetite and will need to eat more often due to this. This device will fail if used inside synthetic entities."
|
||||
icon_state = "setup_implant"
|
||||
complexity = 10
|
||||
origin_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_BIO = 5)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/metabolic_siphon/proc/test_validity(var/mob/living/carbon/human/host)
|
||||
if(!host || host.isSynthetic() || host.stat == DEAD || host.nutrition <= 10)
|
||||
return FALSE // Robots and dead people don't have a metabolism.
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/metabolic_siphon/make_energy()
|
||||
var/mob/living/carbon/human/host = null
|
||||
if(assembly && istype(assembly, /obj/item/device/electronic_assembly/implant))
|
||||
var/obj/item/device/electronic_assembly/implant/implant_assembly = assembly
|
||||
if(implant_assembly.implant.imp_in)
|
||||
host = implant_assembly.implant.imp_in
|
||||
if(host && test_validity(host))
|
||||
assembly.give_power(10)
|
||||
host.nutrition = max(host.nutrition - DEFAULT_HUNGER_FACTOR, 0)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/metabolic_siphon/synthetic
|
||||
name = "internal energy siphon"
|
||||
desc = "A small circuit designed to be connected to an internal power wire inside a synthetic entity."
|
||||
extended_desc = "The siphon generates 10W of energy, so long as the siphon exists inside a synthetic entity. The entity need to recharge \
|
||||
more often due to this. This device will fail if used inside organic entities."
|
||||
icon_state = "setup_implant"
|
||||
complexity = 10
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 4, TECH_DATA = 3)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/metabolic_siphon/synthetic/test_validity(var/mob/living/carbon/human/host)
|
||||
if(!host || !host.isSynthetic() || host.stat == DEAD || host.nutrition <= 10)
|
||||
return FALSE // This time we don't want a metabolism.
|
||||
return TRUE
|
||||
|
||||
// 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 = ITEMSIZE_NORMAL
|
||||
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 = 250
|
||||
|
||||
// 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 = ITEMSIZE_LARGE
|
||||
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 = 2000
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/relay/make_energy()
|
||||
if(!assembly)
|
||||
return
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
if(A.powered(EQUIP))
|
||||
A.use_power(power_amount, EQUIP)
|
||||
assembly.give_power(power_amount) // give_power() handles CELLRATE on its own.
|
||||
@@ -6,6 +6,7 @@
|
||||
activators = list("compute")
|
||||
category_text = "Arithmetic"
|
||||
autopulse = 1
|
||||
power_draw_per_use = 5 // Math is pretty cheap.
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/on_data_written()
|
||||
if(autopulse == 1)
|
||||
@@ -6,6 +6,7 @@
|
||||
activators = list("convert")
|
||||
category_text = "Converter"
|
||||
autopulse = 1
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/converter/on_data_written()
|
||||
if(autopulse == 1)
|
||||
186
code/modules/integrated_electronics/subtypes/data_transfer.dm
Normal file
186
code/modules/integrated_electronics/subtypes/data_transfer.dm
Normal file
@@ -0,0 +1,186 @@
|
||||
/obj/item/integrated_circuit/transfer
|
||||
category_text = "Data Transfer"
|
||||
autopulse = 1
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/on_data_written()
|
||||
if(autopulse == 1)
|
||||
check_then_do_work()
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter
|
||||
name = "splitter"
|
||||
desc = "Splits incoming data into all of the output pins."
|
||||
icon_state = "splitter"
|
||||
complexity = 3
|
||||
inputs = list("data to split")
|
||||
outputs = list("A","B")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter/medium
|
||||
name = "four splitter"
|
||||
icon_state = "splitter4"
|
||||
complexity = 5
|
||||
outputs = list("A","B","C","D")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter/large
|
||||
name = "eight splitter"
|
||||
icon_state = "splitter8"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
complexity = 9
|
||||
outputs = list("A","B","C","D","E","F","G","H")
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 8
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = I.data
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter
|
||||
name = "activator splitter"
|
||||
desc = "Splits incoming activation pulses into all of the output pins."
|
||||
icon_state = "splitter"
|
||||
complexity = 3
|
||||
activators = list(
|
||||
"incoming pulse",
|
||||
"outgoing pulse A",
|
||||
"outgoing pulse B"
|
||||
)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter/do_work()
|
||||
for(var/datum/integrated_io/activate/A in outputs)
|
||||
if(A == activators[1])
|
||||
continue
|
||||
if(A.linked.len)
|
||||
for(var/datum/integrated_io/activate/target in A.linked)
|
||||
target.holder.check_then_do_work()
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter/medium
|
||||
name = "four activator splitter"
|
||||
icon_state = "splitter4"
|
||||
complexity = 5
|
||||
activators = list(
|
||||
"incoming pulse",
|
||||
"outgoing pulse A",
|
||||
"outgoing pulse B",
|
||||
"outgoing pulse C",
|
||||
"outgoing pulse D"
|
||||
)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter/large
|
||||
name = "eight activator splitter"
|
||||
icon_state = "splitter4"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
complexity = 9
|
||||
activators = list(
|
||||
"incoming pulse",
|
||||
"outgoing pulse A",
|
||||
"outgoing pulse B",
|
||||
"outgoing pulse C",
|
||||
"outgoing pulse D",
|
||||
"outgoing pulse E",
|
||||
"outgoing pulse F",
|
||||
"outgoing pulse G",
|
||||
"outgoing pulse H"
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 8
|
||||
|
||||
|
||||
/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")
|
||||
outputs = list("output")
|
||||
activators = list("select")
|
||||
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]"
|
||||
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)
|
||||
var/output = null
|
||||
|
||||
if(isnum(input_index) && (input_index >= 1 && input_index < inputs.len))
|
||||
output = get_pin_data(IC_INPUT, input_index + 1)
|
||||
set_pin_data(IC_OUTPUT, 1, output)
|
||||
|
||||
/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 = ITEMSIZE_SMALL
|
||||
icon_state = "mux8"
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/huge
|
||||
name = "sixteen multiplexer"
|
||||
icon_state = "mux16"
|
||||
w_class = ITEMSIZE_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","input")
|
||||
outputs = list()
|
||||
activators = list("select")
|
||||
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]"
|
||||
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)
|
||||
var/output = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
for(var/i = 1 to outputs.len)
|
||||
set_pin_data(IC_OUTPUT, i, i == output_index ? output : null)
|
||||
|
||||
/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 = ITEMSIZE_SMALL
|
||||
number_of_outputs = 8
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/huge
|
||||
name = "sixteen demultiplexer"
|
||||
icon_state = "dmux16"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
number_of_outputs = 16
|
||||
@@ -1,6 +1,7 @@
|
||||
/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
|
||||
@@ -23,6 +24,21 @@
|
||||
target.holder.check_then_do_work()
|
||||
to_chat(user, "<span class='notice'>You press the button labeled '[src.name]'.</span>")
|
||||
|
||||
/obj/item/integrated_circuit/input/toggle_button
|
||||
name = "toggle button"
|
||||
desc = "It toggles on, off, on, off..."
|
||||
icon_state = "toggle_button"
|
||||
complexity = 1
|
||||
inputs = list()
|
||||
outputs = list("on" = 0)
|
||||
activators = list("on toggle")
|
||||
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))
|
||||
activate_pin(1)
|
||||
to_chat(user, "<span class='notice'>You toggle the button labeled '[src.name]' [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."
|
||||
@@ -33,6 +49,7 @@
|
||||
outputs = list("number entered")
|
||||
activators = list("on entered")
|
||||
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
|
||||
@@ -53,6 +70,7 @@
|
||||
outputs = list("string entered")
|
||||
activators = list("on entered")
|
||||
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
|
||||
@@ -73,6 +91,7 @@
|
||||
activators = list("scan")
|
||||
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/datum/integrated_io/I = inputs[1]
|
||||
@@ -111,6 +130,7 @@
|
||||
activators = list("scan")
|
||||
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/datum/integrated_io/I = inputs[1]
|
||||
@@ -148,12 +168,12 @@
|
||||
outputs = list("located ref")
|
||||
activators = list("locate")
|
||||
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(istype(src.loc, /obj/item/device/electronic_assembly)) // Check to make sure we're actually in a machine.
|
||||
var/obj/item/device/electronic_assembly/assembly = src.loc
|
||||
if(assembly)
|
||||
if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us.
|
||||
O.data = weakref(assembly.loc)
|
||||
|
||||
@@ -170,6 +190,7 @@
|
||||
outputs = list("located ref")
|
||||
activators = list("locate")
|
||||
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]
|
||||
@@ -205,7 +226,9 @@
|
||||
outputs = list()
|
||||
activators = list("send signal","on signal received")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2)
|
||||
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
|
||||
@@ -287,7 +310,8 @@
|
||||
outputs = list("address received", "data received", "secondary text received")
|
||||
activators = list("send data", "on data received")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2, TECH_BLUESPACE = 2)
|
||||
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()
|
||||
@@ -334,6 +358,7 @@
|
||||
outputs = list("X (abs)", "Y (abs)")
|
||||
activators = list("get coordinates")
|
||||
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)
|
||||
@@ -361,6 +386,7 @@
|
||||
outputs = list("speaker \<String\>", "message \<String\>")
|
||||
activators = list("on message received")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 15
|
||||
|
||||
/obj/item/integrated_circuit/input/microphone/New()
|
||||
..()
|
||||
@@ -385,9 +411,27 @@
|
||||
for(var/datum/integrated_io/output/out in outputs)
|
||||
out.push_data()
|
||||
|
||||
A.push_data()
|
||||
|
||||
|
||||
|
||||
/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."
|
||||
icon_state = "recorder"
|
||||
complexity = 12
|
||||
inputs = list()
|
||||
outputs = list("scanned ref \<Ref\>")
|
||||
activators = list("on scanned")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 120
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/do_work()
|
||||
// Because this gets called by attack(), all this needs to do is pulse the activator.
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.push_data()
|
||||
var/datum/integrated_io/activate/A = activators[1]
|
||||
A.push_data()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/output
|
||||
@@ -401,8 +445,18 @@
|
||||
outputs = list()
|
||||
activators = list("load data")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 10
|
||||
autopulse = 1
|
||||
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 [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))
|
||||
@@ -416,22 +470,24 @@
|
||||
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 = istype(loc, /obj/item/device/electronic_assembly) ? loc : src
|
||||
visible_message("<span class='notice'>\icon[O] [stuff_to_display]</span>")
|
||||
var/obj/O = assembly ? assembly : src
|
||||
to_chat(M, "<span class='notice'>\icon[O] [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 = istype(loc, /obj/item/device/electronic_assembly) ? loc : src
|
||||
var/obj/O = assembly ? loc : assembly
|
||||
O.visible_message("<span class='notice'>\icon[O] [stuff_to_display]</span>")
|
||||
|
||||
/obj/item/integrated_circuit/output/light
|
||||
@@ -446,6 +502,10 @@
|
||||
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/Destroy()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/output/light/do_work()
|
||||
light_toggled = !light_toggled
|
||||
@@ -456,6 +516,7 @@
|
||||
set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb)
|
||||
else
|
||||
set_light(0)
|
||||
power_draw_idle = light_toggled ? light_brightness * 2 : 0
|
||||
|
||||
/obj/item/integrated_circuit/output/light/advanced/update_lighting()
|
||||
var/datum/integrated_io/R = inputs[1]
|
||||
@@ -473,6 +534,10 @@
|
||||
|
||||
..()
|
||||
|
||||
/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."
|
||||
@@ -504,6 +569,7 @@
|
||||
)
|
||||
outputs = list()
|
||||
activators = list("play sound")
|
||||
power_draw_per_use = 20
|
||||
var/list/sounds = list()
|
||||
|
||||
/obj/item/integrated_circuit/output/text_to_speech
|
||||
@@ -517,11 +583,12 @@
|
||||
outputs = list()
|
||||
activators = list("to speech")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 60
|
||||
|
||||
/obj/item/integrated_circuit/output/text_to_speech/do_work()
|
||||
var/datum/integrated_io/text = inputs[1]
|
||||
if(istext(text.data))
|
||||
var/obj/O = istype(loc, /obj/item/device/electronic_assembly) ? loc : src
|
||||
var/obj/O = assembly ? loc : assembly
|
||||
audible_message("\icon[O] \The [O.name] states, \"[text.data]\"")
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/New()
|
||||
@@ -576,4 +643,118 @@
|
||||
"secure day" = 'sound/voice/bsecureday.ogg',
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1)
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 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 = ITEMSIZE_SMALL
|
||||
complexity = 10
|
||||
inputs = list("camera name" = "video camera circuit", "camera active" = 0)
|
||||
outputs = list()
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_idle = 5 // Raises to 80 when on.
|
||||
var/obj/machinery/camera/network/research/camera
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/New()
|
||||
..()
|
||||
camera = new(src)
|
||||
on_data_written()
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/Destroy()
|
||||
qdel(camera)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/proc/set_camera_status(var/status)
|
||||
if(camera)
|
||||
camera.set_status(status)
|
||||
power_draw_idle = camera.status ? 80 : 5
|
||||
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/datum/integrated_io/cam_name = inputs[1]
|
||||
var/datum/integrated_io/cam_active = inputs[2]
|
||||
if(istext(cam_name.data))
|
||||
camera.c_tag = cam_name.data
|
||||
if(isnum(cam_active.data))
|
||||
set_camera_status(cam_active.data)
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/power_fail()
|
||||
if(camera)
|
||||
set_camera_status(0)
|
||||
var/datum/integrated_io/cam_active = inputs[2]
|
||||
cam_active.data = 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")
|
||||
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/any_examine(mob/user)
|
||||
var/text_output = list()
|
||||
var/initial_name = initial(name)
|
||||
|
||||
// Doing all this work just to have a color-blind friendly output.
|
||||
text_output += "There is "
|
||||
if(name == initial_name)
|
||||
text_output += "\an [name]"
|
||||
else
|
||||
text_output += "\an ["\improper[initial_name]"] labeled '[name]'"
|
||||
text_output += " which is currently [get_pin_data(IC_INPUT, 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 = COLOR_RED
|
||||
|
||||
/obj/item/integrated_circuit/output/led/orange
|
||||
name = "orange LED"
|
||||
led_color = COLOR_ORANGE
|
||||
|
||||
/obj/item/integrated_circuit/output/led/yellow
|
||||
name = "yellow LED"
|
||||
led_color = COLOR_YELLOW
|
||||
|
||||
/obj/item/integrated_circuit/output/led/green
|
||||
name = "green LED"
|
||||
led_color = COLOR_GREEN
|
||||
|
||||
/obj/item/integrated_circuit/output/led/blue
|
||||
name = "blue LED"
|
||||
led_color = COLOR_BLUE
|
||||
|
||||
/obj/item/integrated_circuit/output/led/purple
|
||||
name = "purple LED"
|
||||
led_color = COLOR_PURPLE
|
||||
|
||||
/obj/item/integrated_circuit/output/led/cyan
|
||||
name = "cyan LED"
|
||||
led_color = COLOR_CYAN
|
||||
|
||||
/obj/item/integrated_circuit/output/led/white
|
||||
name = "white LED"
|
||||
led_color = COLOR_WHITE
|
||||
|
||||
/obj/item/integrated_circuit/output/led/pink
|
||||
name = "pink LED"
|
||||
led_color = COLOR_PINK
|
||||
@@ -4,9 +4,10 @@
|
||||
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", "on true result")
|
||||
activators = list("compare", "on true result", "on false result")
|
||||
category_text = "Logic"
|
||||
autopulse = 1
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/logic/on_data_written()
|
||||
if(autopulse == 1)
|
||||
@@ -14,10 +15,13 @@
|
||||
|
||||
/obj/item/integrated_circuit/logic/do_work()
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
var/datum/integrated_io/P = activators[2]
|
||||
var/datum/integrated_io/T = activators[2]
|
||||
var/datum/integrated_io/F = activators[3]
|
||||
O.push_data()
|
||||
if(O.data)
|
||||
P.push_data()
|
||||
T.push_data()
|
||||
else
|
||||
F.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary
|
||||
inputs = list("A","B")
|
||||
@@ -53,6 +57,15 @@
|
||||
/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/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."
|
||||
@@ -114,4 +127,4 @@
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary/not/do_check(var/datum/integrated_io/A)
|
||||
return !A.data
|
||||
return !A.data
|
||||
@@ -9,6 +9,7 @@
|
||||
The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Note that the \
|
||||
normal limitations to firearms, such as ammunition requirements and firing delays, still hold true if fired by the mechanism."
|
||||
complexity = 20
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
inputs = list(
|
||||
"target X rel",
|
||||
"target Y rel"
|
||||
@@ -20,6 +21,7 @@
|
||||
var/obj/item/weapon/gun/installed_gun = null
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4)
|
||||
power_draw_per_use = 50 // The targeting mechanism uses this. The actual gun uses its own cell for firing if it's an energy weapon.
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/Destroy()
|
||||
qdel(installed_gun)
|
||||
@@ -106,20 +108,21 @@
|
||||
<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 = ITEMSIZE_NORMAL
|
||||
complexity = 20
|
||||
inputs = list("dir num")
|
||||
outputs = list()
|
||||
activators = list("step towards dir")
|
||||
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 && istype(loc, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/machine = loc
|
||||
if(machine.anchored || !machine.can_move())
|
||||
if(T && assembly)
|
||||
if(assembly.anchored || !assembly.can_move())
|
||||
return
|
||||
if(machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held.
|
||||
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))
|
||||
step(machine, wanted_dir.data)
|
||||
step(assembly, wanted_dir.data)
|
||||
@@ -8,6 +8,7 @@
|
||||
activators = list("set")
|
||||
category_text = "Memory"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/memory/examine(mob/user)
|
||||
..()
|
||||
@@ -33,15 +34,18 @@
|
||||
name = "memory circuit"
|
||||
desc = "This circuit can store four pieces of data."
|
||||
icon_state = "memory4"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
complexity = 4
|
||||
inputs = list("input pin 1","input pin 2","input pin 3","input pin 4")
|
||||
outputs = list("output pin 1","output pin 2","output pin 3","output pin 4")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/memory/large
|
||||
name = "large memory circuit"
|
||||
desc = "This big circuit can hold eight pieces of data."
|
||||
icon_state = "memory8"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
complexity = 8
|
||||
inputs = list(
|
||||
"input pin 1",
|
||||
@@ -63,11 +67,13 @@
|
||||
"output pin 8")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3)
|
||||
power_draw_per_use = 4
|
||||
|
||||
/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 = ITEMSIZE_NORMAL
|
||||
complexity = 16
|
||||
inputs = list(
|
||||
"input pin 1",
|
||||
@@ -106,6 +112,7 @@
|
||||
"output pin 16")
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4)
|
||||
power_draw_per_use = 8
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant
|
||||
name = "constant chip"
|
||||
80
code/modules/integrated_electronics/subtypes/power.dm
Normal file
80
code/modules/integrated_electronics/subtypes/power.dm
Normal file
@@ -0,0 +1,80 @@
|
||||
/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 = ITEMSIZE_SMALL
|
||||
complexity = 16
|
||||
inputs = list("target ref")
|
||||
outputs = list("target cell charge", "target cell max charge", "target cell percentage")
|
||||
activators = list("transmit")
|
||||
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 = ITEMSIZE_LARGE
|
||||
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()
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
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/weapon/cell/cell = null
|
||||
if(istype(AM, /obj/item/weapon/cell)) // Is this already a cell?
|
||||
cell = AM
|
||||
else // If not, maybe there's a cell inside it?
|
||||
for(var/obj/item/weapon/cell/C in AM.contents)
|
||||
if(C) // Find one cell to charge.
|
||||
cell = C
|
||||
break
|
||||
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.fully_charged())
|
||||
return FALSE
|
||||
|
||||
if(transfer_amount && assembly.draw_power(amount_to_move)) // CELLRATE is already handled in draw_power()
|
||||
cell.give(transfer_amount * CELLRATE)
|
||||
AM.update_icon()
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, cell.charge)
|
||||
set_pin_data(IC_OUTPUT, 2, cell.maxcharge)
|
||||
set_pin_data(IC_OUTPUT, 3, cell.percent())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/power/transmitter/large/do_work()
|
||||
if(..()) // If the above code succeeds, do this below.
|
||||
if(prob(2))
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(src))
|
||||
sparks.start()
|
||||
visible_message("<span class='warning'>\The [assembly] makes some sparks!</span>")
|
||||
qdel(sparks)
|
||||
@@ -23,6 +23,7 @@
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3)
|
||||
volume = 100
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/do_work()
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
@@ -47,6 +48,7 @@
|
||||
activators = list("inject")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
volume = 30
|
||||
power_draw_per_use = 15
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/proc/inject_amount()
|
||||
var/datum/integrated_io/amount = inputs[2]
|
||||
@@ -92,6 +94,7 @@
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/transfer_amount = 10
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump/on_data_written()
|
||||
var/datum/integrated_io/amount = inputs[3]
|
||||
33
code/modules/integrated_electronics/subtypes/smart.dm
Normal file
33
code/modules/integrated_electronics/subtypes/smart.dm
Normal file
@@ -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 ref")
|
||||
outputs = list("dir")
|
||||
activators = list("calculate dir")
|
||||
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]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
|
||||
if(!isweakref(I.data))
|
||||
return
|
||||
var/atom/A = I.data.resolve()
|
||||
if(!A)
|
||||
return
|
||||
if(!(A in view(get_turf(src))))
|
||||
return // Can't see the target.
|
||||
var/desired_dir = get_dir(get_turf(src), A)
|
||||
if(desired_dir)
|
||||
O.data = desired_dir
|
||||
O.push_data()
|
||||
@@ -14,6 +14,7 @@
|
||||
var/delay = 2 SECONDS
|
||||
activators = list("incoming pulse","outgoing pulse")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/do_work()
|
||||
set waitfor = 0 // Don't sleep in a proc that is called by a processor. It'll delay the entire thing
|
||||
@@ -82,6 +83,7 @@
|
||||
inputs = list("enable ticking")
|
||||
activators = list("outgoing pulse")
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/Destroy()
|
||||
if(is_running)
|
||||
@@ -116,6 +118,7 @@
|
||||
complexity = 12
|
||||
ticks_to_pulse = 2
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 8
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/slow
|
||||
name = "slow ticker"
|
||||
@@ -124,6 +127,7 @@
|
||||
complexity = 4
|
||||
ticks_to_pulse = 6
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/time/clock
|
||||
name = "integrated clock"
|
||||
@@ -132,6 +136,7 @@
|
||||
inputs = list()
|
||||
outputs = list("time (string)", "hours (number)", "minutes (number)", "seconds (number)")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/time/clock/do_work()
|
||||
var/datum/integrated_io/time = outputs[1]
|
||||
@@ -7,6 +7,7 @@
|
||||
category_text = "Trig"
|
||||
extended_desc = "Input and output are in degrees."
|
||||
autopulse = 1
|
||||
power_draw_per_use = 1 // Still cheap math.
|
||||
|
||||
/obj/item/integrated_circuit/trig/on_data_written()
|
||||
if(autopulse == 1)
|
||||
@@ -118,7 +119,7 @@
|
||||
|
||||
/obj/item/integrated_circuit/trig/cotangent
|
||||
name = "cot circuit"
|
||||
desc = "Outputs the cotangent of A. Has nothing to do with the security department."
|
||||
desc = "Outputs the cotangent of A."
|
||||
icon_state = "cotangent"
|
||||
inputs = list("A")
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
@@ -1,6 +0,0 @@
|
||||
#undef IC_INPUT
|
||||
#undef IC_OUTPUT
|
||||
#undef IC_ACTIVATOR
|
||||
|
||||
#undef DATA_CHANNEL
|
||||
#undef PULSE_CHANNEL
|
||||
16
code/modules/integrated_electronics/~defines/~defines.dm
Normal file
16
code/modules/integrated_electronics/~defines/~defines.dm
Normal file
@@ -0,0 +1,16 @@
|
||||
#undef IC_INPUT
|
||||
#undef IC_OUTPUT
|
||||
#undef IC_ACTIVATOR
|
||||
|
||||
#undef DATA_CHANNEL
|
||||
#undef PULSE_CHANNEL
|
||||
|
||||
#undef IC_SPAWN_DEFAULT
|
||||
//#undef IC_SPAWN_RESEARCH // Research designs depend on this unfortunately.
|
||||
|
||||
#undef IC_FORMAT_STRING
|
||||
#undef IC_FORMAT_NUMBER
|
||||
#undef IC_FORMAT_REF
|
||||
#undef IC_FORMAT_LIST
|
||||
#undef IC_FORMAT_ANY
|
||||
#undef IC_FORMAT_PULSE
|
||||
@@ -252,8 +252,9 @@
|
||||
for(var/iy = 0,iy < 5, iy++)
|
||||
for(var/ix = 0, ix < 5, ix++)
|
||||
mine_turf = locate(tx + ix, ty + iy, T.z)
|
||||
if(mine_turf && mine_turf.has_resources)
|
||||
resource_field += mine_turf
|
||||
if(!istype(mine_turf, /turf/space/))
|
||||
if(mine_turf && mine_turf.has_resources)
|
||||
resource_field += mine_turf
|
||||
|
||||
if(!resource_field.len)
|
||||
system_error("resources depleted")
|
||||
|
||||
@@ -35,7 +35,7 @@ var/list/mining_overlay_cache = list()
|
||||
var/ignore_mapgen
|
||||
|
||||
var/ore_types = list(
|
||||
"iron" = /obj/item/weapon/ore/iron,
|
||||
"hematite" = /obj/item/weapon/ore/iron,
|
||||
"uranium" = /obj/item/weapon/ore/uranium,
|
||||
"gold" = /obj/item/weapon/ore/gold,
|
||||
"silver" = /obj/item/weapon/ore/silver,
|
||||
@@ -44,7 +44,7 @@ var/list/mining_overlay_cache = list()
|
||||
"osmium" = /obj/item/weapon/ore/osmium,
|
||||
"hydrogen" = /obj/item/weapon/ore/hydrogen,
|
||||
"silicates" = /obj/item/weapon/ore/glass,
|
||||
"carbonaceous rock" = /obj/item/weapon/ore/coal
|
||||
"carbon" = /obj/item/weapon/ore/coal
|
||||
)
|
||||
|
||||
has_resources = 1
|
||||
@@ -483,6 +483,11 @@ var/list/mining_overlay_cache = list()
|
||||
if(prob(50))
|
||||
M.Stun(5)
|
||||
M.apply_effect(25, IRRADIATE)
|
||||
if(prob(25))
|
||||
excavate_find(prob(5), finds[1])
|
||||
else if(rand(1,500) == 1)
|
||||
visible_message("<span class='notice'>An old dusty crate was buried within!</span>")
|
||||
new /obj/structure/closet/crate/secure/loot(src)
|
||||
|
||||
make_floor()
|
||||
update_icon(1)
|
||||
@@ -546,10 +551,10 @@ var/list/mining_overlay_cache = list()
|
||||
|
||||
var/mineral_name
|
||||
if(rare_ore)
|
||||
mineral_name = pickweight(list("uranium" = 10, "platinum" = 10, "iron" = 20, "coal" = 20, "diamond" = 2, "gold" = 10, "silver" = 10, "phoron" = 20))
|
||||
mineral_name = pickweight(list("uranium" = 10, "platinum" = 10, "hematite" = 20, "carbon" = 20, "diamond" = 2, "gold" = 10, "silver" = 10, "phoron" = 20))
|
||||
|
||||
else
|
||||
mineral_name = pickweight(list("uranium" = 5, "platinum" = 5, "iron" = 35, "coal" = 35, "diamond" = 1, "gold" = 5, "silver" = 5, "phoron" = 10))
|
||||
mineral_name = pickweight(list("uranium" = 5, "platinum" = 5, "hematite" = 35, "carbon" = 35, "diamond" = 1, "gold" = 5, "silver" = 5, "phoron" = 10))
|
||||
|
||||
if(mineral_name && (mineral_name in ore_data))
|
||||
mineral = ore_data[mineral_name]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/language/ling
|
||||
name = "Changeling"
|
||||
name = LANGUAGE_CHANGELING
|
||||
desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance."
|
||||
speech_verb = "says"
|
||||
colour = "changeling"
|
||||
@@ -38,7 +38,7 @@
|
||||
..(speaker,message,speaker_mask)
|
||||
|
||||
/datum/language/vox
|
||||
name = "Vox-pidgin"
|
||||
name = LANGUAGE_VOX
|
||||
desc = "The common tongue of the various Vox ships making up the Shoal. It sounds like chaotic shrieking to everyone else."
|
||||
speech_verb = "shrieks"
|
||||
ask_verb = "creels"
|
||||
@@ -73,7 +73,7 @@
|
||||
"d'rekkathnor", "khari'd", "gual'te", "nikka", "nikt'o", "barada", "kla'atu", "barhah", "hra" ,"zar'garis", "spiri", "malum")
|
||||
|
||||
/datum/language/cult
|
||||
name = "Occult"
|
||||
name = LANGUAGE_OCCULT
|
||||
desc = "The initiated can share their thoughts by means defying all reason."
|
||||
speech_verb = "intones"
|
||||
ask_verb = "intones"
|
||||
|
||||
@@ -437,7 +437,6 @@
|
||||
stop_pulling()
|
||||
src << "<span class='warning'>You slipped on [slipped_on]!</span>"
|
||||
playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
|
||||
Stun(stun_duration)
|
||||
Weaken(Floor(stun_duration/2))
|
||||
return 1
|
||||
|
||||
|
||||
@@ -24,3 +24,8 @@
|
||||
var/pulse = PULSE_NORM //current pulse level
|
||||
|
||||
var/does_not_breathe = 0 //Used for specific mobs that can't take advantage of the species flags (changelings)
|
||||
|
||||
//these two help govern taste. The first is the last time a taste message was shown to the plaer.
|
||||
//the second is the message in question.
|
||||
var/last_taste_time = 0
|
||||
var/last_taste_text = ""
|
||||
@@ -685,12 +685,20 @@
|
||||
if(istype(src.head, /obj/item/clothing/head/helmet/space/emergency))
|
||||
number -= 2
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses/thermal))
|
||||
number -= 1
|
||||
var/obj/item/clothing/glasses/thermal/T = src.glasses
|
||||
if(T.active)
|
||||
number -= 1
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses/night))
|
||||
var/obj/item/clothing/glasses/night/N = src.glasses
|
||||
if(N.active)
|
||||
number -= 1
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses/sunglasses))
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses/sunglasses/sechud/aviator))
|
||||
var/obj/item/clothing/glasses/sunglasses/sechud/aviator/S = src.glasses
|
||||
if(!S.on)
|
||||
if(!S.active)
|
||||
number += 1
|
||||
else if(istype(src.glasses, /obj/item/clothing/glasses/sunglasses/medhud/aviator))
|
||||
number += 0
|
||||
else
|
||||
number += 1
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses/welding))
|
||||
@@ -1315,7 +1323,8 @@
|
||||
/mob/living/carbon/human/slip(var/slipped_on, stun_duration=8)
|
||||
if((species.flags & NO_SLIP) || (shoes && (shoes.item_flags & NOSLIP)))
|
||||
return 0
|
||||
..(slipped_on,stun_duration)
|
||||
if(..(slipped_on,stun_duration))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/undislocate()
|
||||
set category = "Object"
|
||||
|
||||
@@ -90,54 +90,6 @@
|
||||
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human
|
||||
var/next_sonar_ping = 0
|
||||
|
||||
/mob/living/carbon/human/proc/sonar_ping()
|
||||
set name = "Listen In"
|
||||
set desc = "Allows you to listen in to movement and noises around you."
|
||||
set category = "Abilities"
|
||||
|
||||
if(incapacitated())
|
||||
src << "<span class='warning'>You need to recover before you can use this ability.</span>"
|
||||
return
|
||||
if(world.time < next_sonar_ping)
|
||||
src << "<span class='warning'>You need another moment to focus.</span>"
|
||||
return
|
||||
if(is_deaf() || is_below_sound_pressure(get_turf(src)))
|
||||
src << "<span class='warning'>You are for all intents and purposes currently deaf!</span>"
|
||||
return
|
||||
next_sonar_ping += 10 SECONDS
|
||||
var/heard_something = FALSE
|
||||
src << "<span class='notice'>You take a moment to listen in to your environment...</span>"
|
||||
for(var/mob/living/L in range(client.view, src))
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T || L == src || L.stat == DEAD || is_below_sound_pressure(T))
|
||||
continue
|
||||
heard_something = TRUE
|
||||
var/feedback = list()
|
||||
feedback += "<span class='notice'>There are noises of movement "
|
||||
var/direction = get_dir(src, L)
|
||||
if(direction)
|
||||
feedback += "towards the [dir2text(direction)], "
|
||||
switch(get_dist(src, L) / client.view)
|
||||
if(0 to 0.2)
|
||||
feedback += "very close by."
|
||||
if(0.2 to 0.4)
|
||||
feedback += "close by."
|
||||
if(0.4 to 0.6)
|
||||
feedback += "some distance away."
|
||||
if(0.6 to 0.8)
|
||||
feedback += "further away."
|
||||
else
|
||||
feedback += "far away."
|
||||
else // No need to check distance if they're standing right on-top of us
|
||||
feedback += "right on top of you."
|
||||
feedback += "</span>"
|
||||
src << jointext(feedback,null)
|
||||
if(!heard_something)
|
||||
src << "<span class='notice'>You hear no movement but your own.</span>"
|
||||
|
||||
#undef HUMAN_EATING_NO_ISSUE
|
||||
#undef HUMAN_EATING_NO_MOUTH
|
||||
#undef HUMAN_EATING_BLOCKED_MOUTH
|
||||
|
||||
@@ -175,3 +175,84 @@
|
||||
output += "[IO.name] - <span style='color:green;'>OK</span>\n"
|
||||
|
||||
src << output
|
||||
|
||||
/mob/living/carbon/human
|
||||
var/next_sonar_ping = 0
|
||||
|
||||
/mob/living/carbon/human/proc/sonar_ping()
|
||||
set name = "Listen In"
|
||||
set desc = "Allows you to listen in to movement and noises around you."
|
||||
set category = "Abilities"
|
||||
|
||||
if(incapacitated())
|
||||
src << "<span class='warning'>You need to recover before you can use this ability.</span>"
|
||||
return
|
||||
if(world.time < next_sonar_ping)
|
||||
src << "<span class='warning'>You need another moment to focus.</span>"
|
||||
return
|
||||
if(is_deaf() || is_below_sound_pressure(get_turf(src)))
|
||||
src << "<span class='warning'>You are for all intents and purposes currently deaf!</span>"
|
||||
return
|
||||
next_sonar_ping += 10 SECONDS
|
||||
var/heard_something = FALSE
|
||||
src << "<span class='notice'>You take a moment to listen in to your environment...</span>"
|
||||
for(var/mob/living/L in range(client.view, src))
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T || L == src || L.stat == DEAD || is_below_sound_pressure(T))
|
||||
continue
|
||||
heard_something = TRUE
|
||||
var/feedback = list()
|
||||
feedback += "<span class='notice'>There are noises of movement "
|
||||
var/direction = get_dir(src, L)
|
||||
if(direction)
|
||||
feedback += "towards the [dir2text(direction)], "
|
||||
switch(get_dist(src, L) / client.view)
|
||||
if(0 to 0.2)
|
||||
feedback += "very close by."
|
||||
if(0.2 to 0.4)
|
||||
feedback += "close by."
|
||||
if(0.4 to 0.6)
|
||||
feedback += "some distance away."
|
||||
if(0.6 to 0.8)
|
||||
feedback += "further away."
|
||||
else
|
||||
feedback += "far away."
|
||||
else // No need to check distance if they're standing right on-top of us
|
||||
feedback += "right on top of you."
|
||||
feedback += "</span>"
|
||||
src << jointext(feedback,null)
|
||||
if(!heard_something)
|
||||
src << "<span class='notice'>You hear no movement but your own.</span>"
|
||||
|
||||
/mob/living/carbon/human/proc/regenerate()
|
||||
set name = "Regenerate"
|
||||
set desc = "Allows you to regrow limbs and heal organs."
|
||||
set category = "Abilities"
|
||||
|
||||
if(nutrition < 250)
|
||||
to_chat(src, "<span class='warning'>You lack the biomass regrow anything!</span>")
|
||||
return
|
||||
|
||||
nutrition -= 200
|
||||
|
||||
// Theoretically the only internal organ a slime will have
|
||||
// is the slime core. but we might as well be thorough.
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
if(I.damage > 0)
|
||||
I.damage = 0
|
||||
to_chat(src, "<span class='notice'>You feel a soothing sensation within your [I.name]...</span>")
|
||||
|
||||
// Replace completely missing limbs.
|
||||
for(var/limb_type in src.species.has_limbs)
|
||||
var/obj/item/organ/external/E = src.organs_by_name[limb_type]
|
||||
if(E && (E.is_stump() || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED))))
|
||||
E.removed()
|
||||
qdel(E)
|
||||
E = null
|
||||
if(!E)
|
||||
var/list/organ_data = src.species.has_limbs[limb_type]
|
||||
var/limb_path = organ_data["path"]
|
||||
var/obj/item/organ/O = new limb_path(src)
|
||||
organ_data["descriptor"] = O.name
|
||||
to_chat(src, "<span class='notice'>You feel a slithering sensation as your [O.name] reform.</span>")
|
||||
src.update_body()
|
||||
|
||||
@@ -1337,6 +1337,9 @@
|
||||
if(istype(G, /obj/item/clothing/glasses/sunglasses/sechud))
|
||||
var/obj/item/clothing/glasses/sunglasses/sechud/S = G
|
||||
O = S.hud
|
||||
if(istype(G, /obj/item/clothing/glasses/sunglasses/medhud))
|
||||
var/obj/item/clothing/glasses/sunglasses/medhud/M = G
|
||||
O = M.hud
|
||||
if(istype(O))
|
||||
O.process_hud(src)
|
||||
if(!druggy && !seer) see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
name_plural = "Vox"
|
||||
icobase = 'icons/mob/human_races/r_vox.dmi'
|
||||
deform = 'icons/mob/human_races/r_def_vox.dmi'
|
||||
default_language = "Vox-pidgin"
|
||||
language = "Galactic Common"
|
||||
default_language = LANGUAGE_VOX
|
||||
language = LANGUAGE_GALCOM
|
||||
num_alternate_languages = 1
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
|
||||
rarity_value = 4
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
// taste_sensitivity = TASTE_DULL
|
||||
|
||||
slowdown = -0.5
|
||||
|
||||
speech_sounds = list('sound/voice/shriek1.ogg')
|
||||
speech_chance = 20
|
||||
|
||||
@@ -37,7 +39,7 @@
|
||||
spawn_flags = SPECIES_IS_WHITELISTED
|
||||
appearance_flags = HAS_EYE_COLOR | HAS_HAIR_COLOR
|
||||
|
||||
blood_color = "#2299FC"
|
||||
blood_color = "#9066BD"
|
||||
flesh_color = "#808D11"
|
||||
|
||||
reagent_tag = IS_VOX
|
||||
@@ -75,11 +77,11 @@
|
||||
/datum/species/vox/equip_survival_gear(var/mob/living/carbon/human/H)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(H), slot_wear_mask)
|
||||
if(H.backbag == 1)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/tank/phoron/vox(H), slot_back)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/tank/vox(H), slot_back)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/vox(H), slot_r_hand)
|
||||
H.internal = H.back
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/tank/phoron/vox(H), slot_r_hand)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/tank/vox(H), slot_r_hand)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/vox(H.back), slot_in_backpack)
|
||||
H.internal = H.r_hand
|
||||
H.internal = locate(/obj/item/weapon/tank) in H.contents
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
var/blood_volume = 560 // Initial blood volume.
|
||||
var/hunger_factor = 0.05 // Multiplier for hunger.
|
||||
|
||||
var/taste_sensitivity = TASTE_NORMAL // How sensitive the species is to minute tastes.
|
||||
|
||||
var/min_age = 17
|
||||
var/max_age = 70
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ var/datum/species/shapeshifter/promethean/prometheans
|
||||
breath_type = null
|
||||
poison_type = null
|
||||
|
||||
gluttonous = 2
|
||||
gluttonous = 1
|
||||
virus_immune = 1
|
||||
blood_volume = 600
|
||||
blood_volume = 560
|
||||
min_age = 1
|
||||
max_age = 5
|
||||
brute_mod = 0.5
|
||||
@@ -73,7 +73,8 @@ var/datum/species/shapeshifter/promethean/prometheans
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_shape,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_colour,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_hair,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_gender
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_gender,
|
||||
/mob/living/carbon/human/proc/regenerate
|
||||
)
|
||||
|
||||
valid_transform_species = list("Human", "Unathi", "Tajara", "Skrell", "Diona", "Teshari", "Monkey")
|
||||
@@ -130,42 +131,14 @@ var/datum/species/shapeshifter/promethean/prometheans
|
||||
var/obj/effect/decal/cleanable/C = locate() in T
|
||||
if(C)
|
||||
qdel(C)
|
||||
//TODO: gain nutriment
|
||||
|
||||
// Regenerate limbs and heal damage if we have any. Copied from Bay xenos code.
|
||||
|
||||
// Theoretically the only internal organ a slime will have
|
||||
// is the slime core. but we might as well be thorough.
|
||||
for(var/obj/item/organ/I in H.internal_organs)
|
||||
if(I.damage > 0)
|
||||
I.damage = max(I.damage - heal_rate, 0)
|
||||
if (prob(5))
|
||||
H << "<span class='notice'>You feel a soothing sensation within your [I.name]...</span>"
|
||||
return 1
|
||||
|
||||
// Replace completely missing limbs.
|
||||
for(var/limb_type in has_limbs)
|
||||
var/obj/item/organ/external/E = H.organs_by_name[limb_type]
|
||||
if(E && (E.is_stump() || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED))))
|
||||
E.removed()
|
||||
qdel(E)
|
||||
E = null
|
||||
if(!E)
|
||||
var/list/organ_data = has_limbs[limb_type]
|
||||
var/limb_path = organ_data["path"]
|
||||
var/obj/item/organ/O = new limb_path(H)
|
||||
organ_data["descriptor"] = O.name
|
||||
H << "<span class='notice'>You feel a slithering sensation as your [O.name] reforms.</span>"
|
||||
H.update_body()
|
||||
return 1
|
||||
H.nutrition += rand(15, 45)
|
||||
|
||||
// Heal remaining damage.
|
||||
if (H.getBruteLoss() || H.getFireLoss() || H.getOxyLoss() || H.getToxLoss())
|
||||
if(H.getBruteLoss() || H.getFireLoss() || H.getOxyLoss() || H.getToxLoss())
|
||||
H.adjustBruteLoss(-heal_rate)
|
||||
H.adjustFireLoss(-heal_rate)
|
||||
H.adjustOxyLoss(-heal_rate)
|
||||
H.adjustToxLoss(-heal_rate)
|
||||
return 1
|
||||
|
||||
/datum/species/shapeshifter/promethean/get_blood_colour(var/mob/living/carbon/human/H)
|
||||
return (H ? rgb(H.r_skin, H.g_skin, H.b_skin) : ..())
|
||||
|
||||
@@ -246,7 +246,8 @@
|
||||
)
|
||||
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/diona_split_nymph
|
||||
/mob/living/carbon/human/proc/diona_split_nymph,
|
||||
/mob/living/carbon/human/proc/regenerate
|
||||
)
|
||||
|
||||
warning_low_pressure = 50
|
||||
|
||||
60
code/modules/mob/living/carbon/taste.dm
Normal file
60
code/modules/mob/living/carbon/taste.dm
Normal file
@@ -0,0 +1,60 @@
|
||||
/mob/living/carbon/proc/ingest(var/datum/reagents/from, var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) //we kind of 'sneak' a proc in here for ingesting stuff so we can play with it.
|
||||
if(last_taste_time + 50 < world.time)
|
||||
var/datum/reagents/temp = new(amount) //temporary holder used to analyse what gets transfered.
|
||||
from.trans_to_holder(temp, amount, multiplier, 1)
|
||||
|
||||
var/text_output = temp.generate_taste_message(src)
|
||||
if(text_output != last_taste_text || last_taste_time + 100 < world.time) //We dont want to spam the same message over and over again at the person. Give it a bit of a buffer.
|
||||
to_chat(src, "<span class='notice'>You can taste [text_output].</span>")//no taste means there are too many tastes and not enough flavor.
|
||||
|
||||
last_taste_time = world.time
|
||||
last_taste_text = text_output
|
||||
return from.trans_to_holder(target,amount,multiplier,copy) //complete transfer
|
||||
|
||||
/* what this does:
|
||||
catalogue the 'taste strength' of each one
|
||||
calculate text size per text.
|
||||
*/
|
||||
/datum/reagents/proc/generate_taste_message(mob/living/carbon/taster = null)
|
||||
var/minimum_percent = 15
|
||||
if(ishuman(taster))
|
||||
var/mob/living/carbon/human/H = taster
|
||||
minimum_percent = round(15/ (H.isSynthetic() ? TASTE_DULL : H.species.taste_sensitivity))
|
||||
|
||||
var/list/out = list()
|
||||
var/list/tastes = list() //descriptor = strength
|
||||
if(minimum_percent <= 100)
|
||||
for(var/datum/reagent/R in reagent_list)
|
||||
if(!R.taste_mult)
|
||||
continue
|
||||
if(R.id == "nutriment") //this is ugly but apparently only nutriment (not subtypes) has taste data TODO figure out why
|
||||
var/list/taste_data = R.get_data()
|
||||
for(var/taste in taste_data)
|
||||
if(taste in tastes)
|
||||
tastes[taste] += taste_data[taste]
|
||||
else
|
||||
tastes[taste] = taste_data[taste]
|
||||
else
|
||||
var/taste_desc = R.taste_description
|
||||
var/taste_amount = get_reagent_amount(R.id) * R.taste_mult
|
||||
if(R.taste_description in tastes)
|
||||
tastes[taste_desc] += taste_amount
|
||||
else
|
||||
tastes[taste_desc] = taste_amount
|
||||
|
||||
//deal with percentages
|
||||
var/total_taste = 0
|
||||
for(var/taste_desc in tastes)
|
||||
total_taste += tastes[taste_desc]
|
||||
for(var/taste_desc in tastes)
|
||||
var/percent = tastes[taste_desc]/total_taste * 100
|
||||
if(percent < minimum_percent)
|
||||
continue
|
||||
var/intensity_desc = "a hint of"
|
||||
if(percent > minimum_percent * 2 || percent == 100)
|
||||
intensity_desc = "the flavor of"
|
||||
else if(percent > minimum_percent * 3)
|
||||
intensity_desc = "the strong flavor of"
|
||||
out += "[intensity_desc] [taste_desc]"
|
||||
|
||||
return english_list(out, "something indescribable")
|
||||
@@ -223,4 +223,25 @@
|
||||
icon_state = "impact_lightning"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#00C6FF"
|
||||
light_color = "#00C6FF"
|
||||
|
||||
//----------------------------
|
||||
// Dark matter
|
||||
//----------------------------
|
||||
/obj/effect/projectile/darkmatter/tracer
|
||||
icon_state = "darkb"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#8837A3"
|
||||
|
||||
/obj/effect/projectile/darkmatter/muzzle
|
||||
icon_state = "muzzle_darkb"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#8837A3"
|
||||
|
||||
/obj/effect/projectile/darkmatter/impact
|
||||
icon_state = "impact_darkb"
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
light_color = "#8837A3"
|
||||
@@ -1,46 +0,0 @@
|
||||
// Alien pinning weapon.
|
||||
/obj/item/weapon/gun/launcher/spikethrower
|
||||
|
||||
name = "spike thrower"
|
||||
desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
|
||||
|
||||
var/last_regen = 0
|
||||
var/spike_gen_time = 150
|
||||
var/max_spikes = 3
|
||||
var/spikes = 3
|
||||
release_force = 30
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "spikethrower3"
|
||||
item_state = "spikethrower"
|
||||
fire_sound_text = "a strange noise"
|
||||
fire_sound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
last_regen = world.time
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/process()
|
||||
if(spikes < max_spikes && world.time > last_regen + spike_gen_time)
|
||||
spikes++
|
||||
last_regen = world.time
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/examine(mob/user)
|
||||
..(user)
|
||||
user << "It has [spikes] spike\s remaining."
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/update_icon()
|
||||
icon_state = "spikethrower[spikes]"
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/update_release_force()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/consume_next_projectile()
|
||||
if(spikes < 1) return null
|
||||
spikes--
|
||||
return new /obj/item/weapon/spike(src)
|
||||
@@ -149,4 +149,4 @@ obj/item/weapon/gun/energy/staff/focus
|
||||
charge_cost = 200
|
||||
user << "<span class='warning'>The [src.name] will now strike only a single person.</span>"
|
||||
projectile_type = "/obj/item/projectile/forcebolt"
|
||||
*/
|
||||
*/
|
||||
139
code/modules/projectiles/guns/vox.dm
Normal file
139
code/modules/projectiles/guns/vox.dm
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Vox Spike Thrower
|
||||
* Alien pinning weapon.
|
||||
*/
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower
|
||||
name = "spike thrower"
|
||||
desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
|
||||
|
||||
var/last_regen = 0
|
||||
var/spike_gen_time = 150
|
||||
var/max_spikes = 3
|
||||
var/spikes = 3
|
||||
release_force = 30
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "spikethrower3"
|
||||
item_state = "spikethrower"
|
||||
fire_sound_text = "a strange noise"
|
||||
fire_sound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
last_regen = world.time
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/process()
|
||||
if(spikes < max_spikes && world.time > last_regen + spike_gen_time)
|
||||
spikes++
|
||||
last_regen = world.time
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/examine(mob/user)
|
||||
..(user)
|
||||
user << "It has [spikes] spike\s remaining."
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/update_icon()
|
||||
icon_state = "spikethrower[spikes]"
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/update_release_force()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/launcher/spikethrower/consume_next_projectile()
|
||||
if(spikes < 1) return null
|
||||
spikes--
|
||||
return new /obj/item/weapon/spike(src)
|
||||
|
||||
/*
|
||||
* Vox Darkmatter Cannon
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/darkmatter
|
||||
name = "dark matter gun"
|
||||
desc = "A vicious alien beam weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
|
||||
icon_state = "darkcannon"
|
||||
item_state = "darkcannon"
|
||||
fire_sound = 'sound/weapons/eLuger.ogg'
|
||||
charge_cost = 600
|
||||
projectile_type = /obj/item/projectile/beam/darkmatter
|
||||
self_recharge = 1
|
||||
accuracy = 2
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="focused", burst=1, fire_delay=null, move_delay=null, burst_accuracy=list(2), dispersion=null, projectile_type=/obj/item/projectile/beam/darkmatter, charge_cost = 600),
|
||||
list(mode_name="scatter burst", burst=8, fire_delay=null, move_delay=4, burst_accuracy=list(0, 0, 0, 0, 0, 0, 0, 0), dispersion=list(3, 3, 3, 3, 3, 3, 3, 3, 3), projectile_type=/obj/item/projectile/energy/darkmatter, charge_cost = 300),
|
||||
)
|
||||
|
||||
/obj/item/projectile/beam/darkmatter
|
||||
name = "dark matter bolt"
|
||||
icon_state = "darkb"
|
||||
damage = 60
|
||||
armor_penetration = 35
|
||||
damage_type = BRUTE
|
||||
check_armour = "energy"
|
||||
light_color = "#8837A3"
|
||||
|
||||
embed_chance = 0
|
||||
|
||||
muzzle_type = /obj/effect/projectile/darkmatter/muzzle
|
||||
tracer_type = /obj/effect/projectile/darkmatter/tracer
|
||||
impact_type = /obj/effect/projectile/darkmatter/impact
|
||||
|
||||
/obj/item/projectile/energy/darkmatter
|
||||
name = "dark matter pellet"
|
||||
icon_state = "dark_pellet"
|
||||
damage = 20
|
||||
armor_penetration = 35
|
||||
damage_type = BRUTE
|
||||
check_armour = "energy"
|
||||
light_color = "#8837A3"
|
||||
|
||||
embed_chance = 0
|
||||
|
||||
/*
|
||||
* Vox Darkmatter Cannon
|
||||
*/
|
||||
/obj/item/weapon/gun/energy/sonic
|
||||
name = "soundcannon"
|
||||
desc = "A vicious alien sound weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
|
||||
icon_state = "noise"
|
||||
item_state = "noise"
|
||||
fire_sound = 'sound/effects/basscannon.ogg'
|
||||
self_recharge = 1
|
||||
charge_cost = 600
|
||||
|
||||
projectile_type=/obj/item/projectile/sonic/strong
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="normal", projectile_type=/obj/item/projectile/sonic/strong, charge_cost = 600),
|
||||
list(mode_name="suppressive", projectile_type=/obj/item/projectile/sonic/weak, charge_cost = 300),
|
||||
)
|
||||
|
||||
/obj/item/projectile/sonic
|
||||
name = "sonic pulse"
|
||||
icon_state = "sound"
|
||||
damage = 15
|
||||
armor_penetration = 30
|
||||
damage_type = BRUTE
|
||||
check_armour = "melee"
|
||||
embed_chance = 0
|
||||
vacuum_traversal = 0
|
||||
|
||||
// var/amplitude = 10 //Roughly how loud it is, changes the way damage will work, and such
|
||||
|
||||
/obj/item/projectile/sonic/weak
|
||||
agony = 30
|
||||
|
||||
/obj/item/projectile/sonic/strong
|
||||
damage = 45
|
||||
|
||||
//Already have thoughts on how to improve this, will take a day or two after initial testing. - Anewbe
|
||||
|
||||
/obj/item/projectile/sonic/strong/on_hit(var/atom/movable/target, var/blocked = 0)
|
||||
if(ismob(target))
|
||||
var/throwdir = get_dir(firer,target)
|
||||
target.throw_at(get_edge_target_turf(target, throwdir), rand(1,6), 10)
|
||||
return 1
|
||||
@@ -8,6 +8,7 @@
|
||||
eyeblur = 4
|
||||
var/frequency = 1
|
||||
hitscan = 1
|
||||
embed_chance = 0
|
||||
invisibility = 101 //beam projectiles are invisible as they are rendered by the effect engine
|
||||
light_range = 2
|
||||
light_power = 0.5
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
armor_penetration = 10
|
||||
kill_count = 4
|
||||
damage = 5
|
||||
agony = 70
|
||||
agony = 55
|
||||
damage_type = BURN
|
||||
vacuum_traversal = 0 //Projectile disappears in empty space
|
||||
|
||||
@@ -151,12 +151,12 @@
|
||||
var/ear_safety = 0
|
||||
ear_safety = M.get_ear_protection()
|
||||
if(ear_safety == 1)
|
||||
M.Weaken(2)
|
||||
M.confused += 150
|
||||
else if (ear_safety > 1)
|
||||
M.Weaken(1)
|
||||
M.confused += 30
|
||||
else if (!ear_safety)
|
||||
M.Stun(10)
|
||||
M.Weaken(3)
|
||||
M.Weaken(2)
|
||||
M.ear_damage += rand(1, 10)
|
||||
M.ear_deaf = max(M.ear_deaf,15)
|
||||
if (M.ear_damage >= 15)
|
||||
|
||||
@@ -156,4 +156,3 @@
|
||||
nodamage = 1
|
||||
damage_type = HALLOSS
|
||||
muzzle_type = /obj/effect/projectile/bullet/muzzle
|
||||
|
||||
|
||||
@@ -383,7 +383,7 @@
|
||||
return trans_to_holder(R, amount, multiplier, copy)
|
||||
if(type == CHEM_INGEST)
|
||||
var/datum/reagents/R = C.ingested
|
||||
return trans_to_holder(R, amount, multiplier, copy)
|
||||
return C.ingest(src, R, amount, multiplier, copy)
|
||||
if(type == CHEM_TOUCH)
|
||||
var/datum/reagents/R = C.touching
|
||||
return trans_to_holder(R, amount, multiplier, copy)
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
var/name = "Reagent"
|
||||
var/id = "reagent"
|
||||
var/description = "A non-descript chemical."
|
||||
var/taste_description = "bitterness"
|
||||
var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable
|
||||
var/datum/reagents/holder = null
|
||||
var/reagent_state = SOLID
|
||||
var/list/data = null
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
data = new/list("donor" = null, "viruses" = null, "species" = "Human", "blood_DNA" = null, "blood_type" = null, "blood_colour" = "#A10808", "resistances" = null, "trace_chem" = null, "antibodies" = list())
|
||||
name = "Blood"
|
||||
id = "blood"
|
||||
taste_description = "iron"
|
||||
taste_mult = 1.3
|
||||
reagent_state = LIQUID
|
||||
metabolism = REM * 5
|
||||
mrate_static = TRUE
|
||||
@@ -74,6 +76,7 @@
|
||||
/datum/reagent/antibodies
|
||||
data = list("antibodies"=list())
|
||||
name = "Antibodies"
|
||||
taste_description = "slime"
|
||||
id = "antibodies"
|
||||
reagent_state = LIQUID
|
||||
color = "#0050F0"
|
||||
@@ -88,6 +91,7 @@
|
||||
/datum/reagent/water
|
||||
name = "Water"
|
||||
id = "water"
|
||||
taste_description = "water"
|
||||
description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen."
|
||||
reagent_state = LIQUID
|
||||
color = "#0064C877"
|
||||
@@ -150,6 +154,7 @@
|
||||
name = "Welding fuel"
|
||||
id = "fuel"
|
||||
description = "Required for welders. Flamable."
|
||||
taste_description = "gross metal"
|
||||
reagent_state = LIQUID
|
||||
color = "#660000"
|
||||
|
||||
|
||||
@@ -2,13 +2,17 @@
|
||||
name = "Aluminum"
|
||||
id = "aluminum"
|
||||
description = "A silvery white and ductile member of the boron group of chemical elements."
|
||||
taste_description = "metal"
|
||||
taste_mult = 1.1
|
||||
reagent_state = SOLID
|
||||
color = "#A8A8A8"
|
||||
|
||||
/datum/reagent/carbon
|
||||
name = "Carbon"
|
||||
id = "carbon"
|
||||
description = "A chemical element, the builing block of life."
|
||||
description = "A chemical element, the building block of life."
|
||||
taste_description = "sour chalk"
|
||||
taste_mult = 1.5
|
||||
reagent_state = SOLID
|
||||
color = "#1C1300"
|
||||
ingest_met = REM * 5
|
||||
@@ -37,6 +41,7 @@
|
||||
name = "Chlorine"
|
||||
id = "chlorine"
|
||||
description = "A chemical element with a characteristic odour."
|
||||
taste_description = "pool water"
|
||||
reagent_state = GAS
|
||||
color = "#808080"
|
||||
|
||||
@@ -50,12 +55,14 @@
|
||||
name = "Copper"
|
||||
id = "copper"
|
||||
description = "A highly ductile metal."
|
||||
taste_description = "pennies"
|
||||
color = "#6E3B08"
|
||||
|
||||
/datum/reagent/ethanol
|
||||
name = "Ethanol" //Parent class for all alcoholic reagents.
|
||||
id = "ethanol"
|
||||
description = "A well-known alcohol with a variety of applications."
|
||||
taste_description = "pure alcohol"
|
||||
reagent_state = LIQUID
|
||||
color = "#404030"
|
||||
var/nutriment_factor = 0
|
||||
@@ -142,6 +149,7 @@
|
||||
name = "Fluorine"
|
||||
id = "fluorine"
|
||||
description = "A highly-reactive chemical element."
|
||||
taste_description = "acid"
|
||||
reagent_state = GAS
|
||||
color = "#808080"
|
||||
|
||||
@@ -155,6 +163,7 @@
|
||||
name = "Hydrogen"
|
||||
id = "hydrogen"
|
||||
description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas."
|
||||
taste_mult = 0 //no taste
|
||||
reagent_state = GAS
|
||||
color = "#808080"
|
||||
|
||||
@@ -162,6 +171,7 @@
|
||||
name = "Iron"
|
||||
id = "iron"
|
||||
description = "Pure iron is a metal."
|
||||
taste_description = "metal"
|
||||
reagent_state = SOLID
|
||||
color = "#353535"
|
||||
|
||||
@@ -173,6 +183,7 @@
|
||||
name = "Lithium"
|
||||
id = "lithium"
|
||||
description = "A chemical element, used as antidepressant."
|
||||
taste_description = "metal"
|
||||
reagent_state = SOLID
|
||||
color = "#808080"
|
||||
|
||||
@@ -187,6 +198,7 @@
|
||||
name = "Mercury"
|
||||
id = "mercury"
|
||||
description = "A chemical element."
|
||||
taste_mult = 0 //mercury apparently is tasteless. IDK
|
||||
reagent_state = LIQUID
|
||||
color = "#484848"
|
||||
|
||||
@@ -202,6 +214,7 @@
|
||||
name = "Nitrogen"
|
||||
id = "nitrogen"
|
||||
description = "A colorless, odorless, tasteless gas."
|
||||
taste_mult = 0 //no taste
|
||||
reagent_state = GAS
|
||||
color = "#808080"
|
||||
|
||||
@@ -209,6 +222,7 @@
|
||||
name = "Oxygen"
|
||||
id = "oxygen"
|
||||
description = "A colorless, odorless gas."
|
||||
taste_mult = 0
|
||||
reagent_state = GAS
|
||||
color = "#808080"
|
||||
|
||||
@@ -220,6 +234,7 @@
|
||||
name = "Phosphorus"
|
||||
id = "phosphorus"
|
||||
description = "A chemical element, the backbone of biological energy carriers."
|
||||
taste_description = "vinegar"
|
||||
reagent_state = SOLID
|
||||
color = "#832828"
|
||||
|
||||
@@ -227,6 +242,7 @@
|
||||
name = "Potassium"
|
||||
id = "potassium"
|
||||
description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water."
|
||||
taste_description = "sweetness" //potassium is bitter in higher doses but sweet in lower ones.
|
||||
reagent_state = SOLID
|
||||
color = "#A0A0A0"
|
||||
|
||||
@@ -234,6 +250,7 @@
|
||||
name = "Radium"
|
||||
id = "radium"
|
||||
description = "Radium is an alkaline earth metal. It is extremely radioactive."
|
||||
taste_mult = 0 //Apparently radium is tasteless
|
||||
reagent_state = SOLID
|
||||
color = "#C7C7C7"
|
||||
|
||||
@@ -266,6 +283,7 @@
|
||||
name = "Sulphuric acid"
|
||||
id = "sacid"
|
||||
description = "A very corrosive mineral acid with the molecular formula H2SO4."
|
||||
taste_description = "acid"
|
||||
reagent_state = LIQUID
|
||||
color = "#DB5008"
|
||||
metabolism = REM * 2
|
||||
@@ -352,6 +370,7 @@
|
||||
name = "Silicon"
|
||||
id = "silicon"
|
||||
description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon."
|
||||
taste_mult = 0
|
||||
reagent_state = SOLID
|
||||
color = "#A8A8A8"
|
||||
|
||||
@@ -359,6 +378,7 @@
|
||||
name = "Sodium"
|
||||
id = "sodium"
|
||||
description = "A chemical element, readily reacts with water."
|
||||
taste_description = "salty metal"
|
||||
reagent_state = SOLID
|
||||
color = "#808080"
|
||||
|
||||
@@ -366,6 +386,8 @@
|
||||
name = "Sugar"
|
||||
id = "sugar"
|
||||
description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste."
|
||||
taste_description = "sugar"
|
||||
taste_mult = 1.8
|
||||
reagent_state = SOLID
|
||||
color = "#FFFFFF"
|
||||
|
||||
@@ -398,6 +420,7 @@
|
||||
name = "Sulfur"
|
||||
id = "sulfur"
|
||||
description = "A chemical element with a pungent smell."
|
||||
taste_description = "old eggs"
|
||||
reagent_state = SOLID
|
||||
color = "#BF8C00"
|
||||
|
||||
@@ -405,5 +428,7 @@
|
||||
name = "Tungsten"
|
||||
id = "tungsten"
|
||||
description = "A chemical element, and a strong oxidising agent."
|
||||
taste_description = "metal"
|
||||
taste_mult = 0 //no taste
|
||||
reagent_state = SOLID
|
||||
color = "#DCDCDC"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
name = "Inaprovaline"
|
||||
id = "inaprovaline"
|
||||
description = "Inaprovaline is a synaptic stimulant and cardiostimulant. Commonly used to stabilize patients."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#00BFFF"
|
||||
overdose = REAGENTS_OVERDOSE * 2
|
||||
@@ -20,6 +21,8 @@
|
||||
name = "Bicaridine"
|
||||
id = "bicaridine"
|
||||
description = "Bicaridine is an analgesic medication and can be used to treat blunt trauma."
|
||||
taste_description = "bitterness"
|
||||
taste_mult = 3
|
||||
reagent_state = LIQUID
|
||||
color = "#BF0000"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
@@ -33,6 +36,7 @@
|
||||
name = "Kelotane"
|
||||
id = "kelotane"
|
||||
description = "Kelotane is a drug used to treat burns."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#FFA800"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
@@ -46,6 +50,8 @@
|
||||
name = "Dermaline"
|
||||
id = "dermaline"
|
||||
description = "Dermaline is the next step in burn medication. Works twice as good as kelotane and enables the body to restore even the direst heat-damaged tissue."
|
||||
taste_description = "bitterness"
|
||||
taste_mult = 1.5
|
||||
reagent_state = LIQUID
|
||||
color = "#FF8000"
|
||||
overdose = REAGENTS_OVERDOSE * 0.5
|
||||
@@ -59,6 +65,7 @@
|
||||
name = "Dylovene"
|
||||
id = "anti_toxin"
|
||||
description = "Dylovene is a broad-spectrum antitoxin."
|
||||
taste_description = "a roll of gauze"
|
||||
reagent_state = LIQUID
|
||||
color = "#00A000"
|
||||
scannable = 1
|
||||
@@ -96,6 +103,7 @@
|
||||
name = "Dexalin"
|
||||
id = "dexalin"
|
||||
description = "Dexalin is used in the treatment of oxygen deprivation."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#0080FF"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
@@ -113,6 +121,7 @@
|
||||
name = "Dexalin Plus"
|
||||
id = "dexalinp"
|
||||
description = "Dexalin Plus is used in the treatment of oxygen deprivation. It is highly effective."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#0040FF"
|
||||
mrate_static = TRUE //Until it's not crazy strong, at least
|
||||
@@ -131,6 +140,7 @@
|
||||
name = "Tricordrazine"
|
||||
id = "tricordrazine"
|
||||
description = "Tricordrazine is a highly potent stimulant, originally derived from cordrazine. Can be used to treat a wide range of injuries."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#8040FF"
|
||||
scannable = 1
|
||||
@@ -145,6 +155,7 @@
|
||||
name = "Cryoxadone"
|
||||
id = "cryoxadone"
|
||||
description = "A chemical mixture with almost magical healing powers. Its main limitation is that the targets body temperature must be under 170K for it to metabolise correctly."
|
||||
taste_description = "overripe bananas"
|
||||
reagent_state = LIQUID
|
||||
color = "#8080FF"
|
||||
metabolism = REM * 0.5
|
||||
@@ -162,6 +173,7 @@
|
||||
name = "Clonexadone"
|
||||
id = "clonexadone"
|
||||
description = "A liquid compound similar to that used in the cloning process. Can be used to 'finish' the cloning process when used in conjunction with a cryo tube."
|
||||
taste_description = "rotten bananas"
|
||||
reagent_state = LIQUID
|
||||
color = "#80BFFF"
|
||||
metabolism = REM * 0.5
|
||||
@@ -181,6 +193,7 @@
|
||||
name = "Paracetamol"
|
||||
id = "paracetamol"
|
||||
description = "Most probably know this as Tylenol, but this chemical is a mild, simple painkiller."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
overdose = 60
|
||||
@@ -199,6 +212,7 @@
|
||||
name = "Tramadol"
|
||||
id = "tramadol"
|
||||
description = "A simple, yet effective painkiller."
|
||||
taste_description = "sourness"
|
||||
reagent_state = LIQUID
|
||||
color = "#CB68FC"
|
||||
overdose = 30
|
||||
@@ -217,6 +231,7 @@
|
||||
name = "Oxycodone"
|
||||
id = "oxycodone"
|
||||
description = "An effective and very addictive painkiller."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#800080"
|
||||
overdose = 20
|
||||
@@ -239,6 +254,7 @@
|
||||
name = "Synaptizine"
|
||||
id = "synaptizine"
|
||||
description = "Synaptizine is used to treat various diseases."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#99CCFF"
|
||||
metabolism = REM * 0.05
|
||||
@@ -261,6 +277,7 @@
|
||||
name = "Alkysine"
|
||||
id = "alkysine"
|
||||
description = "Alkysine is a drug used to lessen the damage to neurological tissue after a catastrophic injury. Can heal brain tissue."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#FFFF66"
|
||||
metabolism = REM * 0.25
|
||||
@@ -277,6 +294,7 @@
|
||||
name = "Imidazoline"
|
||||
id = "imidazoline"
|
||||
description = "Heals eye damage"
|
||||
taste_description = "dull toxin"
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
@@ -300,6 +318,7 @@
|
||||
name = "Peridaxon"
|
||||
id = "peridaxon"
|
||||
description = "Used to encourage recovery of internal organs and nervous systems. Medicate cautiously."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#561EC3"
|
||||
overdose = 10
|
||||
@@ -371,6 +390,7 @@
|
||||
name = "Ryetalyn"
|
||||
id = "ryetalyn"
|
||||
description = "Ryetalyn can cure all genetic abnomalities via a catalytic process."
|
||||
taste_description = "acid"
|
||||
reagent_state = SOLID
|
||||
color = "#004000"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
@@ -391,6 +411,7 @@
|
||||
name = "Ethylredoxrazine"
|
||||
id = "ethylredoxrazine"
|
||||
description = "A powerful oxidizer that reacts with ethanol."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = SOLID
|
||||
color = "#605048"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
@@ -411,6 +432,7 @@
|
||||
name = "Hyronalin"
|
||||
id = "hyronalin"
|
||||
description = "Hyronalin is a medicinal drug used to counter the effect of radiation poisoning."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#408000"
|
||||
metabolism = REM * 0.25
|
||||
@@ -426,6 +448,7 @@
|
||||
name = "Arithrazine"
|
||||
id = "arithrazine"
|
||||
description = "Arithrazine is an unstable medication used for the most extreme cases of radiation poisoning."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#008000"
|
||||
metabolism = REM * 0.25
|
||||
@@ -444,6 +467,7 @@
|
||||
name = "Spaceacillin"
|
||||
id = "spaceacillin"
|
||||
description = "An all-purpose antiviral agent."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#C1C1C1"
|
||||
metabolism = REM * 0.05
|
||||
@@ -455,6 +479,7 @@
|
||||
name = "Sterilizine"
|
||||
id = "sterilizine"
|
||||
description = "Sterilizes wounds in preparation for surgery and thoroughly removes blood."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
touch_met = 5
|
||||
@@ -480,6 +505,7 @@
|
||||
name = "Leporazine"
|
||||
id = "leporazine"
|
||||
description = "Leporazine can be use to stabilize an individuals body temperature."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
@@ -523,6 +549,7 @@
|
||||
name = "Methylphenidate"
|
||||
id = "methylphenidate"
|
||||
description = "Improves the ability to concentrate."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#BF80BF"
|
||||
metabolism = 0.01
|
||||
@@ -544,6 +571,7 @@
|
||||
name = "Citalopram"
|
||||
id = "citalopram"
|
||||
description = "Stabilizes the mind a little."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#FF80FF"
|
||||
metabolism = 0.01
|
||||
@@ -565,6 +593,7 @@
|
||||
name = "Paroxetine"
|
||||
id = "paroxetine"
|
||||
description = "Stabilizes the mind greatly, but has a chance of adverse effects."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#FF80BF"
|
||||
metabolism = 0.01
|
||||
@@ -584,4 +613,25 @@
|
||||
M << "<span class='notice'>Your mind feels much more stable.</span>"
|
||||
else
|
||||
M << "<span class='warning'>Your mind breaks apart...</span>"
|
||||
M.hallucination += 200
|
||||
M.hallucination += 200
|
||||
|
||||
/datum/reagent/rezadone
|
||||
name = "Rezadone"
|
||||
id = "rezadone"
|
||||
description = "A powder with almost magical properties, this substance can effectively treat genetic damage in humanoids, though excessive consumption has side effects."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = SOLID
|
||||
color = "#669900"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
scannable = 1
|
||||
|
||||
/datum/reagent/rezadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
M.adjustCloneLoss(-20 * removed)
|
||||
M.adjustOxyLoss(-2 * removed)
|
||||
M.heal_organ_damage(20 * removed, 20 * removed)
|
||||
M.adjustToxLoss(-20 * removed)
|
||||
if(dose > 3)
|
||||
M.status_flags &= ~DISFIGURED
|
||||
if(dose > 10)
|
||||
M.make_dizzy(5)
|
||||
M.make_jittery(5)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
name = "Crayon dust"
|
||||
id = "crayon_dust"
|
||||
description = "Intensely coloured powder obtained by grinding crayons."
|
||||
taste_description = "powdered wax"
|
||||
reagent_state = LIQUID
|
||||
color = "#888888"
|
||||
overdose = 5
|
||||
@@ -52,6 +53,7 @@
|
||||
name = "Paint"
|
||||
id = "paint"
|
||||
description = "This paint will stick to almost any object."
|
||||
taste_description = "chalk"
|
||||
reagent_state = LIQUID
|
||||
color = "#808080"
|
||||
overdose = REAGENTS_OVERDOSE * 0.5
|
||||
@@ -108,6 +110,7 @@
|
||||
name = "Adminordrazine"
|
||||
id = "adminordrazine"
|
||||
description = "It's magic. We don't have to explain it."
|
||||
taste_description = "bwoink"
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
affects_dead = 1 //This can even heal dead people.
|
||||
@@ -146,6 +149,7 @@
|
||||
name = "Gold"
|
||||
id = "gold"
|
||||
description = "Gold is a dense, soft, shiny metal and the most malleable and ductile metal known."
|
||||
taste_description = "metal"
|
||||
reagent_state = SOLID
|
||||
color = "#F7C430"
|
||||
|
||||
@@ -153,6 +157,7 @@
|
||||
name = "Silver"
|
||||
id = "silver"
|
||||
description = "A soft, white, lustrous transition metal, it has the highest electrical conductivity of any element and the highest thermal conductivity of any metal."
|
||||
taste_description = "metal"
|
||||
reagent_state = SOLID
|
||||
color = "#D0D0D0"
|
||||
|
||||
@@ -160,6 +165,7 @@
|
||||
name ="Uranium"
|
||||
id = "uranium"
|
||||
description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive."
|
||||
taste_description = "metal"
|
||||
reagent_state = SOLID
|
||||
color = "#B8B8C0"
|
||||
|
||||
@@ -181,6 +187,7 @@
|
||||
name = "Adrenaline"
|
||||
id = "adrenaline"
|
||||
description = "Adrenaline is a hormone used as a drug to treat cardiac arrest and other cardiac dysrhythmias resulting in diminished or absent cardiac output."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
mrate_static = TRUE
|
||||
@@ -196,6 +203,7 @@
|
||||
name = "Holy Water"
|
||||
id = "holywater"
|
||||
description = "An ashen-obsidian-water mix, this solution will alter certain sections of the brain's rationality."
|
||||
taste_description = "water"
|
||||
color = "#E0E8EF"
|
||||
mrate_static = TRUE
|
||||
|
||||
@@ -217,6 +225,8 @@
|
||||
name = "Ammonia"
|
||||
id = "ammonia"
|
||||
description = "A caustic substance commonly used in fertilizer or household cleaners."
|
||||
taste_description = "mordant"
|
||||
taste_mult = 2
|
||||
reagent_state = GAS
|
||||
color = "#404030"
|
||||
|
||||
@@ -224,6 +234,7 @@
|
||||
name = "Diethylamine"
|
||||
id = "diethylamine"
|
||||
description = "A secondary amine, mildly corrosive."
|
||||
taste_description = "iron"
|
||||
reagent_state = LIQUID
|
||||
color = "#604030"
|
||||
|
||||
@@ -231,6 +242,7 @@
|
||||
name = "Fluorosurfactant"
|
||||
id = "fluorosurfactant"
|
||||
description = "A perfluoronated sulfonic acid that forms a foam when mixed with water."
|
||||
taste_description = "metal"
|
||||
reagent_state = LIQUID
|
||||
color = "#9E6B38"
|
||||
|
||||
@@ -238,6 +250,7 @@
|
||||
name = "Foaming agent"
|
||||
id = "foaming_agent"
|
||||
description = "A agent that yields metallic foam when mixed with light metal and a strong acid."
|
||||
taste_description = "metal"
|
||||
reagent_state = SOLID
|
||||
color = "#664B63"
|
||||
|
||||
@@ -245,6 +258,7 @@
|
||||
name = "Thermite"
|
||||
id = "thermite"
|
||||
description = "Thermite produces an aluminothermic reaction known as a thermite reaction. Can be used to melt walls."
|
||||
taste_description = "sweet tasting metal"
|
||||
reagent_state = SOLID
|
||||
color = "#673910"
|
||||
touch_met = 50
|
||||
@@ -269,6 +283,7 @@
|
||||
name = "Space cleaner"
|
||||
id = "cleaner"
|
||||
description = "A compound used to clean things. Now with 50% more sodium hypochlorite!"
|
||||
taste_description = "sourness"
|
||||
reagent_state = LIQUID
|
||||
color = "#A5F0EE"
|
||||
touch_met = 50
|
||||
@@ -317,6 +332,7 @@
|
||||
name = "Space Lube"
|
||||
id = "lube"
|
||||
description = "Lubricant is a substance introduced between two moving surfaces to reduce the friction and wear between them. giggity."
|
||||
taste_description = "slime"
|
||||
reagent_state = LIQUID
|
||||
color = "#009CA8"
|
||||
|
||||
@@ -330,6 +346,7 @@
|
||||
name = "Silicate"
|
||||
id = "silicate"
|
||||
description = "A compound that can be used to reinforce glass."
|
||||
taste_description = "plastic"
|
||||
reagent_state = LIQUID
|
||||
color = "#C7FFFF"
|
||||
|
||||
@@ -344,6 +361,7 @@
|
||||
name = "Glycerol"
|
||||
id = "glycerol"
|
||||
description = "Glycerol is a simple polyol compound. Glycerol is sweet-tasting and of low toxicity."
|
||||
taste_description = "sweetness"
|
||||
reagent_state = LIQUID
|
||||
color = "#808080"
|
||||
|
||||
@@ -351,6 +369,7 @@
|
||||
name = "Nitroglycerin"
|
||||
id = "nitroglycerin"
|
||||
description = "Nitroglycerin is a heavy, colorless, oily, explosive liquid obtained by nitrating glycerol."
|
||||
taste_description = "oil"
|
||||
reagent_state = LIQUID
|
||||
color = "#808080"
|
||||
|
||||
@@ -358,6 +377,8 @@
|
||||
name = "Coolant"
|
||||
id = "coolant"
|
||||
description = "Industrial cooling substance."
|
||||
taste_description = "sourness"
|
||||
taste_mult = 1.1
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
|
||||
@@ -365,12 +386,14 @@
|
||||
name = "Ultra Glue"
|
||||
id = "glue"
|
||||
description = "An extremely powerful bonding agent."
|
||||
taste_description = "a special education class"
|
||||
color = "#FFFFCC"
|
||||
|
||||
/datum/reagent/woodpulp
|
||||
name = "Wood Pulp"
|
||||
id = "woodpulp"
|
||||
description = "A mass of wood fibers."
|
||||
taste_description = "wood"
|
||||
reagent_state = LIQUID
|
||||
color = "#B97A57"
|
||||
|
||||
@@ -378,6 +401,7 @@
|
||||
name = "Luminol"
|
||||
id = "luminol"
|
||||
description = "A compound that interacts with blood on the molecular level."
|
||||
taste_description = "metal"
|
||||
reagent_state = LIQUID
|
||||
color = "#F2F3F4"
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/* Toxins, poisons, venoms */
|
||||
|
||||
/datum/reagent/toxin
|
||||
name = "Toxin"
|
||||
name = "toxin"
|
||||
id = "toxin"
|
||||
description = "A toxic chemical."
|
||||
taste_description = "bitterness"
|
||||
taste_mult = 1.2
|
||||
reagent_state = LIQUID
|
||||
color = "#CF3600"
|
||||
metabolism = REM * 0.25 // 0.05 by default. Hopefully enough to get some help, or die horribly, whatever floats your boat
|
||||
mrate_static = TRUE
|
||||
var/strength = 4 // How much damage it deals per unit
|
||||
|
||||
/datum/reagent/toxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
@@ -19,6 +20,7 @@
|
||||
name = "Plasticide"
|
||||
id = "plasticide"
|
||||
description = "Liquid plastic, do not eat."
|
||||
taste_description = "plastic"
|
||||
reagent_state = LIQUID
|
||||
color = "#CF3600"
|
||||
strength = 5
|
||||
@@ -27,6 +29,7 @@
|
||||
name = "Amatoxin"
|
||||
id = "amatoxin"
|
||||
description = "A powerful poison derived from certain species of mushroom."
|
||||
taste_description = "mushroom"
|
||||
reagent_state = LIQUID
|
||||
color = "#792300"
|
||||
strength = 10
|
||||
@@ -35,6 +38,7 @@
|
||||
name = "Carpotoxin"
|
||||
id = "carpotoxin"
|
||||
description = "A deadly neurotoxin produced by the dreaded space carp."
|
||||
taste_description = "fish"
|
||||
reagent_state = LIQUID
|
||||
color = "#003333"
|
||||
strength = 10
|
||||
@@ -50,6 +54,7 @@
|
||||
name = "Phoron"
|
||||
id = "phoron"
|
||||
description = "Phoron in its liquid form."
|
||||
taste_mult = 1.5
|
||||
reagent_state = LIQUID
|
||||
color = "#9D14DB"
|
||||
strength = 30
|
||||
@@ -84,6 +89,8 @@
|
||||
name = "Cyanide"
|
||||
id = "cyanide"
|
||||
description = "A highly toxic chemical."
|
||||
taste_description = "almond"
|
||||
taste_mult = 0.6
|
||||
reagent_state = LIQUID
|
||||
color = "#CF3600"
|
||||
strength = 20
|
||||
@@ -98,6 +105,7 @@
|
||||
name = "Hyperzine"
|
||||
id = "hyperzine"
|
||||
description = "Hyperzine is a highly effective, long lasting, muscle stimulant."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#FF3300"
|
||||
overdose = REAGENTS_OVERDOSE * 0.5
|
||||
@@ -115,6 +123,8 @@
|
||||
name = "Stimm"
|
||||
id = "stimm"
|
||||
description = "A homemade stimulant with some serious side-effects."
|
||||
taste_description = "sweetness"
|
||||
taste_mult = 1.8
|
||||
color = "#d0583a"
|
||||
metabolism = REM * 3
|
||||
overdose = 10
|
||||
@@ -135,6 +145,7 @@
|
||||
name = "Potassium Chloride"
|
||||
id = "potassium_chloride"
|
||||
description = "A delicious salt that stops the heart when injected into cardiac muscle."
|
||||
taste_description = "salt"
|
||||
reagent_state = SOLID
|
||||
color = "#FFFFFF"
|
||||
strength = 0
|
||||
@@ -154,6 +165,7 @@
|
||||
name = "Potassium Chlorophoride"
|
||||
id = "potassium_chlorophoride"
|
||||
description = "A specific chemical based on Potassium Chloride to stop the heart for surgery. Not safe to eat!"
|
||||
taste_description = "salt"
|
||||
reagent_state = SOLID
|
||||
color = "#FFFFFF"
|
||||
strength = 10
|
||||
@@ -173,6 +185,7 @@
|
||||
name = "Zombie Powder"
|
||||
id = "zombiepowder"
|
||||
description = "A strong neurotoxin that puts the subject into a death-like state."
|
||||
taste_description = "numbness"
|
||||
reagent_state = SOLID
|
||||
color = "#669900"
|
||||
metabolism = REM
|
||||
@@ -198,6 +211,8 @@
|
||||
name = "fertilizer"
|
||||
id = "fertilizer"
|
||||
description = "A chemical mix good for growing plants with."
|
||||
taste_description = "plant food"
|
||||
taste_mult = 0.5
|
||||
reagent_state = LIQUID
|
||||
strength = 0.5 // It's not THAT poisonous.
|
||||
color = "#664330"
|
||||
@@ -218,6 +233,7 @@
|
||||
name = "Plant-B-Gone"
|
||||
id = "plantbgone"
|
||||
description = "A harmful toxic mixture to kill plantlife. Do not ingest!"
|
||||
taste_mult = 1
|
||||
reagent_state = LIQUID
|
||||
color = "#49002E"
|
||||
strength = 4
|
||||
@@ -246,6 +262,7 @@
|
||||
name = "Polytrinic acid"
|
||||
id = "pacid"
|
||||
description = "Polytrinic acid is a an extremely corrosive chemical substance."
|
||||
taste_description = "acid"
|
||||
reagent_state = LIQUID
|
||||
color = "#8E18A9"
|
||||
power = 10
|
||||
@@ -255,6 +272,7 @@
|
||||
name = "Lexorin"
|
||||
id = "lexorin"
|
||||
description = "Lexorin temporarily stops respiration. Causes tissue damage."
|
||||
taste_description = "acid"
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
@@ -275,6 +293,8 @@
|
||||
name = "Unstable mutagen"
|
||||
id = "mutagen"
|
||||
description = "Might cause unpredictable mutations. Keep away from children."
|
||||
taste_description = "slime"
|
||||
taste_mult = 0.9
|
||||
reagent_state = LIQUID
|
||||
color = "#13BC5E"
|
||||
|
||||
@@ -310,6 +330,8 @@
|
||||
name = "Slime Jelly"
|
||||
id = "slimejelly"
|
||||
description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL."
|
||||
taste_description = "slime"
|
||||
taste_mult = 1.3
|
||||
reagent_state = LIQUID
|
||||
color = "#801E28"
|
||||
|
||||
@@ -326,6 +348,7 @@
|
||||
name = "Soporific"
|
||||
id = "stoxin"
|
||||
description = "An effective hypnotic used to treat insomnia."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#009CA8"
|
||||
metabolism = REM * 0.5
|
||||
@@ -360,6 +383,7 @@
|
||||
name = "Chloral Hydrate"
|
||||
id = "chloralhydrate"
|
||||
description = "A powerful sedative."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = SOLID
|
||||
color = "#000067"
|
||||
metabolism = REM * 0.5
|
||||
@@ -393,6 +417,7 @@
|
||||
name = "Beer"
|
||||
id = "beer2"
|
||||
description = "An alcoholic beverage made from malted grains, hops, yeast, and water. The fermentation appears to be incomplete." //If the players manage to analyze this, they deserve to know something is wrong.
|
||||
taste_description = "beer"
|
||||
reagent_state = LIQUID
|
||||
color = "#FFD300"
|
||||
|
||||
@@ -404,6 +429,8 @@
|
||||
name = "Space drugs"
|
||||
id = "space_drugs"
|
||||
description = "An illegal chemical compound used as drug."
|
||||
taste_description = "bitterness"
|
||||
taste_mult = 0.4
|
||||
reagent_state = LIQUID
|
||||
color = "#60A584"
|
||||
metabolism = REM * 0.5
|
||||
@@ -427,6 +454,7 @@
|
||||
name = "Serotrotium"
|
||||
id = "serotrotium"
|
||||
description = "A chemical compound that promotes concentrated production of the serotonin neurotransmitter in humans."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#202040"
|
||||
metabolism = REM * 0.25
|
||||
@@ -443,6 +471,7 @@
|
||||
name = "Cryptobiolin"
|
||||
id = "cryptobiolin"
|
||||
description = "Cryptobiolin causes confusion and dizzyness."
|
||||
taste_description = "sourness"
|
||||
reagent_state = LIQUID
|
||||
color = "#000055"
|
||||
metabolism = REM * 0.5
|
||||
@@ -461,6 +490,7 @@
|
||||
name = "Impedrezene"
|
||||
id = "impedrezene"
|
||||
description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions."
|
||||
taste_description = "numbness"
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
@@ -480,6 +510,7 @@
|
||||
name = "Mindbreaker Toxin"
|
||||
id = "mindbreaker"
|
||||
description = "A powerful hallucinogen, it can cause fatal effects in users."
|
||||
taste_description = "sourness"
|
||||
reagent_state = LIQUID
|
||||
color = "#B31008"
|
||||
metabolism = REM * 0.25
|
||||
@@ -498,6 +529,7 @@
|
||||
name = "Psilocybin"
|
||||
id = "psilocybin"
|
||||
description = "A strong psycotropic derived from certain species of mushroom."
|
||||
taste_description = "mushroom"
|
||||
color = "#E700E7"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
metabolism = REM * 0.5
|
||||
@@ -538,6 +570,7 @@
|
||||
name = "Nicotine"
|
||||
id = "nicotine"
|
||||
description = "A highly addictive stimulant extracted from the tobacco plant."
|
||||
taste_description = "bitterness"
|
||||
reagent_state = LIQUID
|
||||
color = "#181818"
|
||||
|
||||
@@ -547,6 +580,7 @@
|
||||
name = "Mutation Toxin"
|
||||
id = "mutationtoxin"
|
||||
description = "A corruptive toxin produced by slimes."
|
||||
taste_description = "sludge"
|
||||
reagent_state = LIQUID
|
||||
color = "#13BC5E"
|
||||
|
||||
@@ -573,6 +607,7 @@
|
||||
name = "Docility Toxin"
|
||||
id = "docilitytoxin"
|
||||
description = "A corruptive toxin produced by slimes."
|
||||
taste_description = "sludge"
|
||||
reagent_state = LIQUID
|
||||
color = "#FF69B4"
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
safe_thing = victim.glasses
|
||||
|
||||
if(safe_thing)
|
||||
trans = reagents.trans_to_obj(safe_thing, amount_per_transfer_from_this)
|
||||
trans = reagents.splash(safe_thing, amount_per_transfer_from_this, max_spill=30)
|
||||
user.visible_message("<span class='warning'>[user] tries to squirt something into [target]'s eyes, but fails!</span>", "<span class='notice'>You transfer [trans] units of the solution.</span>")
|
||||
return
|
||||
|
||||
@@ -67,14 +67,15 @@
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [name] to squirt [M.name] ([M.key]). Reagents: [contained]</font>")
|
||||
msg_admin_attack("[user.name] ([user.ckey]) squirted [M.name] ([M.key]) with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
trans = reagents.trans_to_mob(target, reagents.total_volume, CHEM_INGEST)
|
||||
trans += reagents.splash(target, reagents.total_volume/2, max_spill=30)
|
||||
trans += reagents.trans_to_mob(target, reagents.total_volume/2, CHEM_BLOOD) //I guess it gets into the bloodstream through the eyes or something
|
||||
user.visible_message("<span class='warning'>[user] squirts something into [target]'s eyes!</span>", "<span class='notice'>You transfer [trans] units of the solution.</span>")
|
||||
|
||||
|
||||
return
|
||||
|
||||
else
|
||||
trans = reagents.trans_to(target, amount_per_transfer_from_this) //sprinkling reagents on generic non-mobs
|
||||
trans = reagents.splash(target, amount_per_transfer_from_this, max_spill=30) //sprinkling reagents on generic non-mobs
|
||||
user << "<span class='notice'>You transfer [trans] units of the solution.</span>"
|
||||
|
||||
else // Taking from something
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@
|
||||
var/image/filling //holds a reference to the current filling overlay
|
||||
var/visible_name = "a syringe"
|
||||
var/time = 30
|
||||
var/drawing = 0
|
||||
|
||||
/obj/item/weapon/reagent_containers/syringe/on_reagent_change()
|
||||
update_icon()
|
||||
@@ -98,7 +99,12 @@
|
||||
user << "<span class='warning'>You are unable to locate any blood.</span>"
|
||||
return
|
||||
|
||||
if(drawing)
|
||||
user << "<span class='warning'>You are already drawing blood from [T.name].</span>"
|
||||
return
|
||||
|
||||
var/datum/reagent/B
|
||||
drawing = 1
|
||||
if(istype(T, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = T
|
||||
if(H.species && !H.should_have_organ(O_HEART))
|
||||
@@ -106,12 +112,16 @@
|
||||
else
|
||||
if(ismob(H) && H != user)
|
||||
if(!do_mob(user, target, time))
|
||||
drawing = 0
|
||||
return
|
||||
B = T.take_blood(src, amount)
|
||||
drawing = 0
|
||||
else
|
||||
if(!do_mob(user, target, time))
|
||||
drawing = 0
|
||||
return
|
||||
B = T.take_blood(src,amount)
|
||||
drawing = 0
|
||||
|
||||
if (B)
|
||||
reagents.reagent_list += B
|
||||
@@ -200,7 +210,10 @@
|
||||
admin_inject_log(user, target, src, contained, trans)
|
||||
else
|
||||
trans = reagents.trans_to(target, amount_per_transfer_from_this)
|
||||
user << "<span class='notice'>You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units.</span>"
|
||||
if(trans)
|
||||
user << "<span class='notice'>You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units.</span>"
|
||||
else
|
||||
user << "<span class='notice'>The syringe is empty.</span>"
|
||||
if (reagents.total_volume <= 0 && mode == SYRINGE_INJECT)
|
||||
mode = SYRINGE_DRAW
|
||||
update_icon()
|
||||
|
||||
@@ -65,6 +65,32 @@
|
||||
|
||||
|
||||
|
||||
/datum/unit_test/integrated_circuits/not_equals_1
|
||||
name = "Logic Circuits: Not Equals - String True"
|
||||
circuit_type = /obj/item/integrated_circuit/logic/binary/not_equals
|
||||
inputs_to_give = list("Test", "Nope")
|
||||
expected_outputs = list(TRUE)
|
||||
|
||||
/datum/unit_test/integrated_circuits/not_equals_2
|
||||
name = "Logic Circuits: Not Equals - String False"
|
||||
circuit_type = /obj/item/integrated_circuit/logic/binary/not_equals
|
||||
inputs_to_give = list("Test", "Test")
|
||||
expected_outputs = list(FALSE)
|
||||
|
||||
/datum/unit_test/integrated_circuits/not_equals_3
|
||||
name = "Logic Circuits: Not Equals - Number True"
|
||||
circuit_type = /obj/item/integrated_circuit/logic/binary/not_equals
|
||||
inputs_to_give = list(150, 20)
|
||||
expected_outputs = list(TRUE)
|
||||
|
||||
/datum/unit_test/integrated_circuits/not_equals_4
|
||||
name = "Logic Circuits: Not Equals - Number False"
|
||||
circuit_type = /obj/item/integrated_circuit/logic/binary/not_equals
|
||||
inputs_to_give = list(100, 100)
|
||||
expected_outputs = list(FALSE)
|
||||
|
||||
|
||||
|
||||
/datum/unit_test/integrated_circuits/and_1
|
||||
name = "Logic Circuits: And - True"
|
||||
circuit_type = /obj/item/integrated_circuit/logic/binary/and
|
||||
|
||||
Reference in New Issue
Block a user