mirror of
https://github.com/Aurorastation/Aurora-Old.git
synced 2026-08-29 07:36:18 +01:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
/*///////////////Circuit Imprinter (By Darem)////////////////////////
|
||||
Used to print new circuit boards (for computers and similar systems) and AI modules. Each circuit board pattern are stored in
|
||||
a /datum/desgin on the linked R&D console. You can then print them out in a fasion similar to a regular lathe. However, instead of
|
||||
using metal and glass, it uses glass and reagents (usually sulfuric acis).
|
||||
|
||||
*/
|
||||
/obj/machinery/r_n_d/circuit_imprinter
|
||||
name = "Circuit Imprinter"
|
||||
icon_state = "circuit_imprinter"
|
||||
flags = OPENCONTAINER
|
||||
|
||||
var/g_amount = 0
|
||||
var/gold_amount = 0
|
||||
var/diamond_amount = 0
|
||||
var/uranium_amount = 0
|
||||
var/max_material_amount = 75000.0
|
||||
|
||||
New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/circuit_imprinter(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
|
||||
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
|
||||
RefreshParts()
|
||||
|
||||
RefreshParts()
|
||||
var/T = 0
|
||||
for(var/obj/item/weapon/reagent_containers/glass/G in component_parts)
|
||||
T += G.reagents.maximum_volume
|
||||
var/datum/reagents/R = new/datum/reagents(T) //Holder for the reagents used as materials.
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
T = 0
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
|
||||
T += M.rating
|
||||
max_material_amount = T * 75000.0
|
||||
|
||||
|
||||
blob_act()
|
||||
if (prob(50))
|
||||
del(src)
|
||||
|
||||
meteorhit()
|
||||
del(src)
|
||||
return
|
||||
|
||||
proc/TotalMaterials()
|
||||
return g_amount + gold_amount + diamond_amount + uranium_amount
|
||||
|
||||
attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if (shocked)
|
||||
shock(user,50)
|
||||
if (istype(O, /obj/item/weapon/screwdriver))
|
||||
if (!opened)
|
||||
opened = 1
|
||||
if(linked_console)
|
||||
linked_console.linked_imprinter = null
|
||||
linked_console = null
|
||||
icon_state = "circuit_imprinter_t"
|
||||
user << "You open the maintenance hatch of [src]."
|
||||
else
|
||||
opened = 0
|
||||
icon_state = "circuit_imprinter"
|
||||
user << "You close the maintenance hatch of [src]."
|
||||
return
|
||||
if (opened)
|
||||
if(istype(O, /obj/item/weapon/crowbar))
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc)
|
||||
M.state = 2
|
||||
M.icon_state = "box_1"
|
||||
for(var/obj/I in component_parts)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker))
|
||||
reagents.trans_to(I, reagents.total_volume)
|
||||
if(I.reliability != 100 && crit_fail)
|
||||
I.crit_fail = 1
|
||||
I.loc = src.loc
|
||||
if(g_amount >= 3750)
|
||||
var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc)
|
||||
G.amount = round(g_amount / 3750)
|
||||
if(gold_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(src.loc)
|
||||
G.amount = round(gold_amount / 2000)
|
||||
if(diamond_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(src.loc)
|
||||
G.amount = round(diamond_amount / 2000)
|
||||
if(uranium_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(src.loc)
|
||||
G.amount = round(uranium_amount / 2000)
|
||||
del(src)
|
||||
return 1
|
||||
else
|
||||
user << "\red You can't load the [src.name] while it's opened."
|
||||
return 1
|
||||
if (disabled)
|
||||
user << "\The [name] appears to not be working!"
|
||||
return
|
||||
if (!linked_console)
|
||||
user << "\The [name] must be linked to an R&D console first!"
|
||||
return 1
|
||||
if (O.is_open_container())
|
||||
return 0
|
||||
if (!istype(O, /obj/item/stack/sheet/glass) && !istype(O, /obj/item/stack/sheet/mineral/gold) && !istype(O, /obj/item/stack/sheet/mineral/diamond) && !istype(O, /obj/item/stack/sheet/mineral/uranium))
|
||||
user << "\red You cannot insert this item into the [name]!"
|
||||
return 1
|
||||
if (stat)
|
||||
return 1
|
||||
if (busy)
|
||||
user << "\red The [name] is busy. Please wait for completion of previous operation."
|
||||
return 1
|
||||
var/obj/item/stack/sheet/stack = O
|
||||
if ((TotalMaterials() + stack.perunit) > max_material_amount)
|
||||
user << "\red The [name] is full. Please remove glass from the protolathe in order to insert more."
|
||||
return 1
|
||||
|
||||
var/amount = round(input("How many sheets do you want to add?") as num)
|
||||
if(amount < 0)
|
||||
amount = 0
|
||||
if(amount == 0)
|
||||
return
|
||||
if(amount > stack.amount)
|
||||
amount = min(stack.amount, round((max_material_amount-TotalMaterials())/stack.perunit))
|
||||
|
||||
busy = 1
|
||||
use_power(max(1000, (3750*amount/10)))
|
||||
var/stacktype = stack.type
|
||||
stack.use(amount)
|
||||
if(do_after(usr,16))
|
||||
user << "\blue You add [amount] sheets to the [src.name]."
|
||||
switch(stacktype)
|
||||
if(/obj/item/stack/sheet/glass)
|
||||
g_amount += amount * 3750
|
||||
if(/obj/item/stack/sheet/mineral/gold)
|
||||
gold_amount += amount * 2000
|
||||
if(/obj/item/stack/sheet/mineral/diamond)
|
||||
diamond_amount += amount * 2000
|
||||
if(/obj/item/stack/sheet/mineral/uranium)
|
||||
uranium_amount += amount * 2000
|
||||
else
|
||||
new stacktype(src.loc, amount)
|
||||
busy = 0
|
||||
src.updateUsrDialog()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,113 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
||||
|
||||
/*
|
||||
Destructive Analyzer
|
||||
|
||||
It is used to destroy hand-held objects and advance technological research. Controls are in the linked R&D console.
|
||||
|
||||
Note: Must be placed within 3 tiles of the R&D Console
|
||||
*/
|
||||
/obj/machinery/r_n_d/destructive_analyzer
|
||||
name = "Destructive Analyzer"
|
||||
icon_state = "d_analyzer"
|
||||
var/obj/item/weapon/loaded_item = null
|
||||
var/decon_mod = 1
|
||||
|
||||
/obj/machinery/r_n_d/destructive_analyzer/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/destructive_analyzer(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/r_n_d/destructive_analyzer/RefreshParts()
|
||||
var/T = 0
|
||||
for(var/obj/item/weapon/stock_parts/S in src)
|
||||
T += S.rating * 0.1
|
||||
T = between (0, T, 1)
|
||||
decon_mod = T
|
||||
|
||||
/obj/machinery/r_n_d/destructive_analyzer/meteorhit()
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/machinery/r_n_d/destructive_analyzer/proc/ConvertReqString2List(var/list/source_list)
|
||||
var/list/temp_list = params2list(source_list)
|
||||
for(var/O in temp_list)
|
||||
temp_list[O] = text2num(temp_list[O])
|
||||
return temp_list
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/destructive_analyzer/attackby(var/obj/O as obj, var/mob/user as mob)
|
||||
if (shocked)
|
||||
shock(user,50)
|
||||
if (istype(O, /obj/item/weapon/screwdriver))
|
||||
if (!opened)
|
||||
opened = 1
|
||||
if(linked_console)
|
||||
linked_console.linked_destroy = null
|
||||
linked_console = null
|
||||
icon_state = "d_analyzer_t"
|
||||
user << "You open the maintenance hatch of [src]."
|
||||
else
|
||||
opened = 0
|
||||
icon_state = "d_analyzer"
|
||||
user << "You close the maintenance hatch of [src]."
|
||||
return
|
||||
if (opened)
|
||||
if(istype(O, /obj/item/weapon/crowbar))
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc)
|
||||
M.state = 2
|
||||
M.icon_state = "box_1"
|
||||
for(var/obj/I in component_parts)
|
||||
I.loc = src.loc
|
||||
del(src)
|
||||
return 1
|
||||
else
|
||||
user << "\red You can't load the [src.name] while it's opened."
|
||||
return 1
|
||||
if (disabled)
|
||||
return
|
||||
if (!linked_console)
|
||||
user << "\red The destructive analyzer must be linked to an R&D console first!"
|
||||
return
|
||||
if (busy)
|
||||
user << "\red The destructive analyzer is busy right now."
|
||||
return
|
||||
if (istype(O, /obj/item) && !loaded_item)
|
||||
if(isrobot(user)) //Don't put your module items in there!
|
||||
return
|
||||
if(!O.origin_tech)
|
||||
user << "\red This doesn't seem to have a tech origin!"
|
||||
return
|
||||
var/list/temp_tech = ConvertReqString2List(O.origin_tech)
|
||||
if (temp_tech.len == 0)
|
||||
user << "\red You cannot deconstruct this item!"
|
||||
return
|
||||
if(O.reliability < 90 && O.crit_fail == 0)
|
||||
usr << "\red Item is neither reliable enough nor broken enough to learn from."
|
||||
return
|
||||
busy = 1
|
||||
loaded_item = O
|
||||
user.drop_item()
|
||||
O.loc = src
|
||||
user << "\blue You add the [O.name] to the machine!"
|
||||
flick("d_analyzer_la", src)
|
||||
spawn(10)
|
||||
icon_state = "d_analyzer_l"
|
||||
busy = 0
|
||||
return 1
|
||||
return
|
||||
|
||||
//For testing purposes only.
|
||||
/*/obj/item/weapon/deconstruction_test
|
||||
name = "Test Item"
|
||||
desc = "WTF?"
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "d20"
|
||||
g_amt = 5000
|
||||
m_amt = 5000
|
||||
origin_tech = "materials=5;plasmatech=5;syndicate=5;programming=9"*/
|
||||
@@ -0,0 +1,355 @@
|
||||
var/global/list/obj/machinery/message_server/message_servers = list()
|
||||
|
||||
/datum/data_pda_msg
|
||||
var/recipient = "Unspecified" //name of the person
|
||||
var/sender = "Unspecified" //name of the sender
|
||||
var/message = "Blank" //transferred message
|
||||
|
||||
/datum/data_pda_msg/New(var/param_rec = "",var/param_sender = "",var/param_message = "")
|
||||
|
||||
if(param_rec)
|
||||
recipient = param_rec
|
||||
if(param_sender)
|
||||
sender = param_sender
|
||||
if(param_message)
|
||||
message = param_message
|
||||
|
||||
/datum/data_rc_msg
|
||||
var/rec_dpt = "Unspecified" //name of the person
|
||||
var/send_dpt = "Unspecified" //name of the sender
|
||||
var/message = "Blank" //transferred message
|
||||
var/stamp = "Unstamped"
|
||||
var/id_auth = "Unauthenticated"
|
||||
var/priority = "Normal"
|
||||
|
||||
/datum/data_rc_msg/New(var/param_rec = "",var/param_sender = "",var/param_message = "",var/param_stamp = "",var/param_id_auth = "",var/param_priority)
|
||||
if(param_rec)
|
||||
rec_dpt = param_rec
|
||||
if(param_sender)
|
||||
send_dpt = param_sender
|
||||
if(param_message)
|
||||
message = param_message
|
||||
if(param_stamp)
|
||||
stamp = param_stamp
|
||||
if(param_id_auth)
|
||||
id_auth = param_id_auth
|
||||
if(param_priority)
|
||||
switch(param_priority)
|
||||
if(1)
|
||||
priority = "Normal"
|
||||
if(2)
|
||||
priority = "High"
|
||||
if(3)
|
||||
priority = "Extreme"
|
||||
else
|
||||
priority = "Undetermined"
|
||||
|
||||
/obj/machinery/message_server
|
||||
icon = 'icons/obj/machines/research.dmi'
|
||||
icon_state = "server"
|
||||
name = "Messaging Server"
|
||||
density = 1
|
||||
anchored = 1.0
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 100
|
||||
|
||||
var/list/datum/data_pda_msg/pda_msgs = list()
|
||||
var/list/datum/data_rc_msg/rc_msgs = list()
|
||||
var/active = 1
|
||||
var/decryptkey = "password"
|
||||
|
||||
/obj/machinery/message_server/New()
|
||||
message_servers += src
|
||||
decryptkey = GenerateKey()
|
||||
send_pda_message("System Administrator", "system", "This is an automated message. The messaging system is functioning correctly.")
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/message_server/Del()
|
||||
message_servers -= src
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/message_server/proc/GenerateKey()
|
||||
//Feel free to move to Helpers.
|
||||
var/newKey
|
||||
newKey += pick("the", "if", "of", "as", "in", "a", "you", "from", "to", "an", "too", "little", "snow", "dead", "drunk", "rosebud", "duck", "al", "le")
|
||||
newKey += pick("diamond", "beer", "mushroom", "assistant", "clown", "captain", "twinkie", "security", "nuke", "small", "big", "escape", "yellow", "gloves", "monkey", "engine", "nuclear", "ai")
|
||||
newKey += pick("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
|
||||
return newKey
|
||||
|
||||
/obj/machinery/message_server/process()
|
||||
//if(decryptkey == "password")
|
||||
// decryptkey = generateKey()
|
||||
if(active && (stat & (BROKEN|NOPOWER)))
|
||||
active = 0
|
||||
return
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/message_server/proc/send_pda_message(var/recipient = "",var/sender = "",var/message = "")
|
||||
pda_msgs += new/datum/data_pda_msg(recipient,sender,message)
|
||||
|
||||
/obj/machinery/message_server/proc/send_rc_message(var/recipient = "",var/sender = "",var/message = "",var/stamp = "", var/id_auth = "", var/priority = 1)
|
||||
rc_msgs += new/datum/data_rc_msg(recipient,sender,message,stamp,id_auth)
|
||||
|
||||
/obj/machinery/message_server/attack_hand(user as mob)
|
||||
// user << "\blue There seem to be some parts missing from this server. They should arrive on the station in a few days, give or take a few CentCom delays."
|
||||
user << "You toggle PDA message passing from [active ? "On" : "Off"] to [active ? "Off" : "On"]"
|
||||
active = !active
|
||||
update_icon()
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/message_server/update_icon()
|
||||
if((stat & (BROKEN|NOPOWER)))
|
||||
icon_state = "server-nopower"
|
||||
else if (!active)
|
||||
icon_state = "server-off"
|
||||
else
|
||||
icon_state = "server-on"
|
||||
|
||||
return
|
||||
|
||||
|
||||
/datum/feedback_variable
|
||||
var/variable
|
||||
var/value
|
||||
var/details
|
||||
|
||||
/datum/feedback_variable/New(var/param_variable,var/param_value = 0)
|
||||
variable = param_variable
|
||||
value = param_value
|
||||
|
||||
/datum/feedback_variable/proc/inc(var/num = 1)
|
||||
if(isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = text2num(value)
|
||||
if(isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/dec(var/num = 1)
|
||||
if(isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = text2num(value)
|
||||
if(isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = -num
|
||||
|
||||
/datum/feedback_variable/proc/set_value(var/num)
|
||||
if(isnum(num))
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/get_value()
|
||||
return value
|
||||
|
||||
/datum/feedback_variable/proc/get_variable()
|
||||
return variable
|
||||
|
||||
/datum/feedback_variable/proc/set_details(var/text)
|
||||
if(istext(text))
|
||||
details = text
|
||||
|
||||
/datum/feedback_variable/proc/add_details(var/text)
|
||||
if(istext(text))
|
||||
if(!details)
|
||||
details = text
|
||||
else
|
||||
details += " [text]"
|
||||
|
||||
/datum/feedback_variable/proc/get_details()
|
||||
return details
|
||||
|
||||
/datum/feedback_variable/proc/get_parsed()
|
||||
return list(variable,value,details)
|
||||
|
||||
var/obj/machinery/blackbox_recorder/blackbox
|
||||
|
||||
/obj/machinery/blackbox_recorder
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "blackbox"
|
||||
name = "Blackbox Recorder"
|
||||
density = 1
|
||||
anchored = 1.0
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 100
|
||||
var/list/messages = list() //Stores messages of non-standard frequencies
|
||||
var/list/messages_admin = list()
|
||||
|
||||
var/list/msg_common = list()
|
||||
var/list/msg_science = list()
|
||||
var/list/msg_command = list()
|
||||
var/list/msg_medical = list()
|
||||
var/list/msg_engineering = list()
|
||||
var/list/msg_security = list()
|
||||
var/list/msg_deathsquad = list()
|
||||
var/list/msg_syndicate = list()
|
||||
var/list/msg_mining = list()
|
||||
var/list/msg_cargo = list()
|
||||
|
||||
var/list/datum/feedback_variable/feedback = new()
|
||||
|
||||
//Only one can exsist in the world!
|
||||
/obj/machinery/blackbox_recorder/New()
|
||||
if(blackbox)
|
||||
if(istype(blackbox,/obj/machinery/blackbox_recorder))
|
||||
del(src)
|
||||
blackbox = src
|
||||
|
||||
/obj/machinery/blackbox_recorder/Del()
|
||||
var/turf/T = locate(1,1,2)
|
||||
if(T)
|
||||
blackbox = null
|
||||
var/obj/machinery/blackbox_recorder/BR = new/obj/machinery/blackbox_recorder(T)
|
||||
BR.msg_common = msg_common
|
||||
BR.msg_science = msg_science
|
||||
BR.msg_command = msg_command
|
||||
BR.msg_medical = msg_medical
|
||||
BR.msg_engineering = msg_engineering
|
||||
BR.msg_security = msg_security
|
||||
BR.msg_deathsquad = msg_deathsquad
|
||||
BR.msg_syndicate = msg_syndicate
|
||||
BR.msg_mining = msg_mining
|
||||
BR.msg_cargo = msg_cargo
|
||||
BR.feedback = feedback
|
||||
BR.messages = messages
|
||||
BR.messages_admin = messages_admin
|
||||
if(blackbox != BR)
|
||||
blackbox = BR
|
||||
..()
|
||||
|
||||
/obj/machinery/blackbox_recorder/proc/find_feedback_datum(var/variable)
|
||||
for(var/datum/feedback_variable/FV in feedback)
|
||||
if(FV.get_variable() == variable)
|
||||
return FV
|
||||
var/datum/feedback_variable/FV = new(variable)
|
||||
feedback += FV
|
||||
return FV
|
||||
|
||||
/obj/machinery/blackbox_recorder/proc/get_round_feedback()
|
||||
return feedback
|
||||
|
||||
/obj/machinery/blackbox_recorder/proc/round_end_data_gathering()
|
||||
|
||||
var/pda_msg_amt = 0
|
||||
var/rc_msg_amt = 0
|
||||
|
||||
for(var/obj/machinery/message_server/MS in machines)
|
||||
if(MS.pda_msgs.len > pda_msg_amt)
|
||||
pda_msg_amt = MS.pda_msgs.len
|
||||
if(MS.rc_msgs.len > rc_msg_amt)
|
||||
rc_msg_amt = MS.rc_msgs.len
|
||||
|
||||
feedback_set_details("radio_usage","")
|
||||
|
||||
feedback_add_details("radio_usage","COM-[msg_common.len]")
|
||||
feedback_add_details("radio_usage","SCI-[msg_science.len]")
|
||||
feedback_add_details("radio_usage","HEA-[msg_command.len]")
|
||||
feedback_add_details("radio_usage","MED-[msg_medical.len]")
|
||||
feedback_add_details("radio_usage","ENG-[msg_engineering.len]")
|
||||
feedback_add_details("radio_usage","SEC-[msg_security.len]")
|
||||
feedback_add_details("radio_usage","DTH-[msg_deathsquad.len]")
|
||||
feedback_add_details("radio_usage","SYN-[msg_syndicate.len]")
|
||||
feedback_add_details("radio_usage","MIN-[msg_mining.len]")
|
||||
feedback_add_details("radio_usage","CAR-[msg_cargo.len]")
|
||||
feedback_add_details("radio_usage","OTH-[messages.len]")
|
||||
feedback_add_details("radio_usage","PDA-[pda_msg_amt]")
|
||||
feedback_add_details("radio_usage","RC-[rc_msg_amt]")
|
||||
|
||||
|
||||
feedback_set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
|
||||
|
||||
|
||||
//This proc is only to be called at round end.
|
||||
/obj/machinery/blackbox_recorder/proc/save_all_data_to_sql()
|
||||
if(!feedback) return
|
||||
|
||||
round_end_data_gathering() //round_end time logging and some other data processing
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected()) return
|
||||
var/round_id
|
||||
|
||||
var/DBQuery/query = dbcon.NewQuery("SELECT MAX(round_id) AS round_id FROM erro_feedback")
|
||||
query.Execute()
|
||||
while(query.NextRow())
|
||||
round_id = query.item[1]
|
||||
|
||||
if(!isnum(round_id))
|
||||
round_id = text2num(round_id)
|
||||
round_id++
|
||||
|
||||
for(var/datum/feedback_variable/FV in feedback)
|
||||
var/sql = "INSERT INTO erro_feedback VALUES (null, Now(), [round_id], \"[FV.get_variable()]\", [FV.get_value()], \"[FV.get_details()]\")"
|
||||
var/DBQuery/query_insert = dbcon.NewQuery(sql)
|
||||
query_insert.Execute()
|
||||
|
||||
// Sanitize inputs to avoid SQL injection attacks
|
||||
proc/sql_sanitize_text(var/text)
|
||||
text = replacetext(text, "'", "''")
|
||||
text = replacetext(text, ";", "")
|
||||
text = replacetext(text, "&", "")
|
||||
return text
|
||||
|
||||
proc/feedback_set(var/variable,var/value)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
|
||||
FV.set_value(value)
|
||||
|
||||
proc/feedback_inc(var/variable,var/value)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
|
||||
FV.inc(value)
|
||||
|
||||
proc/feedback_dec(var/variable,var/value)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
|
||||
FV.dec(value)
|
||||
|
||||
proc/feedback_set_details(var/variable,var/details)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
details = sql_sanitize_text(details)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
|
||||
FV.set_details(details)
|
||||
|
||||
proc/feedback_add_details(var/variable,var/details)
|
||||
if(!blackbox) return
|
||||
|
||||
variable = sql_sanitize_text(variable)
|
||||
details = sql_sanitize_text(details)
|
||||
|
||||
var/datum/feedback_variable/FV = blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV) return
|
||||
|
||||
FV.add_details(details)
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
Protolathe
|
||||
|
||||
Similar to an autolathe, you load glass and metal sheets (but not other objects) into it to be used as raw materials for the stuff
|
||||
it creates. All the menus and other manipulation commands are in the R&D console.
|
||||
|
||||
Note: Must be placed west/left of and R&D console to function.
|
||||
|
||||
*/
|
||||
/obj/machinery/r_n_d/protolathe
|
||||
name = "Protolathe"
|
||||
icon_state = "protolathe"
|
||||
flags = OPENCONTAINER
|
||||
|
||||
var/max_material_storage = 100000 //All this could probably be done better with a list but meh.
|
||||
var/m_amount = 0.0
|
||||
var/g_amount = 0.0
|
||||
var/gold_amount = 0.0
|
||||
var/silver_amount = 0.0
|
||||
var/plasma_amount = 0.0
|
||||
var/uranium_amount = 0.0
|
||||
var/diamond_amount = 0.0
|
||||
var/clown_amount = 0.0
|
||||
var/adamantine_amount = 0.0
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/protolathe/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/protolathe(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
|
||||
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/r_n_d/protolathe/proc/TotalMaterials() //returns the total of all the stored materials. Makes code neater.
|
||||
return m_amount + g_amount + gold_amount + silver_amount + plasma_amount + uranium_amount + diamond_amount + clown_amount
|
||||
|
||||
/obj/machinery/r_n_d/protolathe/RefreshParts()
|
||||
var/T = 0
|
||||
for(var/obj/item/weapon/reagent_containers/glass/G in component_parts)
|
||||
T += G.reagents.maximum_volume
|
||||
var/datum/reagents/R = new/datum/reagents(T) //Holder for the reagents used as materials.
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
T = 0
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
|
||||
T += M.rating
|
||||
max_material_storage = T * 75000
|
||||
|
||||
/obj/machinery/r_n_d/protolathe/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if (shocked)
|
||||
shock(user,50)
|
||||
if (O.is_open_container())
|
||||
return 1
|
||||
if (istype(O, /obj/item/weapon/screwdriver))
|
||||
if (!opened)
|
||||
opened = 1
|
||||
if(linked_console)
|
||||
linked_console.linked_lathe = null
|
||||
linked_console = null
|
||||
icon_state = "protolathe_t"
|
||||
user << "You open the maintenance hatch of [src]."
|
||||
else
|
||||
opened = 0
|
||||
icon_state = "protolathe"
|
||||
user << "You close the maintenance hatch of [src]."
|
||||
return
|
||||
if (opened)
|
||||
if(istype(O, /obj/item/weapon/crowbar))
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc)
|
||||
M.state = 2
|
||||
M.icon_state = "box_1"
|
||||
for(var/obj/I in component_parts)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker))
|
||||
reagents.trans_to(I, reagents.total_volume)
|
||||
if(I.reliability != 100 && crit_fail)
|
||||
I.crit_fail = 1
|
||||
I.loc = src.loc
|
||||
if(m_amount >= 3750)
|
||||
var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(src.loc)
|
||||
G.amount = round(m_amount / G.perunit)
|
||||
if(g_amount >= 3750)
|
||||
var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc)
|
||||
G.amount = round(g_amount / G.perunit)
|
||||
if(plasma_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/plasma/G = new /obj/item/stack/sheet/mineral/plasma(src.loc)
|
||||
G.amount = round(plasma_amount / G.perunit)
|
||||
if(silver_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/silver/G = new /obj/item/stack/sheet/mineral/silver(src.loc)
|
||||
G.amount = round(silver_amount / G.perunit)
|
||||
if(gold_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(src.loc)
|
||||
G.amount = round(gold_amount / G.perunit)
|
||||
if(uranium_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(src.loc)
|
||||
G.amount = round(uranium_amount / G.perunit)
|
||||
if(diamond_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(src.loc)
|
||||
G.amount = round(diamond_amount / G.perunit)
|
||||
if(clown_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/clown/G = new /obj/item/stack/sheet/mineral/clown(src.loc)
|
||||
G.amount = round(clown_amount / G.perunit)
|
||||
if(adamantine_amount >= 2000)
|
||||
var/obj/item/stack/sheet/mineral/adamantine/G = new /obj/item/stack/sheet/mineral/adamantine(src.loc)
|
||||
G.amount = round(adamantine_amount / G.perunit)
|
||||
del(src)
|
||||
return 1
|
||||
else
|
||||
user << "\red You can't load the [src.name] while it's opened."
|
||||
return 1
|
||||
if (disabled)
|
||||
return
|
||||
if (!linked_console)
|
||||
user << "\The protolathe must be linked to an R&D console first!"
|
||||
return 1
|
||||
if (busy)
|
||||
user << "\red The protolathe is busy. Please wait for completion of previous operation."
|
||||
return 1
|
||||
if (!istype(O, /obj/item/stack/sheet))
|
||||
user << "\red You cannot insert this item into the protolathe!"
|
||||
return 1
|
||||
if (stat)
|
||||
return 1
|
||||
if(istype(O,/obj/item/stack/sheet))
|
||||
var/obj/item/stack/sheet/S = O
|
||||
if (TotalMaterials() + S.perunit > max_material_storage)
|
||||
user << "\red The protolathe's material bin is full. Please remove material before adding more."
|
||||
return 1
|
||||
|
||||
var/obj/item/stack/sheet/stack = O
|
||||
var/amount = round(input("How many sheets do you want to add?") as num)//No decimals
|
||||
if(!O)
|
||||
return
|
||||
if(amount < 0)//No negative numbers
|
||||
amount = 0
|
||||
if(amount == 0)
|
||||
return
|
||||
if(amount > stack.amount)
|
||||
amount = stack.amount
|
||||
if(max_material_storage - TotalMaterials() < (amount*stack.perunit))//Can't overfill
|
||||
amount = min(stack.amount, round((max_material_storage-TotalMaterials())/stack.perunit))
|
||||
|
||||
src.overlays += "protolathe_[stack.name]"
|
||||
sleep(10)
|
||||
src.overlays -= "protolathe_[stack.name]"
|
||||
|
||||
icon_state = "protolathe"
|
||||
busy = 1
|
||||
use_power(max(1000, (3750*amount/10)))
|
||||
var/stacktype = stack.type
|
||||
stack.use(amount)
|
||||
if (do_after(user, 16))
|
||||
user << "\blue You add [amount] sheets to the [src.name]."
|
||||
icon_state = "protolathe"
|
||||
switch(stacktype)
|
||||
if(/obj/item/stack/sheet/metal)
|
||||
m_amount += amount * 3750
|
||||
if(/obj/item/stack/sheet/glass)
|
||||
g_amount += amount * 3750
|
||||
if(/obj/item/stack/sheet/mineral/gold)
|
||||
gold_amount += amount * 2000
|
||||
if(/obj/item/stack/sheet/mineral/silver)
|
||||
silver_amount += amount * 2000
|
||||
if(/obj/item/stack/sheet/mineral/plasma)
|
||||
plasma_amount += amount * 2000
|
||||
if(/obj/item/stack/sheet/mineral/uranium)
|
||||
uranium_amount += amount * 2000
|
||||
if(/obj/item/stack/sheet/mineral/diamond)
|
||||
diamond_amount += amount * 2000
|
||||
if(/obj/item/stack/sheet/mineral/clown)
|
||||
clown_amount += amount * 2000
|
||||
if(/obj/item/stack/sheet/mineral/adamantine)
|
||||
adamantine_amount += amount * 2000
|
||||
else
|
||||
new stacktype(src.loc, amount)
|
||||
busy = 0
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
Research and Development System. (Designed specifically for the /tg/station 13 (Space Station 13) open source project)
|
||||
|
||||
///////////////Overview///////////////////
|
||||
This system is a "tech tree" research and development system designed for SS13. It allows a "researcher" job (this document assumes
|
||||
the "scientist" job is given this role) the tools necessiary to research new and better technologies. In general, the system works
|
||||
by breaking existing technology and using what you learn from to advance your knowledge of SCIENCE! As your knowledge progresses,
|
||||
you can build newer (and better?) devices (which you can also, eventually, deconstruct to advance your knowledge).
|
||||
|
||||
A brief overview is below. For more details, see the related files.
|
||||
|
||||
////////////Game Use/////////////
|
||||
The major research and development is performed using a combination of four machines:
|
||||
- R&D Console: A computer console that allows you to manipulate the other devices that are linked to it and view/manipulate the
|
||||
technologies you have researched so far.
|
||||
- Protolathe: Used to make new hand-held devices and parts for larger devices. All metals and reagents as raw materials.
|
||||
- Destructive Analyzer: You can put hand-held objects into it and it'll analyze them for technological advancements but it destroys
|
||||
them in the process. Destroyed items will send their raw materials to a linked Protolathe (if any)
|
||||
- Circuit Imprinter: Similar to the Protolathe, it allows for the construction of circuit boards. Uses glass and acid as the raw
|
||||
materials.
|
||||
|
||||
While researching you are dealing with two different types of information: Technology Paths and Device Designs. Technology Paths
|
||||
are the "Tech Trees" of the game. You start out with a number of them at the game start and they are improved by using the
|
||||
Destructive Analyzer. By themselves, they don't do a whole lot. However, they unlock Device Designs. This is the information used
|
||||
by the circuit imprinter and the protolathe to produce objects. It also tracks the current reliability of that particular design.
|
||||
|
||||
//EXISTING TECH
|
||||
Each tech path should have at LEAST one item at every level (levels 1 - 20). This is to allow for a more fluid progression of the
|
||||
researching. Existing tech (ie, anything you can find on the station or get from the quartermaster) shouldn't go higher then
|
||||
level 5 or 7. Everything past that should be stuff you research.
|
||||
|
||||
Below is a checklist to make sure every tree is filled. As new items get added to R&D, add them here if there is an empty slot.
|
||||
When thinking about new stuff, check here to see if there are any slots unfilled.
|
||||
|
||||
//MATERIALS
|
||||
1 | Metal
|
||||
2 | Solid Plasma
|
||||
3 | Silver
|
||||
4 | Gold, Super Capacitor
|
||||
5 | Uranium, Nuclear Gun, SUPERPACMAN
|
||||
6 | Diamond, MRSPACMAN
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 |
|
||||
13 |
|
||||
14 |
|
||||
15 |
|
||||
16 |
|
||||
17 |
|
||||
18 |
|
||||
19 |
|
||||
20 |
|
||||
|
||||
//PLASMA TECH
|
||||
1 |
|
||||
2 | Solid Plasma
|
||||
3 | Pacman Generator
|
||||
4 |
|
||||
5 |
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 |
|
||||
13 |
|
||||
14 |
|
||||
15 |
|
||||
16 |
|
||||
17 |
|
||||
18 |
|
||||
19 |
|
||||
20 |
|
||||
|
||||
//POWER TECH
|
||||
1 | Basic Capacitor, Basic Cell
|
||||
2 | High-Capacity Cell (10,000)
|
||||
3 | Super-Capacity Cell (20,000), Powersink, PACMAN
|
||||
4 | SUPERPACMAN
|
||||
5 | MRSPACMAN, Super Capacitor
|
||||
6 | Hyper-Capacity Cell (30,000)
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 |
|
||||
13 |
|
||||
14 |
|
||||
15 |
|
||||
16 |
|
||||
17 |
|
||||
18 |
|
||||
19 |
|
||||
20 |
|
||||
|
||||
//BLUE SPACE
|
||||
1 |
|
||||
2 | Teleporter Console Board
|
||||
3 | Teleport Gun, Hand Tele
|
||||
4 | Teleportation Scroll
|
||||
5 |
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 |
|
||||
13 |
|
||||
14 |
|
||||
15 |
|
||||
16 |
|
||||
17 |
|
||||
18 |
|
||||
19 |
|
||||
20 |
|
||||
|
||||
//BIOTECH
|
||||
1 | Bruise Pack, Scalple
|
||||
2 | PANDEMIC Board, Mass Spectrometer
|
||||
3 | AI Core, Brains (MMI)
|
||||
4 | MMI+Radio
|
||||
5 |
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 |
|
||||
13 |
|
||||
14 |
|
||||
15 |
|
||||
16 |
|
||||
17 |
|
||||
18 |
|
||||
19 |
|
||||
20 |
|
||||
|
||||
//MAGNETS
|
||||
1 | Basic Sensor
|
||||
2 | Comm Console Board
|
||||
3 | Adv Sensor
|
||||
4 | Adv Mass Spectrometer, Chameleon Projector
|
||||
5 | Phasic Sensor
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 |
|
||||
13 |
|
||||
14 |
|
||||
15 |
|
||||
16 |
|
||||
17 |
|
||||
18 |
|
||||
19 |
|
||||
20 |
|
||||
|
||||
//PROGRAMMING
|
||||
1 | Arcade Board
|
||||
2 | Sec Camera
|
||||
3 | Cloning Machine Console Board
|
||||
4 | AI Core, Intellicard
|
||||
5 | Pico-Manipulator, Ultra-Micro-Laser
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 |
|
||||
13 |
|
||||
14 |
|
||||
15 |
|
||||
16 |
|
||||
17 |
|
||||
18 |
|
||||
19 |
|
||||
20 |
|
||||
|
||||
//SYNDICATE
|
||||
1 | Sleepypen
|
||||
2 | TYRANT Module, Emag
|
||||
3 | Cloaking Device, Power Sink
|
||||
4 |
|
||||
5 |
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 |
|
||||
13 |
|
||||
14 |
|
||||
15 |
|
||||
16 |
|
||||
17 |
|
||||
18 |
|
||||
19 |
|
||||
20 |
|
||||
|
||||
//COMBAT
|
||||
1 | Flashbang, Mousetrap, Nettle
|
||||
2 | Stun Baton
|
||||
3 | Power Axe, Death Nettle, Nuclear Gun
|
||||
4 |
|
||||
5 |
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 |
|
||||
13 |
|
||||
14 |
|
||||
15 |
|
||||
16 |
|
||||
17 |
|
||||
18 |
|
||||
19 |
|
||||
20 |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,915 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
||||
|
||||
/*
|
||||
Research and Development (R&D) Console
|
||||
|
||||
This is the main work horse of the R&D system. It contains the menus/controls for the Destructive Analyzer, Protolathe, and Circuit
|
||||
imprinter. It also contains the /datum/research holder with all the known/possible technology paths and device designs.
|
||||
|
||||
Basic use: When it first is created, it will attempt to link up to related devices within 3 squares. It'll only link up if they
|
||||
aren't already linked to another console. Any consoles it cannot link up with (either because all of a certain type are already
|
||||
linked or there aren't any in range), you'll just not have access to that menu. In the settings menu, there are menu options that
|
||||
allow a player to attempt to re-sync with nearby consoles. You can also force it to disconnect from a specific console.
|
||||
|
||||
The imprinting and construction menus do NOT require toxins access to access but all the other menus do. However, if you leave it
|
||||
on a menu, nothing is to stop the person from using the options on that menu (although they won't be able to change to a different
|
||||
one). You can also lock the console on the settings menu if you're feeling paranoid and you don't want anyone messing with it who
|
||||
doesn't have toxins access.
|
||||
|
||||
When a R&D console is destroyed or even partially disassembled, you lose all research data on it. However, there are two ways around
|
||||
this dire fate:
|
||||
- The easiest way is to go to the settings menu and select "Sync Database with Network." That causes it to upload (but not download)
|
||||
it's data to every other device in the game. Each console has a "disconnect from network" option that'll will cause data base sync
|
||||
operations to skip that console. This is useful if you want to make a "public" R&D console or, for example, give the engineers
|
||||
a circuit imprinter with certain designs on it and don't want it accidentally updating. The downside of this method is that you have
|
||||
to have physical access to the other console to send data back. Note: An R&D console is on CentCom so if a random griffan happens to
|
||||
cause a ton of data to be lost, an admin can go send it back.
|
||||
- The second method is with Technology Disks and Design Disks. Each of these disks can hold a single technology or design datum in
|
||||
it's entirety. You can then take the disk to any R&D console and upload it's data to it. This method is a lot more secure (since it
|
||||
won't update every console in existence) but it's more of a hassle to do. Also, the disks can be stolen.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/obj/machinery/computer/rdconsole
|
||||
name = "R&D Console"
|
||||
icon_state = "rdcomp"
|
||||
var/datum/research/files //Stores all the collected research data.
|
||||
var/obj/item/weapon/disk/tech_disk/t_disk = null //Stores the technology disk.
|
||||
var/obj/item/weapon/disk/design_disk/d_disk = null //Stores the design disk.
|
||||
|
||||
var/obj/machinery/r_n_d/destructive_analyzer/linked_destroy = null //Linked Destructive Analyzer
|
||||
var/obj/machinery/r_n_d/protolathe/linked_lathe = null //Linked Protolathe
|
||||
var/obj/machinery/r_n_d/circuit_imprinter/linked_imprinter = null //Linked Circuit Imprinter
|
||||
|
||||
var/screen = 1.0 //Which screen is currently showing.
|
||||
var/id = 0 //ID of the computer (for server restrictions).
|
||||
var/sync = 1 //If sync = 0, it doesn't show up on Server Control Console
|
||||
|
||||
req_access = list(access_tox) //Data and setting manipulation requires scientist access.
|
||||
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/CallTechName(var/ID) //A simple helper proc to find the name of a tech with a given ID.
|
||||
var/datum/tech/check_tech
|
||||
var/return_name = null
|
||||
for(var/T in typesof(/datum/tech) - /datum/tech)
|
||||
check_tech = null
|
||||
check_tech = new T()
|
||||
if(check_tech.id == ID)
|
||||
return_name = check_tech.name
|
||||
del(check_tech)
|
||||
check_tech = null
|
||||
break
|
||||
|
||||
return return_name
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/CallMaterialName(var/ID)
|
||||
var/datum/reagent/temp_reagent
|
||||
var/return_name = null
|
||||
if (copytext(ID, 1, 2) == "$")
|
||||
return_name = copytext(ID, 2)
|
||||
switch(return_name)
|
||||
if("metal")
|
||||
return_name = "Metal"
|
||||
if("glass")
|
||||
return_name = "Glass"
|
||||
if("gold")
|
||||
return_name = "Gold"
|
||||
if("silver")
|
||||
return_name = "Silver"
|
||||
if("plasma")
|
||||
return_name = "Solid Plasma"
|
||||
if("uranium")
|
||||
return_name = "Uranium"
|
||||
if("diamond")
|
||||
return_name = "Diamond"
|
||||
if("clown")
|
||||
return_name = "Bananium"
|
||||
else
|
||||
for(var/R in typesof(/datum/reagent) - /datum/reagent)
|
||||
temp_reagent = null
|
||||
temp_reagent = new R()
|
||||
if(temp_reagent.id == ID)
|
||||
return_name = temp_reagent.name
|
||||
del(temp_reagent)
|
||||
temp_reagent = null
|
||||
break
|
||||
return return_name
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any).
|
||||
for(var/obj/machinery/r_n_d/D in oview(3,src))
|
||||
if(D.linked_console != null || D.disabled || D.opened)
|
||||
continue
|
||||
if(istype(D, /obj/machinery/r_n_d/destructive_analyzer))
|
||||
if(linked_destroy == null)
|
||||
linked_destroy = D
|
||||
D.linked_console = src
|
||||
else if(istype(D, /obj/machinery/r_n_d/protolathe))
|
||||
if(linked_lathe == null)
|
||||
linked_lathe = D
|
||||
D.linked_console = src
|
||||
else if(istype(D, /obj/machinery/r_n_d/circuit_imprinter))
|
||||
if(linked_imprinter == null)
|
||||
linked_imprinter = D
|
||||
D.linked_console = src
|
||||
return
|
||||
|
||||
//Have it automatically push research to the centcomm server so wild griffins can't fuck up R&D's work --NEO
|
||||
/obj/machinery/computer/rdconsole/proc/griefProtection()
|
||||
for(var/obj/machinery/r_n_d/server/centcom/C in machines)
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
C.files.AddTech2Known(T)
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
C.files.AddDesign2Known(D)
|
||||
C.files.RefreshResearch()
|
||||
|
||||
|
||||
/obj/machinery/computer/rdconsole/New()
|
||||
..()
|
||||
files = new /datum/research(src) //Setup the research data holder.
|
||||
if(!id)
|
||||
for(var/obj/machinery/r_n_d/server/centcom/S in machines)
|
||||
S.initialize()
|
||||
break
|
||||
|
||||
/obj/machinery/computer/rdconsole/initialize()
|
||||
SyncRDevices()
|
||||
|
||||
/* Instead of calling this every tick, it is only being called when needed
|
||||
/obj/machinery/computer/rdconsole/process()
|
||||
griefProtection()
|
||||
*/
|
||||
|
||||
/obj/machinery/computer/rdconsole/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
|
||||
//The construction/deconstruction of the console code.
|
||||
if(istype(D, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
if (src.stat & BROKEN)
|
||||
user << "\blue The broken glass falls out."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
var/obj/item/weapon/circuitboard/rdconsole/M = new /obj/item/weapon/circuitboard/rdconsole( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/item/weapon/circuitboard/rdconsole/M = new /obj/item/weapon/circuitboard/rdconsole( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
//Loading a disk into it.
|
||||
else if(istype(D, /obj/item/weapon/disk))
|
||||
if(t_disk || d_disk)
|
||||
user << "A disk is already loaded into the machine."
|
||||
return
|
||||
|
||||
if(istype(D, /obj/item/weapon/disk/tech_disk)) t_disk = D
|
||||
else if (istype(D, /obj/item/weapon/disk/design_disk)) d_disk = D
|
||||
else
|
||||
user << "\red Machine cannot accept disks in that format."
|
||||
return
|
||||
user.drop_item()
|
||||
D.loc = src
|
||||
user << "\blue You add the disk to the machine!"
|
||||
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = 1
|
||||
user << "\blue You you disable the security protocols"
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/rdconsole/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
usr.set_machine(src)
|
||||
if(href_list["menu"]) //Switches menu screens. Converts a sent text string into a number. Saves a LOT of code.
|
||||
var/temp_screen = text2num(href_list["menu"])
|
||||
if(temp_screen <= 1.1 || (3 <= temp_screen && 4.9 >= temp_screen) || src.allowed(usr) || emagged) //Unless you are making something, you need access.
|
||||
screen = temp_screen
|
||||
else
|
||||
usr << "Unauthorized Access."
|
||||
|
||||
else if(href_list["updt_tech"]) //Update the research holder with information from the technology disk.
|
||||
screen = 0.0
|
||||
spawn(50)
|
||||
screen = 1.2
|
||||
files.AddTech2Known(t_disk.stored)
|
||||
updateUsrDialog()
|
||||
griefProtection() //Update centcomm too
|
||||
|
||||
else if(href_list["clear_tech"]) //Erase data on the technology disk.
|
||||
t_disk.stored = null
|
||||
|
||||
else if(href_list["eject_tech"]) //Eject the technology disk.
|
||||
t_disk:loc = src.loc
|
||||
t_disk = null
|
||||
screen = 1.0
|
||||
|
||||
else if(href_list["copy_tech"]) //Copys some technology data from the research holder to the disk.
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
if(href_list["copy_tech_ID"] == T.id)
|
||||
t_disk.stored = T
|
||||
break
|
||||
screen = 1.2
|
||||
|
||||
else if(href_list["updt_design"]) //Updates the research holder with design data from the design disk.
|
||||
screen = 0.0
|
||||
spawn(50)
|
||||
screen = 1.4
|
||||
files.AddDesign2Known(d_disk.blueprint)
|
||||
updateUsrDialog()
|
||||
griefProtection() //Update centcomm too
|
||||
|
||||
else if(href_list["clear_design"]) //Erases data on the design disk.
|
||||
d_disk.blueprint = null
|
||||
|
||||
else if(href_list["eject_design"]) //Eject the design disk.
|
||||
d_disk:loc = src.loc
|
||||
d_disk = null
|
||||
screen = 1.0
|
||||
|
||||
else if(href_list["copy_design"]) //Copy design data from the research holder to the design disk.
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(href_list["copy_design_ID"] == D.id)
|
||||
d_disk.blueprint = D
|
||||
break
|
||||
screen = 1.4
|
||||
|
||||
else if(href_list["eject_item"]) //Eject the item inside the destructive analyzer.
|
||||
if(linked_destroy)
|
||||
if(linked_destroy.busy)
|
||||
usr << "\red The destructive analyzer is busy at the moment."
|
||||
|
||||
else if(linked_destroy.loaded_item)
|
||||
linked_destroy.loaded_item.loc = linked_destroy.loc
|
||||
linked_destroy.loaded_item = null
|
||||
linked_destroy.icon_state = "d_analyzer"
|
||||
screen = 2.1
|
||||
|
||||
else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder.
|
||||
if(linked_destroy)
|
||||
if(linked_destroy.busy)
|
||||
usr << "\red The destructive analyzer is busy at the moment."
|
||||
else
|
||||
var/choice = input("Proceeding will destroy loaded item.") in list("Proceed", "Cancel")
|
||||
if(choice == "Cancel" || !linked_destroy) return
|
||||
linked_destroy.busy = 1
|
||||
screen = 0.1
|
||||
updateUsrDialog()
|
||||
flick("d_analyzer_process", linked_destroy)
|
||||
spawn(24)
|
||||
if(linked_destroy)
|
||||
linked_destroy.busy = 0
|
||||
if(!linked_destroy.hacked)
|
||||
if(!linked_destroy.loaded_item)
|
||||
usr <<"\red The destructive analyzer appears to be empty."
|
||||
screen = 1.0
|
||||
return
|
||||
if(linked_destroy.loaded_item.reliability >= 90)
|
||||
var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech)
|
||||
for(var/T in temp_tech)
|
||||
files.UpdateTech(T, temp_tech[T])
|
||||
if(linked_destroy.loaded_item.reliability < 100 && linked_destroy.loaded_item.crit_fail)
|
||||
files.UpdateDesign(linked_destroy.loaded_item.type)
|
||||
if(linked_lathe) //Also sends salvaged materials to a linked protolathe, if any.
|
||||
linked_lathe.m_amount += min((linked_lathe.max_material_storage - linked_lathe.TotalMaterials()), (linked_destroy.loaded_item.m_amt*linked_destroy.decon_mod))
|
||||
linked_lathe.g_amount += min((linked_lathe.max_material_storage - linked_lathe.TotalMaterials()), (linked_destroy.loaded_item.g_amt*linked_destroy.decon_mod))
|
||||
linked_destroy.loaded_item = null
|
||||
for(var/obj/I in linked_destroy.contents)
|
||||
for(var/mob/M in I.contents)
|
||||
M.death()
|
||||
if(istype(I,/obj/item/stack/sheet))//Only deconsturcts one sheet at a time instead of the entire stack
|
||||
var/obj/item/stack/sheet/S = I
|
||||
if(S.amount > 1)
|
||||
S.amount--
|
||||
linked_destroy.loaded_item = S
|
||||
else
|
||||
del(S)
|
||||
linked_destroy.icon_state = "d_analyzer"
|
||||
else
|
||||
if(!(I in linked_destroy.component_parts))
|
||||
del(I)
|
||||
linked_destroy.icon_state = "d_analyzer"
|
||||
use_power(250)
|
||||
screen = 1.0
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["lock"]) //Lock the console from use by anyone without tox access.
|
||||
if(src.allowed(usr))
|
||||
screen = text2num(href_list["lock"])
|
||||
else
|
||||
usr << "Unauthorized Access."
|
||||
|
||||
else if(href_list["sync"]) //Sync the research holder with all the R&D consoles in the game that aren't sync protected.
|
||||
screen = 0.0
|
||||
if(!sync)
|
||||
usr << "\red You must connect to the network first!"
|
||||
else
|
||||
griefProtection() //Putting this here because I dont trust the sync process
|
||||
spawn(30)
|
||||
if(src)
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
var/server_processed = 0
|
||||
if(S.disabled)
|
||||
continue
|
||||
if((id in S.id_with_upload) || istype(S, /obj/machinery/r_n_d/server/centcom))
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
S.files.AddTech2Known(T)
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
S.files.AddDesign2Known(D)
|
||||
S.files.RefreshResearch()
|
||||
server_processed = 1
|
||||
if(((id in S.id_with_download) && !istype(S, /obj/machinery/r_n_d/server/centcom)) || S.hacked)
|
||||
for(var/datum/tech/T in S.files.known_tech)
|
||||
files.AddTech2Known(T)
|
||||
for(var/datum/design/D in S.files.known_designs)
|
||||
files.AddDesign2Known(D)
|
||||
files.RefreshResearch()
|
||||
server_processed = 1
|
||||
if(!istype(S, /obj/machinery/r_n_d/server/centcom) && server_processed)
|
||||
S.produce_heat(100)
|
||||
screen = 1.6
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["togglesync"]) //Prevents the console from being synced by other consoles. Can still send data.
|
||||
sync = !sync
|
||||
|
||||
else if(href_list["build"]) //Causes the Protolathe to build something.
|
||||
if(linked_lathe)
|
||||
var/datum/design/being_built = null
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.id == href_list["build"])
|
||||
being_built = D
|
||||
break
|
||||
if(being_built)
|
||||
var/power = 2000
|
||||
for(var/M in being_built.materials)
|
||||
power += round(being_built.materials[M] / 5)
|
||||
power = max(2000, power)
|
||||
screen = 0.3
|
||||
linked_lathe.busy = 1
|
||||
flick("protolathe_n",linked_lathe)
|
||||
var/key = usr.key //so we don't lose the info during the spawn delay
|
||||
spawn(16)
|
||||
use_power(power)
|
||||
spawn(16)
|
||||
for(var/M in being_built.materials)
|
||||
switch(M)
|
||||
if("$metal")
|
||||
linked_lathe.m_amount = max(0, (linked_lathe.m_amount-being_built.materials[M]))
|
||||
if("$glass")
|
||||
linked_lathe.g_amount = max(0, (linked_lathe.g_amount-being_built.materials[M]))
|
||||
if("$gold")
|
||||
linked_lathe.gold_amount = max(0, (linked_lathe.gold_amount-being_built.materials[M]))
|
||||
if("$silver")
|
||||
linked_lathe.silver_amount = max(0, (linked_lathe.silver_amount-being_built.materials[M]))
|
||||
if("$plasma")
|
||||
linked_lathe.plasma_amount = max(0, (linked_lathe.plasma_amount-being_built.materials[M]))
|
||||
if("$uranium")
|
||||
linked_lathe.uranium_amount = max(0, (linked_lathe.uranium_amount-being_built.materials[M]))
|
||||
if("$diamond")
|
||||
linked_lathe.diamond_amount = max(0, (linked_lathe.diamond_amount-being_built.materials[M]))
|
||||
if("$clown")
|
||||
linked_lathe.clown_amount = max(0, (linked_lathe.clown_amount-being_built.materials[M]))
|
||||
else
|
||||
linked_lathe.reagents.remove_reagent(M, being_built.materials[M])
|
||||
|
||||
if(being_built.build_path)
|
||||
var/obj/new_item = new being_built.build_path(src)
|
||||
if( new_item.type == /obj/item/weapon/storage/backpack/holding )
|
||||
new_item.investigate_log("built by [key]","singulo")
|
||||
new_item.reliability = being_built.reliability
|
||||
if(linked_lathe.hacked) being_built.reliability = max((reliability / 2), 0)
|
||||
/*if(being_built.locked)
|
||||
var/obj/item/weapon/storage/lockbox/L = new/obj/item/weapon/storage/lockbox(linked_lathe.loc)
|
||||
new_item.loc = L
|
||||
L.name += " ([new_item.name])"*/
|
||||
else
|
||||
new_item.loc = linked_lathe.loc
|
||||
linked_lathe.busy = 0
|
||||
screen = 3.1
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["imprint"]) //Causes the Circuit Imprinter to build something.
|
||||
if(linked_imprinter)
|
||||
var/datum/design/being_built = null
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.id == href_list["imprint"])
|
||||
being_built = D
|
||||
break
|
||||
if(being_built)
|
||||
var/power = 2000
|
||||
for(var/M in being_built.materials)
|
||||
power += round(being_built.materials[M] / 5)
|
||||
power = max(2000, power)
|
||||
screen = 0.4
|
||||
linked_imprinter.busy = 1
|
||||
flick("circuit_imprinter_ani",linked_imprinter)
|
||||
spawn(16)
|
||||
use_power(power)
|
||||
for(var/M in being_built.materials)
|
||||
switch(M)
|
||||
if("$glass")
|
||||
linked_imprinter.g_amount = max(0, (linked_imprinter.g_amount-being_built.materials[M]))
|
||||
if("$gold")
|
||||
linked_imprinter.gold_amount = max(0, (linked_imprinter.gold_amount-being_built.materials[M]))
|
||||
if("$diamond")
|
||||
linked_imprinter.diamond_amount = max(0, (linked_imprinter.diamond_amount-being_built.materials[M]))
|
||||
if("$uranium")
|
||||
linked_imprinter.uranium_amount = max(0, (linked_imprinter.uranium_amount-being_built.materials[M]))
|
||||
else
|
||||
linked_imprinter.reagents.remove_reagent(M, being_built.materials[M])
|
||||
var/obj/new_item = new being_built.build_path(src)
|
||||
new_item.reliability = being_built.reliability
|
||||
if(linked_imprinter.hacked) being_built.reliability = max((reliability / 2), 0)
|
||||
new_item.loc = linked_imprinter.loc
|
||||
linked_imprinter.busy = 0
|
||||
screen = 4.1
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it)
|
||||
linked_imprinter.reagents.del_reagent(href_list["dispose"])
|
||||
|
||||
else if(href_list["disposeallI"] && linked_imprinter) //Causes the circuit imprinter to dispose of all it's reagents.
|
||||
linked_imprinter.reagents.clear_reagents()
|
||||
|
||||
else if(href_list["disposeP"] && linked_lathe) //Causes the protolathe to dispose of a single reagent (all of it)
|
||||
linked_lathe.reagents.del_reagent(href_list["dispose"])
|
||||
|
||||
else if(href_list["disposeallP"] && linked_lathe) //Causes the protolathe to dispose of all it's reagents.
|
||||
linked_lathe.reagents.clear_reagents()
|
||||
|
||||
else if(href_list["lathe_ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material
|
||||
var/desired_num_sheets = text2num(href_list["lathe_ejectsheet_amt"])
|
||||
var/res_amount, type
|
||||
switch(href_list["lathe_ejectsheet"])
|
||||
if("metal")
|
||||
type = /obj/item/stack/sheet/metal
|
||||
res_amount = "m_amount"
|
||||
if("glass")
|
||||
type = /obj/item/stack/sheet/glass
|
||||
res_amount = "g_amount"
|
||||
if("gold")
|
||||
type = /obj/item/stack/sheet/mineral/gold
|
||||
res_amount = "gold_amount"
|
||||
if("silver")
|
||||
type = /obj/item/stack/sheet/mineral/silver
|
||||
res_amount = "silver_amount"
|
||||
if("plasma")
|
||||
type = /obj/item/stack/sheet/mineral/plasma
|
||||
res_amount = "plasma_amount"
|
||||
if("uranium")
|
||||
type = /obj/item/stack/sheet/mineral/uranium
|
||||
res_amount = "uranium_amount"
|
||||
if("diamond")
|
||||
type = /obj/item/stack/sheet/mineral/diamond
|
||||
res_amount = "diamond_amount"
|
||||
if("clown")
|
||||
type = /obj/item/stack/sheet/mineral/clown
|
||||
res_amount = "clown_amount"
|
||||
if(ispath(type) && hasvar(linked_lathe, res_amount))
|
||||
var/obj/item/stack/sheet/sheet = new type(linked_lathe.loc)
|
||||
var/available_num_sheets = round(linked_lathe.vars[res_amount]/sheet.perunit)
|
||||
if(available_num_sheets>0)
|
||||
sheet.amount = min(available_num_sheets, desired_num_sheets)
|
||||
linked_lathe.vars[res_amount] = max(0, (linked_lathe.vars[res_amount]-sheet.amount * sheet.perunit))
|
||||
else
|
||||
del sheet
|
||||
else if(href_list["imprinter_ejectsheet"] && linked_imprinter) //Causes the protolathe to eject a sheet of material
|
||||
var/desired_num_sheets = text2num(href_list["imprinter_ejectsheet_amt"])
|
||||
var/res_amount, type
|
||||
switch(href_list["imprinter_ejectsheet"])
|
||||
if("glass")
|
||||
type = /obj/item/stack/sheet/glass
|
||||
res_amount = "g_amount"
|
||||
if("gold")
|
||||
type = /obj/item/stack/sheet/mineral/gold
|
||||
res_amount = "gold_amount"
|
||||
if("diamond")
|
||||
type = /obj/item/stack/sheet/mineral/diamond
|
||||
res_amount = "diamond_amount"
|
||||
if("uranium")
|
||||
type = /obj/item/stack/sheet/mineral/uranium
|
||||
res_amount = "uranium_amount"
|
||||
if(ispath(type) && hasvar(linked_imprinter, res_amount))
|
||||
var/obj/item/stack/sheet/sheet = new type(linked_imprinter.loc)
|
||||
var/available_num_sheets = round(linked_imprinter.vars[res_amount]/sheet.perunit)
|
||||
if(available_num_sheets>0)
|
||||
sheet.amount = min(available_num_sheets, desired_num_sheets)
|
||||
linked_imprinter.vars[res_amount] = max(0, (linked_imprinter.vars[res_amount]-sheet.amount * sheet.perunit))
|
||||
else
|
||||
del sheet
|
||||
|
||||
else if(href_list["find_device"]) //The R&D console looks for devices nearby to link up with.
|
||||
screen = 0.0
|
||||
spawn(20)
|
||||
SyncRDevices()
|
||||
screen = 1.7
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["disconnect"]) //The R&D console disconnects with a specific device.
|
||||
switch(href_list["disconnect"])
|
||||
if("destroy")
|
||||
linked_destroy.linked_console = null
|
||||
linked_destroy = null
|
||||
if("lathe")
|
||||
linked_lathe.linked_console = null
|
||||
linked_lathe = null
|
||||
if("imprinter")
|
||||
linked_imprinter.linked_console = null
|
||||
linked_imprinter = null
|
||||
|
||||
else if(href_list["reset"]) //Reset the R&D console's database.
|
||||
griefProtection()
|
||||
var/choice = alert("R&D Console Database Reset", "Are you sure you want to reset the R&D console's database? Data lost cannot be recovered.", "Continue", "Cancel")
|
||||
if(choice == "Continue")
|
||||
screen = 0.0
|
||||
del(files)
|
||||
files = new /datum/research(src)
|
||||
spawn(20)
|
||||
screen = 1.6
|
||||
updateUsrDialog()
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/rdconsole/attack_hand(mob/user as mob)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = ""
|
||||
files.RefreshResearch()
|
||||
switch(screen) //A quick check to make sure you get the right screen when a device is disconnected.
|
||||
if(2 to 2.9)
|
||||
if(linked_destroy == null)
|
||||
screen = 2.0
|
||||
else if(linked_destroy.loaded_item == null)
|
||||
screen = 2.1
|
||||
else
|
||||
screen = 2.2
|
||||
if(3 to 3.9)
|
||||
if(linked_lathe == null)
|
||||
screen = 3.0
|
||||
if(4 to 4.9)
|
||||
if(linked_imprinter == null)
|
||||
screen = 4.0
|
||||
|
||||
switch(screen)
|
||||
|
||||
//////////////////////R&D CONSOLE SCREENS//////////////////
|
||||
if(0.0) dat += "Updating Database...."
|
||||
|
||||
if(0.1) dat += "Processing and Updating Database..."
|
||||
|
||||
if(0.2)
|
||||
dat += "SYSTEM LOCKED<BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];lock=1.6'>Unlock</A>"
|
||||
|
||||
if(0.3)
|
||||
dat += "Constructing Prototype. Please Wait..."
|
||||
|
||||
if(0.4)
|
||||
dat += "Imprinting Circuit. Please Wait..."
|
||||
|
||||
if(1.0) //Main Menu
|
||||
dat += "Main Menu:<BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];menu=1.1'>Current Research Levels</A><BR>"
|
||||
if(t_disk) dat += "<A href='?src=\ref[src];menu=1.2'>Disk Operations</A><BR>"
|
||||
else if(d_disk) dat += "<A href='?src=\ref[src];menu=1.4'>Disk Operations</A><BR>"
|
||||
else dat += "(Please Insert Disk)<BR>"
|
||||
if(linked_destroy != null) dat += "<A href='?src=\ref[src];menu=2.2'>Destructive Analyzer Menu</A><BR>"
|
||||
if(linked_lathe != null) dat += "<A href='?src=\ref[src];menu=3.1'>Protolathe Construction Menu</A><BR>"
|
||||
if(linked_imprinter != null) dat += "<A href='?src=\ref[src];menu=4.1'>Circuit Construction Menu</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];menu=1.6'>Settings</A>"
|
||||
|
||||
if(1.1) //Research viewer
|
||||
dat += "Current Research Levels:<BR><BR>"
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
dat += "[T.name]<BR>"
|
||||
dat += "* Level: [T.level]<BR>"
|
||||
dat += "* Summary: [T.desc]<HR>"
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A>"
|
||||
|
||||
if(1.2) //Technology Disk Menu
|
||||
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "Disk Contents: (Technology Data Disk)<BR><BR>"
|
||||
if(t_disk.stored == null)
|
||||
dat += "The disk has no data stored on it.<HR>"
|
||||
dat += "Operations: "
|
||||
dat += "<A href='?src=\ref[src];menu=1.3'>Load Tech to Disk</A> || "
|
||||
else
|
||||
dat += "Name: [t_disk.stored.name]<BR>"
|
||||
dat += "Level: [t_disk.stored.level]<BR>"
|
||||
dat += "Description: [t_disk.stored.desc]<HR>"
|
||||
dat += "Operations: "
|
||||
dat += "<A href='?src=\ref[src];updt_tech=1'>Upload to Database</A> || "
|
||||
dat += "<A href='?src=\ref[src];clear_tech=1'>Clear Disk</A> || "
|
||||
dat += "<A href='?src=\ref[src];eject_tech=1'>Eject Disk</A>"
|
||||
|
||||
if(1.3) //Technology Disk submenu
|
||||
dat += "<BR><A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=1.2'>Return to Disk Operations</A><HR>"
|
||||
dat += "Load Technology to Disk:<BR><BR>"
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
dat += "[T.name] "
|
||||
dat += "<A href='?src=\ref[src];copy_tech=1;copy_tech_ID=[T.id]'>(Copy to Disk)</A><BR>"
|
||||
|
||||
if(1.4) //Design Disk menu.
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
if(d_disk.blueprint == null)
|
||||
dat += "The disk has no data stored on it.<HR>"
|
||||
dat += "Operations: "
|
||||
dat += "<A href='?src=\ref[src];menu=1.5'>Load Design to Disk</A> || "
|
||||
else
|
||||
dat += "Name: [d_disk.blueprint.name]<BR>"
|
||||
dat += "Level: [between(0, (d_disk.blueprint.reliability + rand(-15,15)), 100)]<BR>"
|
||||
switch(d_disk.blueprint.build_type)
|
||||
if(IMPRINTER) dat += "Lathe Type: Circuit Imprinter<BR>"
|
||||
if(PROTOLATHE) dat += "Lathe Type: Proto-lathe<BR>"
|
||||
if(AUTOLATHE) dat += "Lathe Type: Auto-lathe<BR>"
|
||||
dat += "Required Materials:<BR>"
|
||||
for(var/M in d_disk.blueprint.materials)
|
||||
if(copytext(M, 1, 2) == "$") dat += "* [copytext(M, 2)] x [d_disk.blueprint.materials[M]]<BR>"
|
||||
else dat += "* [M] x [d_disk.blueprint.materials[M]]<BR>"
|
||||
dat += "<HR>Operations: "
|
||||
dat += "<A href='?src=\ref[src];updt_design=1'>Upload to Database</A> || "
|
||||
dat += "<A href='?src=\ref[src];clear_design=1'>Clear Disk</A> || "
|
||||
dat += "<A href='?src=\ref[src];eject_design=1'>Eject Disk</A>"
|
||||
|
||||
if(1.5) //Technology disk submenu
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=1.4'>Return to Disk Operations</A><HR>"
|
||||
dat += "Load Design to Disk:<BR><BR>"
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
dat += "[D.name] "
|
||||
dat += "<A href='?src=\ref[src];copy_design=1;copy_design_ID=[D.id]'>(Copy to Disk)</A><BR>"
|
||||
|
||||
if(1.6) //R&D console settings
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "R&D Console Setting:<BR><BR>"
|
||||
if(sync)
|
||||
dat += "<A href='?src=\ref[src];sync=1'>Sync Database with Network</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];togglesync=1'>Disconnect from Research Network</A><BR>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];togglesync=1'>Connect to Research Network</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];menu=1.7'>Device Linkage Menu</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];lock=0.2'>Lock Console</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];reset=1'>Reset R&D Database.</A><BR>"
|
||||
|
||||
if(1.7) //R&D device linkage
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=1.6'>Settings Menu</A><HR> "
|
||||
dat += "R&D Console Device Linkage Menu:<BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];find_device=1'>Re-sync with Nearby Devices</A><BR>"
|
||||
dat += "Linked Devices:<BR>"
|
||||
if(linked_destroy)
|
||||
dat += "* Destructive Analyzer <A href='?src=\ref[src];disconnect=destroy'>(Disconnect)</A><BR>"
|
||||
else
|
||||
dat += "* (No Destructive Analyzer Linked)<BR>"
|
||||
if(linked_lathe)
|
||||
dat += "* Protolathe <A href='?src=\ref[src];disconnect=lathe'>(Disconnect)</A><BR>"
|
||||
else
|
||||
dat += "* (No Protolathe Linked)<BR>"
|
||||
if(linked_imprinter)
|
||||
dat += "* Circuit Imprinter <A href='?src=\ref[src];disconnect=imprinter'>(Disconnect)</A><BR>"
|
||||
else
|
||||
dat += "* (No Circuit Imprinter Linked)<BR>"
|
||||
|
||||
////////////////////DESTRUCTIVE ANALYZER SCREENS////////////////////////////
|
||||
if(2.0)
|
||||
dat += "NO DESTRUCTIVE ANALYZER LINKED TO CONSOLE<BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A>"
|
||||
|
||||
if(2.1)
|
||||
dat += "No Item Loaded. Standing-by...<BR><HR>"
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A>"
|
||||
|
||||
if(2.2)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "Deconstruction Menu<HR>"
|
||||
dat += "Name: [linked_destroy.loaded_item.name]<BR>"
|
||||
dat += "Origin Tech:<BR>"
|
||||
var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech)
|
||||
for(var/T in temp_tech)
|
||||
dat += "* [CallTechName(T)] [temp_tech[T]]<BR>"
|
||||
dat += "<HR><A href='?src=\ref[src];deconstruct=1'>Deconstruct Item</A> || "
|
||||
dat += "<A href='?src=\ref[src];eject_item=1'>Eject Item</A> || "
|
||||
|
||||
/////////////////////PROTOLATHE SCREENS/////////////////////////
|
||||
if(3.0)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "NO PROTOLATHE LINKED TO CONSOLE<BR><BR>"
|
||||
|
||||
if(3.1)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.2'>Material Storage</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.3'>Chemical Storage</A><HR>"
|
||||
dat += "Protolathe Menu:<BR><BR>"
|
||||
dat += "<B>Material Amount:</B> [linked_lathe.TotalMaterials()] cm<sup>3</sup> (MAX: [linked_lathe.max_material_storage])<BR>"
|
||||
dat += "<B>Chemical Volume:</B> [linked_lathe.reagents.total_volume] (MAX: [linked_lathe.reagents.maximum_volume])<HR>"
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(!(D.build_type & PROTOLATHE))
|
||||
continue
|
||||
var/temp_dat = "[D.name]"
|
||||
var/check_materials = 1
|
||||
for(var/M in D.materials)
|
||||
temp_dat += " [D.materials[M]] [CallMaterialName(M)]"
|
||||
if(copytext(M, 1, 2) == "$")
|
||||
switch(M)
|
||||
if("$glass")
|
||||
if(D.materials[M] > linked_lathe.g_amount) check_materials = 0
|
||||
if("$metal")
|
||||
if(D.materials[M] > linked_lathe.m_amount) check_materials = 0
|
||||
if("$gold")
|
||||
if(D.materials[M] > linked_lathe.gold_amount) check_materials = 0
|
||||
if("$silver")
|
||||
if(D.materials[M] > linked_lathe.silver_amount) check_materials = 0
|
||||
if("$plasma")
|
||||
if(D.materials[M] > linked_lathe.plasma_amount) check_materials = 0
|
||||
if("$uranium")
|
||||
if(D.materials[M] > linked_lathe.uranium_amount) check_materials = 0
|
||||
if("$diamond")
|
||||
if(D.materials[M] > linked_lathe.diamond_amount) check_materials = 0
|
||||
if("$clown")
|
||||
if(D.materials[M] > linked_lathe.clown_amount) check_materials = 0
|
||||
else if (!linked_lathe.reagents.has_reagent(M, D.materials[M]))
|
||||
check_materials = 0
|
||||
if (check_materials)
|
||||
dat += "* <A href='?src=\ref[src];build=[D.id]'>[temp_dat]</A><BR>"
|
||||
else
|
||||
dat += "* [temp_dat]<BR>"
|
||||
|
||||
if(3.2) //Protolathe Material Storage Sub-menu
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.1'>Protolathe Menu</A><HR>"
|
||||
dat += "Material Storage<BR><HR>"
|
||||
//Metal
|
||||
dat += "* [linked_lathe.m_amount] cm<sup>3</sup> of Metal || "
|
||||
dat += "Eject: "
|
||||
if(linked_lathe.m_amount >= 3750) dat += "<A href='?src=\ref[src];lathe_ejectsheet=metal;lathe_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_lathe.m_amount >= 18750) dat += "<A href='?src=\ref[src];lathe_ejectsheet=metal;lathe_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_lathe.m_amount >= 3750) dat += "<A href='?src=\ref[src];lathe_ejectsheet=metal;lathe_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Glass
|
||||
dat += "* [linked_lathe.g_amount] cm<sup>3</sup> of Glass || "
|
||||
dat += "Eject: "
|
||||
if(linked_lathe.g_amount >= 3750) dat += "<A href='?src=\ref[src];lathe_ejectsheet=glass;lathe_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_lathe.g_amount >= 18750) dat += "<A href='?src=\ref[src];lathe_ejectsheet=glass;lathe_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_lathe.g_amount >= 3750) dat += "<A href='?src=\ref[src];lathe_ejectsheet=glass;lathe_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Gold
|
||||
dat += "* [linked_lathe.gold_amount] cm<sup>3</sup> of Gold || "
|
||||
dat += "Eject: "
|
||||
if(linked_lathe.gold_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=gold;lathe_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_lathe.gold_amount >= 10000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=gold;lathe_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_lathe.gold_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=gold;lathe_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Silver
|
||||
dat += "* [linked_lathe.silver_amount] cm<sup>3</sup> of Silver || "
|
||||
dat += "Eject: "
|
||||
if(linked_lathe.silver_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=silver;lathe_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_lathe.silver_amount >= 10000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=silver;lathe_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_lathe.silver_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=silver;lathe_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Plasma
|
||||
dat += "* [linked_lathe.plasma_amount] cm<sup>3</sup> of Solid Plasma || "
|
||||
dat += "Eject: "
|
||||
if(linked_lathe.plasma_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=plasma;lathe_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_lathe.plasma_amount >= 10000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=plasma;lathe_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_lathe.plasma_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=plasmalathe_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Uranium
|
||||
dat += "* [linked_lathe.uranium_amount] cm<sup>3</sup> of Uranium || "
|
||||
dat += "Eject: "
|
||||
if(linked_lathe.uranium_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=uranium;lathe_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_lathe.uranium_amount >= 10000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=uranium;lathe_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_lathe.uranium_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=uranium;lathe_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Diamond
|
||||
dat += "* [linked_lathe.diamond_amount] cm<sup>3</sup> of Diamond || "
|
||||
dat += "Eject: "
|
||||
if(linked_lathe.diamond_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=diamond;lathe_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_lathe.diamond_amount >= 10000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=diamond;lathe_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_lathe.diamond_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=diamond;lathe_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Bananium
|
||||
dat += "* [linked_lathe.clown_amount] cm<sup>3</sup> of Bananium || "
|
||||
dat += "Eject: "
|
||||
if(linked_lathe.clown_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=clown;lathe_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_lathe.clown_amount >= 10000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=clown;lathe_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_lathe.clown_amount >= 2000) dat += "<A href='?src=\ref[src];lathe_ejectsheet=clown;lathe_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
|
||||
if(3.3) //Protolathe Chemical Storage Submenu
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.1'>Protolathe Menu</A><HR>"
|
||||
dat += "Chemical Storage<BR><HR>"
|
||||
for(var/datum/reagent/R in linked_lathe.reagents.reagent_list)
|
||||
dat += "Name: [R.name] | Units: [R.volume] "
|
||||
dat += "<A href='?src=\ref[src];disposeP=[R.id]'>(Purge)</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];disposeallP=1'><U>Disposal All Chemicals in Storage</U></A><BR>"
|
||||
|
||||
///////////////////CIRCUIT IMPRINTER SCREENS////////////////////
|
||||
if(4.0)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "NO CIRCUIT IMPRINTER LINKED TO CONSOLE<BR><BR>"
|
||||
|
||||
if(4.1)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.3'>Material Storage</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.2'>Chemical Storage</A><HR>"
|
||||
dat += "Circuit Imprinter Menu:<BR><BR>"
|
||||
dat += "Material Amount: [linked_imprinter.TotalMaterials()] cm<sup>3</sup><BR>"
|
||||
dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]<HR>"
|
||||
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(!(D.build_type & IMPRINTER))
|
||||
continue
|
||||
var/temp_dat = "[D.name]"
|
||||
var/check_materials = 1
|
||||
for(var/M in D.materials)
|
||||
temp_dat += " [D.materials[M]] [CallMaterialName(M)]"
|
||||
if(copytext(M, 1, 2) == "$")
|
||||
switch(M)
|
||||
if("$glass")
|
||||
if(D.materials[M] > linked_imprinter.g_amount) check_materials = 0
|
||||
if("$gold")
|
||||
if(D.materials[M] > linked_imprinter.gold_amount) check_materials = 0
|
||||
if("$diamond")
|
||||
if(D.materials[M] > linked_imprinter.diamond_amount) check_materials = 0
|
||||
if("$uranium")
|
||||
if(D.materials[M] > linked_imprinter.uranium_amount) check_materials = 0
|
||||
else if (!linked_imprinter.reagents.has_reagent(M, D.materials[M]))
|
||||
check_materials = 0
|
||||
if (check_materials)
|
||||
dat += "* <A href='?src=\ref[src];imprint=[D.id]'>[temp_dat]</A><BR>"
|
||||
else
|
||||
dat += "* [temp_dat]<BR>"
|
||||
|
||||
if(4.2)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.1'>Imprinter Menu</A><HR>"
|
||||
dat += "Chemical Storage<BR><HR>"
|
||||
for(var/datum/reagent/R in linked_imprinter.reagents.reagent_list)
|
||||
dat += "Name: [R.name] | Units: [R.volume] "
|
||||
dat += "<A href='?src=\ref[src];disposeI=[R.id]'>(Purge)</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];disposeallI=1'><U>Disposal All Chemicals in Storage</U></A><BR>"
|
||||
|
||||
if(4.3)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.1'>Circuit Imprinter Menu</A><HR>"
|
||||
dat += "Material Storage<BR><HR>"
|
||||
//Glass
|
||||
dat += "* [linked_imprinter.g_amount] cm<sup>3</sup> of Glass || "
|
||||
dat += "Eject: "
|
||||
if(linked_imprinter.g_amount >= 3750) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=glass;imprinter_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_imprinter.g_amount >= 18750) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=glass;imprinter_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_imprinter.g_amount >= 3750) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=glass;imprinter_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Gold
|
||||
dat += "* [linked_imprinter.gold_amount] cm<sup>3</sup> of Gold || "
|
||||
dat += "Eject: "
|
||||
if(linked_imprinter.gold_amount >= 2000) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=gold;imprinter_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_imprinter.gold_amount >= 10000) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=gold;imprinter_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_imprinter.gold_amount >= 2000) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=gold;imprinter_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Diamond
|
||||
dat += "* [linked_imprinter.diamond_amount] cm<sup>3</sup> of Diamond || "
|
||||
dat += "Eject: "
|
||||
if(linked_imprinter.diamond_amount >= 2000) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=diamond;imprinter_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_imprinter.diamond_amount >= 10000) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=diamond;imprinter_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_imprinter.diamond_amount >= 2000) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=diamond;imprinter_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
dat += "<BR>"
|
||||
//Uranium
|
||||
dat += "* [linked_imprinter.uranium_amount] cm<sup>3</sup> of Uranium || "
|
||||
dat += "Eject: "
|
||||
if(linked_imprinter.uranium_amount >= 2000) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=uranium;imprinter_ejectsheet_amt=1'>(1 Sheet)</A> "
|
||||
if(linked_imprinter.uranium_amount >= 10000) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=uranium;imprinter_ejectsheet_amt=5'>(5 Sheets)</A> "
|
||||
if(linked_imprinter.uranium_amount >= 2000) dat += "<A href='?src=\ref[src];imprinter_ejectsheet=uranium;imprinter_ejectsheet_amt=50'>(Max Sheets)</A>"
|
||||
|
||||
user << browse("<TITLE>Research and Development Console</TITLE><HR>[dat]", "window=rdconsole;size=575x400")
|
||||
onclose(user, "rdconsole")
|
||||
|
||||
/obj/machinery/computer/rdconsole/robotics
|
||||
name = "Robotics R&D Console"
|
||||
id = 2
|
||||
req_access = null
|
||||
req_access_txt = "29"
|
||||
|
||||
/obj/machinery/computer/rdconsole/core
|
||||
name = "Core R&D Console"
|
||||
id = 1
|
||||
@@ -0,0 +1,107 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
||||
|
||||
//All devices that link into the R&D console fall into thise type for easy identification and some shared procs.
|
||||
|
||||
|
||||
/obj/machinery/r_n_d
|
||||
name = "R&D Device"
|
||||
icon = 'icons/obj/machines/research.dmi'
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
var/busy = 0
|
||||
var/hacked = 0
|
||||
var/disabled = 0
|
||||
var/shocked = 0
|
||||
var/list/wires = list()
|
||||
var/hack_wire
|
||||
var/disable_wire
|
||||
var/shock_wire
|
||||
var/opened = 0
|
||||
var/obj/machinery/computer/rdconsole/linked_console
|
||||
|
||||
/obj/machinery/r_n_d/New()
|
||||
..()
|
||||
wires["Red"] = 0
|
||||
wires["Blue"] = 0
|
||||
wires["Green"] = 0
|
||||
wires["Yellow"] = 0
|
||||
wires["Black"] = 0
|
||||
wires["White"] = 0
|
||||
var/list/w = list("Red","Blue","Green","Yellow","Black","White")
|
||||
src.hack_wire = pick(w)
|
||||
w -= src.hack_wire
|
||||
src.shock_wire = pick(w)
|
||||
w -= src.shock_wire
|
||||
src.disable_wire = pick(w)
|
||||
w -= src.disable_wire
|
||||
|
||||
/obj/machinery/r_n_d/proc/
|
||||
shock(mob/user, prb)
|
||||
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
|
||||
return 0
|
||||
if(!prob(prb))
|
||||
return 0
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
if (electrocute_mob(user, get_area(src), src, 0.7))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/machinery/r_n_d/attack_hand(mob/user as mob)
|
||||
if (shocked)
|
||||
shock(user,50)
|
||||
if(opened)
|
||||
var/dat as text
|
||||
dat += "[src.name] Wires:<BR>"
|
||||
for(var/wire in src.wires)
|
||||
dat += text("[wire] Wire: <A href='?src=\ref[src];wire=[wire];cut=1'>[src.wires[wire] ? "Mend" : "Cut"]</A> <A href='?src=\ref[src];wire=[wire];pulse=1'>Pulse</A><BR>")
|
||||
|
||||
dat += text("The red light is [src.disabled ? "off" : "on"].<BR>")
|
||||
dat += text("The green light is [src.shocked ? "off" : "on"].<BR>")
|
||||
dat += text("The blue light is [src.hacked ? "off" : "on"].<BR>")
|
||||
user << browse("<HTML><HEAD><TITLE>[src.name] Hacking</TITLE></HEAD><BODY>[dat]</BODY></HTML>","window=hack_win")
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["pulse"])
|
||||
var/temp_wire = href_list["wire"]
|
||||
if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
|
||||
usr << "You need a multitool!"
|
||||
else
|
||||
if(src.wires[temp_wire])
|
||||
usr << "You can't pulse a cut wire."
|
||||
else
|
||||
if(src.hack_wire == href_list["wire"])
|
||||
src.hacked = !src.hacked
|
||||
spawn(100) src.hacked = !src.hacked
|
||||
if(src.disable_wire == href_list["wire"])
|
||||
src.disabled = !src.disabled
|
||||
src.shock(usr,50)
|
||||
spawn(100) src.disabled = !src.disabled
|
||||
if(src.shock_wire == href_list["wire"])
|
||||
src.shocked = !src.shocked
|
||||
src.shock(usr,50)
|
||||
spawn(100) src.shocked = !src.shocked
|
||||
if(href_list["cut"])
|
||||
if (!istype(usr.get_active_hand(), /obj/item/weapon/wirecutters))
|
||||
usr << "You need wirecutters!"
|
||||
else
|
||||
var/temp_wire = href_list["wire"]
|
||||
wires[temp_wire] = !wires[temp_wire]
|
||||
if(src.hack_wire == temp_wire)
|
||||
src.hacked = !src.hacked
|
||||
if(src.disable_wire == temp_wire)
|
||||
src.disabled = !src.disabled
|
||||
src.shock(usr,50)
|
||||
if(src.shock_wire == temp_wire)
|
||||
src.shocked = !src.shocked
|
||||
src.shock(usr,50)
|
||||
src.updateUsrDialog()
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
General Explination:
|
||||
The research datum is the "folder" where all the research information is stored in a R&D console. It's also a holder for all the
|
||||
various procs used to manipulate it. It has four variables and seven procs:
|
||||
|
||||
Variables:
|
||||
- possible_tech is a list of all the /datum/tech that can potentially be researched by the player. The RefreshResearch() proc
|
||||
(explained later) only goes through those when refreshing what you know. Generally, possible_tech contains ALL of the existing tech
|
||||
but it is possible to add tech to the game that DON'T start in it (example: Xeno tech). Generally speaking, you don't want to mess
|
||||
with these since they should be the default version of the datums. They're actually stored in a list rather then using typesof to
|
||||
refer to them since it makes it a bit easier to search through them for specific information.
|
||||
- know_tech is the companion list to possible_tech. It's the tech you can actually research and improve. Until it's added to this
|
||||
list, it can't be improved. All the tech in this list are visible to the player.
|
||||
- possible_designs is functionally identical to possbile_tech except it's for /datum/design.
|
||||
- known_designs is functionally identical to known_tech except it's for /datum/design
|
||||
|
||||
Procs:
|
||||
- TechHasReqs: Used by other procs (specifically RefreshResearch) to see whether all of a tech's requirements are currently in
|
||||
known_tech and at a high enough level.
|
||||
- DesignHasReqs: Same as TechHasReqs but for /datum/design and known_design.
|
||||
- AddTech2Known: Adds a /datum/tech to known_tech. It checks to see whether it already has that tech (if so, it just replaces it). If
|
||||
it doesn't have it, it adds it. Note: It does NOT check possible_tech at all. So if you want to add something strange to it (like
|
||||
a player made tech?) you can.
|
||||
- AddDesign2Known: Same as AddTech2Known except for /datum/design and known_designs.
|
||||
- RefreshResearch: This is the workhorse of the R&D system. It updates the /datum/research holder and adds any unlocked tech paths
|
||||
and designs you have reached the requirements for. It only checks through possible_tech and possible_designs, however, so it won't
|
||||
accidentally add "secret" tech to it.
|
||||
- UpdateTech is used as part of the actual researching process. It takes an ID and finds techs with that same ID in known_tech. When
|
||||
it finds it, it checks to see whether it can improve it at all. If the known_tech's level is less then or equal to
|
||||
the inputted level, it increases the known tech's level to the inputted level -1 or know tech's level +1 (whichever is higher).
|
||||
|
||||
The tech datums are the actual "tech trees" that you improve through researching. Each one has five variables:
|
||||
- Name: Pretty obvious. This is often viewable to the players.
|
||||
- Desc: Pretty obvious. Also player viewable.
|
||||
- ID: This is the unique ID of the tech that is used by the various procs to find and/or maniuplate it.
|
||||
- Level: This is the current level of the tech. All techs start at 1 and have a max of 20. Devices and some techs require a certain
|
||||
level in specific techs before you can produce them.
|
||||
- Req_tech: This is a list of the techs required to unlock this tech path. If left blank, it'll automatically be loaded into the
|
||||
research holder datum.
|
||||
|
||||
*/
|
||||
/***************************************************************
|
||||
** Master Types **
|
||||
** Includes all the helper procs and basic tech processing. **
|
||||
***************************************************************/
|
||||
|
||||
/datum/research //Holder for all the existing, archived, and known tech. Individual to console.
|
||||
|
||||
//Datum/tech go here.
|
||||
var/list/possible_tech = list() //List of all tech in the game that players have access to (barring special events).
|
||||
var/list/known_tech = list() //List of locally known tech.
|
||||
var/list/possible_designs = list() //List of all designs (at base reliability).
|
||||
var/list/known_designs = list() //List of available designs (at base reliability).
|
||||
|
||||
/datum/research/New() //Insert techs into possible_tech here. Known_tech automatically updated.
|
||||
for(var/T in typesof(/datum/tech) - /datum/tech)
|
||||
possible_tech += new T(src)
|
||||
for(var/D in typesof(/datum/design) - /datum/design)
|
||||
possible_designs += new D(src)
|
||||
RefreshResearch()
|
||||
|
||||
|
||||
|
||||
//Checks to see if tech has all the required pre-reqs.
|
||||
//Input: datum/tech; Output: 0/1 (false/true)
|
||||
/datum/research/proc/TechHasReqs(var/datum/tech/T)
|
||||
if(T.req_tech.len == 0)
|
||||
return 1
|
||||
var/matches = 0
|
||||
for(var/req in T.req_tech)
|
||||
for(var/datum/tech/known in known_tech)
|
||||
if((req == known.id) && (known.level >= T.req_tech[req]))
|
||||
matches++
|
||||
break
|
||||
if(matches == T.req_tech.len)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
//Checks to see if design has all the required pre-reqs.
|
||||
//Input: datum/design; Output: 0/1 (false/true)
|
||||
/datum/research/proc/DesignHasReqs(var/datum/design/D)
|
||||
if(D.req_tech.len == 0)
|
||||
return 1
|
||||
var/matches = 0
|
||||
var/list/k_tech = list()
|
||||
for(var/datum/tech/known in known_tech)
|
||||
k_tech[known.id] = known.level
|
||||
for(var/req in D.req_tech)
|
||||
if(!isnull(k_tech[req]) && k_tech[req] >= D.req_tech[req])
|
||||
matches++
|
||||
if(matches == D.req_tech.len)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
/*
|
||||
//Checks to see if design has all the required pre-reqs.
|
||||
//Input: datum/design; Output: 0/1 (false/true)
|
||||
/datum/research/proc/DesignHasReqs(var/datum/design/D)
|
||||
if(D.req_tech.len == 0)
|
||||
return 1
|
||||
var/matches = 0
|
||||
for(var/req in D.req_tech)
|
||||
for(var/datum/tech/known in known_tech)
|
||||
if((req == known.id) && (known.level >= D.req_tech[req]))
|
||||
matches++
|
||||
break
|
||||
if(matches == D.req_tech.len)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
*/
|
||||
//Adds a tech to known_tech list. Checks to make sure there aren't duplicates and updates existing tech's levels if needed.
|
||||
//Input: datum/tech; Output: Null
|
||||
/datum/research/proc/AddTech2Known(var/datum/tech/T)
|
||||
for(var/datum/tech/known in known_tech)
|
||||
if(T.id == known.id)
|
||||
if(T.level > known.level)
|
||||
known.level = T.level
|
||||
return
|
||||
known_tech += T
|
||||
return
|
||||
|
||||
/datum/research/proc/AddDesign2Known(var/datum/design/D)
|
||||
for(var/datum/design/known in known_designs)
|
||||
if(D.id == known.id)
|
||||
if(D.reliability_mod > known.reliability_mod)
|
||||
known.reliability_mod = D.reliability_mod
|
||||
return
|
||||
known_designs += D
|
||||
return
|
||||
|
||||
//Refreshes known_tech and known_designs list. Then updates the reliability vars of the designs in the known_designs list.
|
||||
//Input/Output: n/a
|
||||
/datum/research/proc/RefreshResearch()
|
||||
for(var/datum/tech/PT in possible_tech)
|
||||
if(TechHasReqs(PT))
|
||||
AddTech2Known(PT)
|
||||
for(var/datum/design/PD in possible_designs)
|
||||
if(DesignHasReqs(PD))
|
||||
AddDesign2Known(PD)
|
||||
for(var/datum/tech/T in known_tech)
|
||||
T = between(1,T.level,20)
|
||||
for(var/datum/design/D in known_designs)
|
||||
D.CalcReliability(known_tech)
|
||||
return
|
||||
|
||||
//Refreshes the levels of a given tech.
|
||||
//Input: Tech's ID and Level; Output: null
|
||||
/datum/research/proc/UpdateTech(var/ID, var/level)
|
||||
for(var/datum/tech/KT in known_tech)
|
||||
if(KT.id == ID)
|
||||
if(KT.level <= level) KT.level = max((KT.level + 1), (level - 1))
|
||||
return
|
||||
|
||||
/datum/research/proc/UpdateDesign(var/path)
|
||||
for(var/datum/design/KD in known_designs)
|
||||
if(KD.build_path == path)
|
||||
KD.reliability_mod += rand(1,2)
|
||||
break
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
** Technology Datums **
|
||||
** Includes all the various technoliges and what they make. **
|
||||
***************************************************************/
|
||||
|
||||
datum/tech //Datum of individual technologies.
|
||||
var/name = "name" //Name of the technology.
|
||||
var/desc = "description" //General description of what it does and what it makes.
|
||||
var/id = "id" //An easily referenced ID. Must be alphanumeric, lower-case, and no symbols.
|
||||
var/level = 1 //A simple number scale of the research level. Level 0 = Secret tech.
|
||||
var/list/req_tech = list() //List of ids associated values of techs required to research this tech. "id" = #
|
||||
|
||||
|
||||
//Trunk Technologies (don't require any other techs and you start knowning them).
|
||||
|
||||
datum/tech/materials
|
||||
name = "Materials Research"
|
||||
desc = "Development of new and improved materials."
|
||||
id = "materials"
|
||||
|
||||
datum/tech/engineering
|
||||
name = "Engineering Research"
|
||||
desc = "Development of new and improved engineering parts and."
|
||||
id = "engineering"
|
||||
|
||||
datum/tech/plasmatech
|
||||
name = "Plasma Research"
|
||||
desc = "Research into the mysterious substance colloqually known as 'plasma'."
|
||||
id = "plasmatech"
|
||||
|
||||
datum/tech/powerstorage
|
||||
name = "Power Manipulation Technology"
|
||||
desc = "The various technologies behind the storage and generation of electicity."
|
||||
id = "powerstorage"
|
||||
|
||||
datum/tech/bluespace
|
||||
name = "'Blue-space' Research"
|
||||
desc = "Research into the sub-reality known as 'blue-space'"
|
||||
id = "bluespace"
|
||||
|
||||
datum/tech/biotech
|
||||
name = "Biological Technology"
|
||||
desc = "Research into the deeper mysteries of life and organic substances."
|
||||
id = "biotech"
|
||||
|
||||
datum/tech/combat
|
||||
name = "Combat Systems Research"
|
||||
desc = "The development of offensive and defensive systems."
|
||||
id = "combat"
|
||||
|
||||
datum/tech/magnets
|
||||
name = "Electromagnetic Spectrum Research"
|
||||
desc = "Research into the electromagnetic spectrum. No clue how they actually work, though."
|
||||
id = "magnets"
|
||||
|
||||
datum/tech/programming
|
||||
name = "Data Theory Research"
|
||||
desc = "The development of new computer and artificial intelligence and data storage systems."
|
||||
id = "programming"
|
||||
|
||||
datum/tech/syndicate
|
||||
name = "Illegal Technologies Research"
|
||||
desc = "The study of technologies that violate standard Nanotrasen regulations."
|
||||
id = "syndicate"
|
||||
|
||||
/*
|
||||
datum/tech/arcane
|
||||
name = "Arcane Research"
|
||||
desc = "Research into the occult and arcane field for use in practical science"
|
||||
id = "arcane"
|
||||
level = 0 //It didn't become "secret" as advertised.
|
||||
|
||||
//Branch Techs
|
||||
datum/tech/explosives
|
||||
name = "Explosives Research"
|
||||
desc = "The creation and application of explosive materials."
|
||||
id = "explosives"
|
||||
req_tech = list("materials" = 3)
|
||||
|
||||
datum/tech/generators
|
||||
name = "Power Generation Technology"
|
||||
desc = "Research into more powerful and more reliable sources."
|
||||
id = "generators"
|
||||
req_tech = list("powerstorage" = 2)
|
||||
|
||||
datum/tech/robotics
|
||||
name = "Robotics Technology"
|
||||
desc = "The development of advanced automated, autonomous machines."
|
||||
id = "robotics"
|
||||
req_tech = list("materials" = 3, "programming" = 3)
|
||||
*/
|
||||
|
||||
|
||||
/obj/item/weapon/disk/tech_disk
|
||||
name = "Technology Disk"
|
||||
desc = "A disk for storing technology data for further research."
|
||||
icon = 'icons/obj/cloning.dmi'
|
||||
icon_state = "datadisk2"
|
||||
item_state = "card-id"
|
||||
w_class = 1.0
|
||||
m_amt = 30
|
||||
g_amt = 10
|
||||
var/datum/tech/stored
|
||||
|
||||
/obj/item/weapon/disk/tech_disk/New()
|
||||
src.pixel_x = rand(-5.0, 5)
|
||||
src.pixel_y = rand(-5.0, 5)
|
||||
@@ -0,0 +1,127 @@
|
||||
|
||||
/**********************Shuttle Computer**************************/
|
||||
|
||||
//copy paste from the mining shuttle
|
||||
|
||||
var/research_shuttle_tickstomove = 10
|
||||
var/research_shuttle_moving = 0
|
||||
var/research_shuttle_location = 0 // 0 = station 13, 1 = research station
|
||||
|
||||
proc/move_research_shuttle()
|
||||
if(research_shuttle_moving) return
|
||||
research_shuttle_moving = 1
|
||||
spawn(research_shuttle_tickstomove*10)
|
||||
var/area/fromArea
|
||||
var/area/toArea
|
||||
if (research_shuttle_location == 1)
|
||||
fromArea = locate(/area/shuttle/research/outpost)
|
||||
toArea = locate(/area/shuttle/research/station)
|
||||
else
|
||||
fromArea = locate(/area/shuttle/research/station)
|
||||
toArea = locate(/area/shuttle/research/outpost)
|
||||
|
||||
|
||||
var/list/dstturfs = list()
|
||||
var/throwy = world.maxy
|
||||
|
||||
for(var/turf/T in toArea)
|
||||
dstturfs += T
|
||||
if(T.y < throwy)
|
||||
throwy = T.y
|
||||
|
||||
// hey you, get out of the way!
|
||||
for(var/turf/T in dstturfs)
|
||||
// find the turf to move things to
|
||||
var/turf/D = locate(T.x, throwy - 1, 1)
|
||||
//var/turf/E = get_step(D, SOUTH)
|
||||
for(var/atom/movable/AM as mob|obj in T)
|
||||
AM.Move(D)
|
||||
// NOTE: Commenting this out to avoid recreating mass driver glitch
|
||||
/*
|
||||
spawn(0)
|
||||
AM.throw_at(E, 1, 1)
|
||||
return
|
||||
*/
|
||||
|
||||
if(istype(T, /turf/simulated))
|
||||
del(T)
|
||||
|
||||
for(var/mob/living/carbon/bug in toArea) // If someone somehow is still in the shuttle's docking area...
|
||||
bug.gib()
|
||||
|
||||
for(var/mob/living/simple_animal/pest in toArea) // And for the other kind of bug...
|
||||
pest.gib()
|
||||
|
||||
fromArea.move_contents_to(toArea)
|
||||
if (research_shuttle_location)
|
||||
research_shuttle_location = 0
|
||||
else
|
||||
research_shuttle_location = 1
|
||||
research_shuttle_moving = 0
|
||||
return
|
||||
|
||||
/obj/machinery/computer/research_shuttle
|
||||
name = "Research Shuttle Console"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_state = "shuttle"
|
||||
req_access = list(access_research)
|
||||
circuit = "/obj/item/weapon/circuitboard/research_shuttle"
|
||||
var/hacked = 0
|
||||
var/location = 0 //0 = station, 1 = research base
|
||||
|
||||
/obj/machinery/computer/research_shuttle/attack_hand(user as mob)
|
||||
src.add_fingerprint(usr)
|
||||
var/dat = "<center>Research shuttle: <b><A href='?src=\ref[src];move=1'>Send</A></b></center><br>"
|
||||
|
||||
user << browse("[dat]", "window=researchshuttle;size=200x100")
|
||||
|
||||
/obj/machinery/computer/research_shuttle/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
usr.machine = src
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["move"])
|
||||
//if(ticker.mode.name == "blob")
|
||||
// if(ticker.mode:declared)
|
||||
// usr << "Under directive 7-10, [station_name()] is quarantined until further notice."
|
||||
// return
|
||||
|
||||
if (!research_shuttle_moving)
|
||||
usr << "\blue Shuttle recieved message and will be sent shortly."
|
||||
move_research_shuttle()
|
||||
else
|
||||
usr << "\blue Shuttle is already moving."
|
||||
|
||||
/obj/machinery/computer/research_shuttle/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
if (istype(W, /obj/item/weapon/card/emag))
|
||||
var/obj/item/weapon/card/emag/E = W
|
||||
if(E.uses)
|
||||
E.uses--
|
||||
else
|
||||
return
|
||||
src.req_access = list()
|
||||
hacked = 1
|
||||
usr << "You fried the consoles ID checking system. It's now available to everyone!"
|
||||
|
||||
else if(istype(W, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/item/weapon/circuitboard/research_shuttle/M = new /obj/item/weapon/circuitboard/research_shuttle( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
|
||||
if (src.stat & BROKEN)
|
||||
user << "\blue The broken glass falls out."
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
|
||||
del(src)
|
||||
@@ -0,0 +1,380 @@
|
||||
/obj/machinery/r_n_d/server
|
||||
name = "R&D Server"
|
||||
icon = 'icons/obj/machines/research.dmi'
|
||||
icon_state = "server"
|
||||
var/datum/research/files
|
||||
var/health = 100
|
||||
var/list/id_with_upload = list() //List of R&D consoles with upload to server access.
|
||||
var/list/id_with_download = list() //List of R&D consoles with download from server access.
|
||||
var/id_with_upload_string = "" //String versions for easy editing in map editor.
|
||||
var/id_with_download_string = ""
|
||||
var/server_id = 0
|
||||
var/heat_gen = 100
|
||||
var/heating_power = 40000
|
||||
var/delay = 10
|
||||
req_access = list(access_rd) //Only the R&D can change server settings.
|
||||
|
||||
/obj/machinery/r_n_d/server/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/rdserver(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/cable_coil(src)
|
||||
component_parts += new /obj/item/weapon/cable_coil(src)
|
||||
RefreshParts()
|
||||
src.initialize(); //Agouri
|
||||
|
||||
/obj/machinery/r_n_d/server/Del()
|
||||
griefProtection()
|
||||
..()
|
||||
|
||||
/obj/machinery/r_n_d/server/RefreshParts()
|
||||
var/tot_rating = 0
|
||||
for(var/obj/item/weapon/stock_parts/SP in src)
|
||||
tot_rating += SP.rating
|
||||
heat_gen /= max(1, tot_rating)
|
||||
|
||||
/obj/machinery/r_n_d/server/initialize()
|
||||
if(!files) files = new /datum/research(src)
|
||||
var/list/temp_list
|
||||
if(!id_with_upload.len)
|
||||
temp_list = list()
|
||||
temp_list = text2list(id_with_upload_string, ";")
|
||||
for(var/N in temp_list)
|
||||
id_with_upload += text2num(N)
|
||||
if(!id_with_download.len)
|
||||
temp_list = list()
|
||||
temp_list = text2list(id_with_download_string, ";")
|
||||
for(var/N in temp_list)
|
||||
id_with_download += text2num(N)
|
||||
|
||||
/obj/machinery/r_n_d/server/process()
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
switch(environment.temperature)
|
||||
if(0 to T0C)
|
||||
health = min(100, health + 1)
|
||||
if(T0C to (T20C + 20))
|
||||
health = between(0, health, 100)
|
||||
if((T20C + 20) to (T0C + 70))
|
||||
health = max(0, health - 1)
|
||||
if(health <= 0)
|
||||
griefProtection() //I dont like putting this in process() but it's the best I can do without re-writing a chunk of rd servers.
|
||||
files.known_designs = list()
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
if(prob(1))
|
||||
T.level--
|
||||
files.RefreshResearch()
|
||||
if(delay)
|
||||
delay--
|
||||
else
|
||||
produce_heat(heat_gen)
|
||||
delay = initial(delay)
|
||||
|
||||
/obj/machinery/r_n_d/server/meteorhit(var/obj/O as obj)
|
||||
griefProtection()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/server/emp_act(severity)
|
||||
griefProtection()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/server/ex_act(severity)
|
||||
griefProtection()
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/server/blob_act()
|
||||
griefProtection()
|
||||
..()
|
||||
|
||||
|
||||
|
||||
//Backup files to centcomm to help admins recover data after greifer attacks
|
||||
/obj/machinery/r_n_d/server/proc/griefProtection()
|
||||
for(var/obj/machinery/r_n_d/server/centcom/C in machines)
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
C.files.AddTech2Known(T)
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
C.files.AddDesign2Known(D)
|
||||
C.files.RefreshResearch()
|
||||
|
||||
/obj/machinery/r_n_d/server/proc/produce_heat(heat_amt)
|
||||
if(!(stat & (NOPOWER|BROKEN))) //Blatently stolen from space heater.
|
||||
var/turf/simulated/L = loc
|
||||
if(istype(L))
|
||||
var/datum/gas_mixture/env = L.return_air()
|
||||
if(env.temperature < (heat_amt+T0C))
|
||||
|
||||
var/transfer_moles = 0.25 * env.total_moles()
|
||||
|
||||
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
||||
|
||||
if(removed)
|
||||
|
||||
var/heat_capacity = removed.heat_capacity()
|
||||
if(heat_capacity == 0 || heat_capacity == null)
|
||||
heat_capacity = 1
|
||||
removed.temperature = min((removed.temperature*heat_capacity + heating_power)/heat_capacity, 1000)
|
||||
|
||||
env.merge(removed)
|
||||
|
||||
/obj/machinery/r_n_d/server/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if (disabled)
|
||||
return
|
||||
if (shocked)
|
||||
shock(user,50)
|
||||
if (istype(O, /obj/item/weapon/screwdriver))
|
||||
if (!opened)
|
||||
opened = 1
|
||||
icon_state = "server_o"
|
||||
user << "You open the maintenance hatch of [src]."
|
||||
else
|
||||
opened = 0
|
||||
icon_state = "server"
|
||||
user << "You close the maintenance hatch of [src]."
|
||||
return
|
||||
if (opened)
|
||||
if(istype(O, /obj/item/weapon/crowbar))
|
||||
griefProtection()
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc)
|
||||
M.state = 2
|
||||
M.icon_state = "box_1"
|
||||
for(var/obj/I in component_parts)
|
||||
if(I.reliability != 100 && crit_fail)
|
||||
I.crit_fail = 1
|
||||
I.loc = src.loc
|
||||
del(src)
|
||||
return 1
|
||||
|
||||
/obj/machinery/r_n_d/server/attack_hand(mob/user as mob)
|
||||
if (disabled)
|
||||
return
|
||||
if (shocked)
|
||||
shock(user,50)
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/server/centcom
|
||||
name = "Centcom Central R&D Database"
|
||||
server_id = -1
|
||||
|
||||
/obj/machinery/r_n_d/server/centcom/initialize()
|
||||
..()
|
||||
var/list/no_id_servers = list()
|
||||
var/list/server_ids = list()
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
switch(S.server_id)
|
||||
if(-1)
|
||||
continue
|
||||
if(0)
|
||||
no_id_servers += S
|
||||
else
|
||||
server_ids += S.server_id
|
||||
|
||||
for(var/obj/machinery/r_n_d/server/S in no_id_servers)
|
||||
var/num = 1
|
||||
while(!S.server_id)
|
||||
if(num in server_ids)
|
||||
num++
|
||||
else
|
||||
S.server_id = num
|
||||
server_ids += num
|
||||
no_id_servers -= S
|
||||
|
||||
/obj/machinery/r_n_d/server/centcom/process()
|
||||
return PROCESS_KILL //don't need process()
|
||||
|
||||
|
||||
/obj/machinery/computer/rdservercontrol
|
||||
name = "R&D Server Controller"
|
||||
icon_state = "rdcomp"
|
||||
var/screen = 0
|
||||
var/obj/machinery/r_n_d/server/temp_server
|
||||
var/list/servers = list()
|
||||
var/list/consoles = list()
|
||||
var/badmin = 0
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
usr.set_machine(src)
|
||||
if(!src.allowed(usr) && !emagged)
|
||||
usr << "\red You do not have the required access level"
|
||||
return
|
||||
|
||||
if(href_list["main"])
|
||||
screen = 0
|
||||
|
||||
else if(href_list["access"] || href_list["data"] || href_list["transfer"])
|
||||
temp_server = null
|
||||
consoles = list()
|
||||
servers = list()
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
if(S.server_id == text2num(href_list["access"]) || S.server_id == text2num(href_list["data"]) || S.server_id == text2num(href_list["transfer"]))
|
||||
temp_server = S
|
||||
break
|
||||
if(href_list["access"])
|
||||
screen = 1
|
||||
for(var/obj/machinery/computer/rdconsole/C in machines)
|
||||
if(C.sync)
|
||||
consoles += C
|
||||
else if(href_list["data"])
|
||||
screen = 2
|
||||
else if(href_list["transfer"])
|
||||
screen = 3
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
if(S == src)
|
||||
continue
|
||||
servers += S
|
||||
|
||||
else if(href_list["upload_toggle"])
|
||||
var/num = text2num(href_list["upload_toggle"])
|
||||
if(num in temp_server.id_with_upload)
|
||||
temp_server.id_with_upload -= num
|
||||
else
|
||||
temp_server.id_with_upload += num
|
||||
|
||||
else if(href_list["download_toggle"])
|
||||
var/num = text2num(href_list["download_toggle"])
|
||||
if(num in temp_server.id_with_download)
|
||||
temp_server.id_with_download -= num
|
||||
else
|
||||
temp_server.id_with_download += num
|
||||
|
||||
else if(href_list["reset_tech"])
|
||||
var/choice = alert("Technology Data Rest", "Are you sure you want to reset this technology to its default data? Data lost cannot be recovered.", "Continue", "Cancel")
|
||||
if(choice == "Continue")
|
||||
for(var/datum/tech/T in temp_server.files.known_tech)
|
||||
if(T.id == href_list["reset_tech"])
|
||||
T.level = 1
|
||||
break
|
||||
temp_server.files.RefreshResearch()
|
||||
|
||||
else if(href_list["reset_design"])
|
||||
var/choice = alert("Design Data Deletion", "Are you sure you want to delete this design? If you still have the prerequisites for the design, it'll reset to its base reliability. Data lost cannot be recovered.", "Continue", "Cancel")
|
||||
if(choice == "Continue")
|
||||
for(var/datum/design/D in temp_server.files.known_designs)
|
||||
if(D.id == href_list["reset_design"])
|
||||
D.reliability_mod = 0
|
||||
temp_server.files.known_designs -= D
|
||||
break
|
||||
temp_server.files.RefreshResearch()
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/attack_hand(mob/user as mob)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = ""
|
||||
|
||||
switch(screen)
|
||||
if(0) //Main Menu
|
||||
dat += "Connected Servers:<BR><BR>"
|
||||
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
if(istype(S, /obj/machinery/r_n_d/server/centcom) && !badmin)
|
||||
continue
|
||||
dat += "[S.name] || "
|
||||
dat += "<A href='?src=\ref[src];access=[S.server_id]'> Access Rights</A> | "
|
||||
dat += "<A href='?src=\ref[src];data=[S.server_id]'>Data Management</A>"
|
||||
if(badmin) dat += " | <A href='?src=\ref[src];transfer=[S.server_id]'>Server-to-Server Transfer</A>"
|
||||
dat += "<BR>"
|
||||
|
||||
if(1) //Access rights menu
|
||||
dat += "[temp_server.name] Access Rights<BR><BR>"
|
||||
dat += "Consoles with Upload Access<BR>"
|
||||
for(var/obj/machinery/computer/rdconsole/C in consoles)
|
||||
var/turf/console_turf = get_turf(C)
|
||||
dat += "* <A href='?src=\ref[src];upload_toggle=[C.id]'>[console_turf.loc]" //FYI, these are all numeric ids, eventually.
|
||||
if(C.id in temp_server.id_with_upload)
|
||||
dat += " (Remove)</A><BR>"
|
||||
else
|
||||
dat += " (Add)</A><BR>"
|
||||
dat += "Consoles with Download Access<BR>"
|
||||
for(var/obj/machinery/computer/rdconsole/C in consoles)
|
||||
var/turf/console_turf = get_turf(C)
|
||||
dat += "* <A href='?src=\ref[src];download_toggle=[C.id]'>[console_turf.loc]"
|
||||
if(C.id in temp_server.id_with_download)
|
||||
dat += " (Remove)</A><BR>"
|
||||
else
|
||||
dat += " (Add)</A><BR>"
|
||||
dat += "<HR><A href='?src=\ref[src];main=1'>Main Menu</A>"
|
||||
|
||||
if(2) //Data Management menu
|
||||
dat += "[temp_server.name] Data ManagementP<BR><BR>"
|
||||
dat += "Known Technologies<BR>"
|
||||
for(var/datum/tech/T in temp_server.files.known_tech)
|
||||
dat += "* [T.name] "
|
||||
dat += "<A href='?src=\ref[src];reset_tech=[T.id]'>(Reset)</A><BR>" //FYI, these are all strings.
|
||||
dat += "Known Designs<BR>"
|
||||
for(var/datum/design/D in temp_server.files.known_designs)
|
||||
dat += "* [D.name] "
|
||||
dat += "<A href='?src=\ref[src];reset_design=[D.id]'>(Delete)</A><BR>"
|
||||
dat += "<HR><A href='?src=\ref[src];main=1'>Main Menu</A>"
|
||||
|
||||
if(3) //Server Data Transfer
|
||||
dat += "[temp_server.name] Server to Server Transfer<BR><BR>"
|
||||
dat += "Send Data to what server?<BR>"
|
||||
for(var/obj/machinery/r_n_d/server/S in servers)
|
||||
dat += "[S.name] <A href='?src=\ref[src];send_to=[S.server_id]'> (Transfer)</A><BR>"
|
||||
dat += "<HR><A href='?src=\ref[src];main=1'>Main Menu</A>"
|
||||
user << browse("<TITLE>R&D Server Control</TITLE><HR>[dat]", "window=server_control;size=575x400")
|
||||
onclose(user, "server_control")
|
||||
return
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
|
||||
if(istype(D, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
if (src.stat & BROKEN)
|
||||
user << "\blue The broken glass falls out."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
var/obj/item/weapon/circuitboard/rdservercontrol/M = new /obj/item/weapon/circuitboard/rdservercontrol( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/item/weapon/circuitboard/rdservercontrol/M = new /obj/item/weapon/circuitboard/rdservercontrol( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = 1
|
||||
user << "\blue You you disable the security protocols"
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/server/robotics
|
||||
name = "Robotics R&D Server"
|
||||
id_with_upload_string = "1;2"
|
||||
id_with_download_string = "1;2"
|
||||
server_id = 2
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/server/core
|
||||
name = "Core R&D Server"
|
||||
id_with_upload_string = "1"
|
||||
id_with_download_string = "1"
|
||||
server_id = 1
|
||||
@@ -0,0 +1,76 @@
|
||||
|
||||
/area/research_outpost
|
||||
name = "Research Outpost"
|
||||
icon_state = "anomaly"
|
||||
|
||||
/area/research_outpost/hallway
|
||||
name = "Research Outpost Hallway"
|
||||
icon_state = "hallC"
|
||||
|
||||
/area/research_outpost/gearstore
|
||||
name = "Expedition Preparation"
|
||||
icon_state = "anog"
|
||||
|
||||
/area/research_outpost/power
|
||||
name = "Research Outpost Power"
|
||||
icon_state = "engine"
|
||||
|
||||
/area/research_outpost/atmos
|
||||
name = "Research Outpost Atmospherics"
|
||||
icon_state = "atmos"
|
||||
|
||||
/area/research_outpost/maint
|
||||
name = "Research Outpost Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
|
||||
/area/research_outpost/iso1
|
||||
name = "Isolation Cell"
|
||||
icon_state = "iso1"
|
||||
|
||||
/area/research_outpost/iso2
|
||||
name = "Isolation Cell"
|
||||
icon_state = "iso2"
|
||||
|
||||
/area/research_outpost/iso3
|
||||
name = "Isolation Cell"
|
||||
icon_state = "iso3"
|
||||
|
||||
/area/research_outpost/harvesting
|
||||
name = "Exotic Particles Collection"
|
||||
icon_state = "anolab"
|
||||
|
||||
/area/research_outpost/sample
|
||||
name = "Sample Preparation Room"
|
||||
icon_state = "anosample"
|
||||
|
||||
/area/research_outpost/spectro
|
||||
name = "Mass Spectrometry Lab"
|
||||
icon_state = "anospectro"
|
||||
|
||||
/area/research_outpost/anomaly
|
||||
name = "Anomalous Materials Lab"
|
||||
icon_state = "anolab"
|
||||
|
||||
/area/research_outpost/med
|
||||
name = "Research Outpost Medbay"
|
||||
icon_state = "medbay3"
|
||||
|
||||
/area/research_outpost/entry
|
||||
name = "Research Outpost Shuttle Dock"
|
||||
icon_state = "entry"
|
||||
|
||||
/area/research_outpost/longtermstorage
|
||||
name = "Long-Term Storage"
|
||||
icon_state = "primarystorage"
|
||||
|
||||
/area/research_outpost/tempstorage
|
||||
name = "Temporary Storage"
|
||||
icon_state = "storage"
|
||||
|
||||
/area/research_outpost/maintstore1
|
||||
name = "Auxiliary Storage"
|
||||
icon_state = "auxstorage"
|
||||
|
||||
/area/research_outpost/maintstore2
|
||||
name = "Maintenance Storage"
|
||||
icon_state = "auxstorage"
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Large finds - (Potentially) active alien machinery from the dawn of time
|
||||
|
||||
/datum/artifact_find
|
||||
var/artifact_id
|
||||
var/artifact_find_type
|
||||
var/artifact_detect_range
|
||||
|
||||
/datum/artifact_find/New()
|
||||
artifact_detect_range = rand(5,300)
|
||||
|
||||
artifact_id = "[pick("kappa","sigma","antaeres","beta","omicron","iota","epsilon","omega","gamma","delta","tau","alpha")]-[rand(100,999)]"
|
||||
|
||||
artifact_find_type = pick(\
|
||||
5;/obj/machinery/power/supermatter,\
|
||||
5;/obj/structure/constructshell,\
|
||||
5;/obj/machinery/syndicate_beacon,\
|
||||
25;/obj/machinery/power/supermatter/shard,\
|
||||
50;/obj/structure/cult/pylon,\
|
||||
100;/obj/machinery/auto_cloner,\
|
||||
100;/obj/machinery/giga_drill,\
|
||||
100;/obj/mecha/working/hoverpod,\
|
||||
100;/obj/machinery/replicator,\
|
||||
150;/obj/structure/crystal,\
|
||||
1000;/obj/machinery/artifact)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Boulders - sometimes turn up after excavating turf - excavate further to try and find large xenoarch finds
|
||||
|
||||
/obj/structure/boulder
|
||||
name = "rocky debris"
|
||||
desc = "Leftover rock from an excavation, it's been partially dug out already but there's still a lot to go."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "boulder1"
|
||||
density = 1
|
||||
opacity = 1
|
||||
anchored = 1
|
||||
var/excavation_level = 0
|
||||
var/datum/geosample/geological_data
|
||||
var/datum/artifact_find/artifact_find
|
||||
|
||||
/obj/structure/boulder/New()
|
||||
icon_state = "boulder[rand(1,4)]"
|
||||
excavation_level = rand(5,50)
|
||||
|
||||
/obj/structure/boulder/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/device/core_sampler))
|
||||
src.geological_data.artifact_distance = rand(-100,100) / 100
|
||||
src.geological_data.artifact_id = artifact_find.artifact_id
|
||||
|
||||
var/obj/item/device/core_sampler/C = W
|
||||
C.sample_item(src, user)
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/depth_scanner))
|
||||
var/obj/item/device/depth_scanner/C = W
|
||||
C.scan_atom(user, src)
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/measuring_tape))
|
||||
var/obj/item/device/measuring_tape/P = W
|
||||
user.visible_message("\blue[user] extends [P] towards [src].","\blue You extend [P] towards [src].")
|
||||
if(do_after(user,40))
|
||||
user << "\blue \icon[P] [src] has been excavated to a depth of [2*src.excavation_level]cm."
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/weapon/pickaxe))
|
||||
var/obj/item/weapon/pickaxe/P = W
|
||||
|
||||
user << "\red You start [P.drill_verb] [src]."
|
||||
|
||||
if(!do_after(user,P.digspeed))
|
||||
return
|
||||
|
||||
user << "\blue You finish [P.drill_verb] [src]."
|
||||
excavation_level += P.excavation_amount
|
||||
|
||||
if(excavation_level > 100)
|
||||
//failure
|
||||
user.visible_message("<font color='red'><b>[src] suddenly crumbles away.</b></font>",\
|
||||
"\red [src] has disintegrated under your onslaught, any secrets it was holding are long gone.")
|
||||
del(src)
|
||||
return
|
||||
|
||||
if(prob(excavation_level))
|
||||
//success
|
||||
if(artifact_find)
|
||||
var/spawn_type = artifact_find.artifact_find_type
|
||||
var/obj/O = new spawn_type(get_turf(src))
|
||||
if(istype(O,/obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/X = O
|
||||
if(X.my_effect)
|
||||
X.my_effect.artifact_id = artifact_find.artifact_id
|
||||
src.visible_message("<font color='red'><b>[src] suddenly crumbles away.</b></font>")
|
||||
else
|
||||
user.visible_message("<font color='red'><b>[src] suddenly crumbles away.</b></font>",\
|
||||
"\blue [src] has been whittled away under your careful excavation, but there was nothing of interest inside.")
|
||||
del(src)
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
/obj/machinery/auto_cloner
|
||||
name = "mysterious pod"
|
||||
desc = "It's full of a viscous liquid, but appears dark and silent."
|
||||
icon = 'icons/obj/cryogenics.dmi'
|
||||
icon_state = "cellold0"
|
||||
var/spawn_type
|
||||
var/current_ticks_spawning = 0
|
||||
var/ticks_required_to_spawn
|
||||
density = 1
|
||||
var/previous_power_state = 0
|
||||
|
||||
use_power = 1
|
||||
active_power_usage = 2000
|
||||
idle_power_usage = 1000
|
||||
|
||||
/obj/machinery/auto_cloner/New()
|
||||
..()
|
||||
|
||||
ticks_required_to_spawn = rand(240,1440)
|
||||
|
||||
//33% chance to spawn nasties
|
||||
if(prob(33))
|
||||
spawn_type = pick(\
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse,\
|
||||
/mob/living/simple_animal/hostile/alien,\
|
||||
/mob/living/simple_animal/hostile/bear,\
|
||||
/mob/living/simple_animal/hostile/creature,\
|
||||
/mob/living/simple_animal/hostile/panther,\
|
||||
/mob/living/simple_animal/hostile/snake\
|
||||
)
|
||||
else
|
||||
spawn_type = pick(\
|
||||
/mob/living/simple_animal/cat,\
|
||||
/mob/living/simple_animal/corgi,\
|
||||
/mob/living/simple_animal/corgi/puppy,\
|
||||
/mob/living/simple_animal/chicken,\
|
||||
/mob/living/simple_animal/cow,\
|
||||
/mob/living/simple_animal/parrot,\
|
||||
/mob/living/simple_animal/slime,\
|
||||
/mob/living/simple_animal/crab,\
|
||||
/mob/living/simple_animal/mouse,\
|
||||
/mob/living/simple_animal/hostile/retaliate/goat,\
|
||||
/mob/living/carbon/monkey\
|
||||
)
|
||||
|
||||
//todo: how the hell is the asteroid permanently powered?
|
||||
/obj/machinery/auto_cloner/process()
|
||||
if(powered(power_channel))
|
||||
if(!previous_power_state)
|
||||
previous_power_state = 1
|
||||
icon_state = "cellold1"
|
||||
src.visible_message("\blue \icon[src] [src] suddenly comes to life!")
|
||||
|
||||
//slowly grow a mob
|
||||
current_ticks_spawning++
|
||||
if(prob(5))
|
||||
src.visible_message("\blue \icon[src] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].")
|
||||
|
||||
//if we've finished growing...
|
||||
if(current_ticks_spawning >= ticks_required_to_spawn)
|
||||
current_ticks_spawning = 0
|
||||
use_power = 1
|
||||
src.visible_message("\blue \icon[src] [src] pings!")
|
||||
icon_state = "cellold1"
|
||||
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow."
|
||||
if(spawn_type)
|
||||
new spawn_type(src.loc)
|
||||
|
||||
//if we're getting close to finished, kick into overdrive power usage
|
||||
if(current_ticks_spawning / ticks_required_to_spawn > 0.75)
|
||||
use_power = 2
|
||||
icon_state = "cellold2"
|
||||
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow. A dark shape appears to be forming inside..."
|
||||
else
|
||||
use_power = 1
|
||||
icon_state = "cellold1"
|
||||
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow."
|
||||
else
|
||||
if(previous_power_state)
|
||||
previous_power_state = 0
|
||||
icon_state = "cellold0"
|
||||
src.visible_message("\blue \icon[src] [src] suddenly shuts down.")
|
||||
|
||||
//cloned mob slowly breaks down
|
||||
if(current_ticks_spawning > 0)
|
||||
current_ticks_spawning--
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
/obj/structure/crystal
|
||||
name = "large crystal"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "crystal"
|
||||
density = 1
|
||||
|
||||
/obj/structure/crystal/New()
|
||||
..()
|
||||
|
||||
icon_state = pick("ano70","ano80")
|
||||
|
||||
desc = pick(\
|
||||
"It shines faintly as it catches the light.",\
|
||||
"It appears to have a faint inner glow.",\
|
||||
"It seems to draw you inward as you look it at.",\
|
||||
"Something twinkles faintly as you look at it.",\
|
||||
"It's mesmerizing to behold.")
|
||||
|
||||
/obj/structure/crystal/Del()
|
||||
src.visible_message("\red<b>[src] shatters!</b>")
|
||||
if(prob(75))
|
||||
new /obj/item/weapon/shard/plasma(src.loc)
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/shard/plasma(src.loc)
|
||||
if(prob(25))
|
||||
new /obj/item/weapon/shard/plasma(src.loc)
|
||||
if(prob(75))
|
||||
new /obj/item/weapon/shard(src.loc)
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/shard(src.loc)
|
||||
if(prob(25))
|
||||
new /obj/item/weapon/shard(src.loc)
|
||||
..()
|
||||
|
||||
//todo: laser_act
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
/obj/machinery/giga_drill
|
||||
name = "alien drill"
|
||||
desc = "A giant, alien drill mounted on long treads."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "gigadrill"
|
||||
var/active = 0
|
||||
var/drill_time = 10
|
||||
var/turf/drilling_turf
|
||||
density = 1
|
||||
layer = 3.1 //to go over ores
|
||||
|
||||
/obj/machinery/giga_drill/attack_hand(mob/user as mob)
|
||||
if(active)
|
||||
active = 0
|
||||
icon_state = "gigadrill"
|
||||
user << "\blue You press a button and [src] slowly spins down."
|
||||
else
|
||||
active = 1
|
||||
icon_state = "gigadrill_mov"
|
||||
user << "\blue You press a button and [src] shudders to life."
|
||||
|
||||
/obj/machinery/giga_drill/Bump(atom/A)
|
||||
if(active && !drilling_turf)
|
||||
if(istype(A,/turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/M = A
|
||||
drilling_turf = get_turf(src)
|
||||
src.visible_message("\red <b>[src] begins to drill into [M]!</b>")
|
||||
anchored = 1
|
||||
spawn(drill_time)
|
||||
if(get_turf(src) == drilling_turf && active)
|
||||
M.GetDrilled()
|
||||
src.loc = M
|
||||
drilling_turf = null
|
||||
anchored = 0
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
/obj/mecha/working/hoverpod
|
||||
name = "hover pod"
|
||||
icon_state = "engineering_pod"
|
||||
desc = "Stubby and round, it has a human sized access hatch on the top."
|
||||
wreckage = /obj/effect/decal/mecha_wreckage/hoverpod
|
||||
|
||||
//duplicate of parent proc, but without space drifting
|
||||
/obj/mecha/working/hoverpod/dyndomove(direction)
|
||||
if(!can_move)
|
||||
return 0
|
||||
if(src.pr_inertial_movement.active())
|
||||
return 0
|
||||
if(!has_charge(step_energy_drain))
|
||||
return 0
|
||||
var/move_result = 0
|
||||
if(hasInternalDamage(MECHA_INT_CONTROL_LOST))
|
||||
move_result = mechsteprand()
|
||||
else if(src.dir!=direction)
|
||||
move_result = mechturn(direction)
|
||||
else
|
||||
move_result = mechstep(direction)
|
||||
if(move_result)
|
||||
can_move = 0
|
||||
use_power(step_energy_drain)
|
||||
/*if(istype(src.loc, /turf/space))
|
||||
if(!src.check_for_support())
|
||||
src.pr_inertial_movement.start(list(src,direction))
|
||||
src.log_message("Movement control lost. Inertial movement started.")*/
|
||||
if(do_after(step_in))
|
||||
can_move = 1
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//these three procs overriden to play different sounds
|
||||
/obj/mecha/working/hoverpod/mechturn(direction)
|
||||
dir = direction
|
||||
//playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return 1
|
||||
|
||||
/obj/mecha/working/hoverpod/mechstep(direction)
|
||||
var/result = step(src,direction)
|
||||
if(result)
|
||||
playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return result
|
||||
|
||||
|
||||
/obj/mecha/working/hoverpod/mechsteprand()
|
||||
var/result = step_rand(src)
|
||||
if(result)
|
||||
playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return result
|
||||
|
||||
/obj/effect/decal/mecha_wreckage/hoverpod
|
||||
name = "Hover pod wreckage"
|
||||
icon_state = "engineering_pod-broken"
|
||||
|
||||
/*New()
|
||||
..()
|
||||
var/list/parts = list(
|
||||
|
||||
for(var/i=0;i<2;i++)
|
||||
if(!isemptylist(parts) && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
return*/
|
||||
@@ -0,0 +1,119 @@
|
||||
|
||||
/obj/machinery/replicator
|
||||
name = "alien machine"
|
||||
desc = "It's some kind of pod with strange wires and gadgets all over it."
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "borgcharger0(old)"
|
||||
density = 1
|
||||
|
||||
idle_power_usage = 100
|
||||
active_power_usage = 1000
|
||||
use_power = 1
|
||||
|
||||
var/spawn_progress = 0
|
||||
var/max_spawn_ticks = 5
|
||||
var/list/construction = list()
|
||||
var/list/spawning_types = list()
|
||||
|
||||
/obj/machinery/replicator/New()
|
||||
..()
|
||||
|
||||
var/list/viables = list(\
|
||||
/obj/item/roller,\
|
||||
/obj/structure/closet/crate,\
|
||||
/obj/structure/closet/acloset,\
|
||||
/mob/living/simple_animal/hostile/mimic,\
|
||||
/mob/living/simple_animal/hostile/viscerator,\
|
||||
/mob/living/simple_animal/hostile/hivebot,\
|
||||
/obj/item/device/analyzer,\
|
||||
/obj/item/device/camera,\
|
||||
/obj/item/device/flash,\
|
||||
/obj/item/device/flashlight,\
|
||||
/obj/item/device/healthanalyzer,\
|
||||
/obj/item/device/multitool,\
|
||||
/obj/item/device/paicard,\
|
||||
/obj/item/device/radio,\
|
||||
/obj/item/device/radio/headset,\
|
||||
/obj/item/device/radio/beacon,\
|
||||
/obj/item/weapon/autopsy_scanner,\
|
||||
/obj/item/weapon/bikehorn,\
|
||||
/obj/item/weapon/bonesetter,\
|
||||
/obj/item/weapon/butch,\
|
||||
/obj/item/weapon/caution,\
|
||||
/obj/item/weapon/caution/cone,\
|
||||
/obj/item/weapon/crowbar,\
|
||||
/obj/item/weapon/clipboard,\
|
||||
/obj/item/weapon/cell,\
|
||||
/obj/item/weapon/circular_saw,\
|
||||
/obj/item/weapon/hatchet,\
|
||||
/obj/item/weapon/handcuffs,\
|
||||
/obj/item/weapon/hemostat,\
|
||||
/obj/item/weapon/kitchenknife,\
|
||||
/obj/item/weapon/lighter,\
|
||||
/obj/item/weapon/lighter,\
|
||||
/obj/item/weapon/light/bulb,\
|
||||
/obj/item/weapon/light/tube,\
|
||||
/obj/item/weapon/pickaxe,\
|
||||
/obj/item/weapon/shovel,\
|
||||
/obj/item/weapon/table_parts,\
|
||||
/obj/item/weapon/weldingtool,\
|
||||
/obj/item/weapon/wirecutters,\
|
||||
/obj/item/weapon/wrench,\
|
||||
/obj/item/weapon/screwdriver,\
|
||||
/obj/item/weapon/grenade/chem_grenade/cleaner,\
|
||||
/obj/item/weapon/grenade/chem_grenade/metalfoam\
|
||||
)
|
||||
|
||||
var/quantity = rand(5,15)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/button_desc = "[pick("a yellow","a purple","a green","a blue","a red","an orange","a white")], "
|
||||
button_desc += "[pick("round","square","diamond","heart","dog","human")] shaped "
|
||||
button_desc += "[pick("toggle","switch","lever","button","pad","hole")]"
|
||||
var/type = pick(viables)
|
||||
viables.Remove(type)
|
||||
construction[button_desc] = type
|
||||
|
||||
/obj/machinery/replicator/process()
|
||||
if(spawning_types.len && powered())
|
||||
spawn_progress++
|
||||
if(spawn_progress > max_spawn_ticks)
|
||||
src.visible_message("\blue \icon[src] [src] pings!")
|
||||
var/spawn_type = spawning_types[1]
|
||||
new spawn_type(src.loc)
|
||||
|
||||
spawning_types.Remove(spawning_types[1])
|
||||
spawn_progress = 0
|
||||
max_spawn_ticks = rand(5,30)
|
||||
|
||||
if(!spawning_types.len)
|
||||
use_power = 1
|
||||
icon_state = "borgcharger0(old)"
|
||||
|
||||
else if(prob(5))
|
||||
src.visible_message("\blue \icon[src] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].")
|
||||
|
||||
/obj/machinery/replicator/attack_hand(mob/user as mob)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/replicator/interact(mob/user)
|
||||
var/dat = "The control panel displays an incomprehensible selection of controls, many with unusual markings or text around them.<br>"
|
||||
dat += "<br>"
|
||||
for(var/index=1, index<=construction.len, index++)
|
||||
dat += "<A href='?src=\ref[src];activate=[index]'>\[[construction[index]]\]</a><br>"
|
||||
|
||||
user << browse(dat, "window=alien_replicator")
|
||||
|
||||
/obj/machinery/replicator/Topic(href, href_list)
|
||||
|
||||
if(href_list["activate"])
|
||||
var/index = text2num(href_list["activate"])
|
||||
if(index > 0 && index <= construction.len)
|
||||
if(spawning_types.len)
|
||||
src.visible_message("\blue \icon[src] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].")
|
||||
else
|
||||
src.visible_message("\blue \icon[src] [src]'s front compartment slides shut.")
|
||||
|
||||
spawning_types.Add(construction[construction[index]])
|
||||
spawn_progress = 0
|
||||
use_power = 2
|
||||
icon_state = "borgcharger1(old)"
|
||||
@@ -0,0 +1,367 @@
|
||||
|
||||
#define EFFECT_TOUCH 0
|
||||
#define EFFECT_AURA 1
|
||||
#define EFFECT_PULSE 2
|
||||
#define MAX_EFFECT 2
|
||||
|
||||
#define TRIGGER_TOUCH 0
|
||||
#define TRIGGER_WATER 1
|
||||
#define TRIGGER_ACID 2
|
||||
#define TRIGGER_VOLATILE 3
|
||||
#define TRIGGER_TOXIN 4
|
||||
#define TRIGGER_FORCE 5
|
||||
#define TRIGGER_ENERGY 6
|
||||
#define TRIGGER_HEAT 7
|
||||
#define TRIGGER_COLD 8
|
||||
#define TRIGGER_PLASMA 9
|
||||
#define TRIGGER_OXY 10
|
||||
#define TRIGGER_CO2 11
|
||||
#define TRIGGER_NITRO 12
|
||||
#define MAX_TRIGGER 12
|
||||
/*
|
||||
//sleeping gas appears to be bugged, currently
|
||||
var/list/valid_primary_effect_types = list(\
|
||||
/datum/artifact_effect/cellcharge,\
|
||||
/datum/artifact_effect/celldrain,\
|
||||
/datum/artifact_effect/forcefield,\
|
||||
/datum/artifact_effect/gasoxy,\
|
||||
/datum/artifact_effect/gasplasma,\
|
||||
/* /datum/artifact_effect/gassleeping,\*/
|
||||
/datum/artifact_effect/heal,\
|
||||
/datum/artifact_effect/hurt,\
|
||||
/datum/artifact_effect/emp,\
|
||||
/datum/artifact_effect/teleport,\
|
||||
/datum/artifact_effect/robohurt,\
|
||||
/datum/artifact_effect/roboheal)
|
||||
|
||||
var/list/valid_secondary_effect_types = list(\
|
||||
/datum/artifact_effect/cold,\
|
||||
/datum/artifact_effect/badfeeling,\
|
||||
/datum/artifact_effect/cellcharge,\
|
||||
/datum/artifact_effect/celldrain,\
|
||||
/datum/artifact_effect/dnaswitch,\
|
||||
/datum/artifact_effect/emp,\
|
||||
/datum/artifact_effect/gasco2,\
|
||||
/datum/artifact_effect/gasnitro,\
|
||||
/datum/artifact_effect/gasoxy,\
|
||||
/datum/artifact_effect/gasplasma,\
|
||||
/* /datum/artifact_effect/gassleeping,\*/
|
||||
/datum/artifact_effect/goodfeeling,\
|
||||
/datum/artifact_effect/heal,\
|
||||
/datum/artifact_effect/hurt,\
|
||||
/datum/artifact_effect/radiate,\
|
||||
/datum/artifact_effect/roboheal,\
|
||||
/datum/artifact_effect/robohurt,\
|
||||
/datum/artifact_effect/sleepy,\
|
||||
/datum/artifact_effect/stun,\
|
||||
/datum/artifact_effect/teleport)
|
||||
*/
|
||||
|
||||
/obj/machinery/artifact
|
||||
name = "alien artifact"
|
||||
desc = "A large alien device."
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "ano00"
|
||||
var/icon_num = 0
|
||||
density = 1
|
||||
var/datum/artifact_effect/my_effect
|
||||
var/datum/artifact_effect/secondary_effect
|
||||
var/being_used = 0
|
||||
|
||||
/obj/machinery/artifact/New()
|
||||
..()
|
||||
|
||||
//setup primary effect - these are the main ones (mixed)
|
||||
var/effecttype = pick(typesof(/datum/artifact_effect) - /datum/artifact_effect)
|
||||
my_effect = new effecttype(src)
|
||||
|
||||
//75% chance to have a secondary stealthy (and mostly bad) effect
|
||||
if(prob(75))
|
||||
effecttype = pick(typesof(/datum/artifact_effect) - /datum/artifact_effect)
|
||||
secondary_effect = new effecttype(src)
|
||||
if(prob(75))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
icon_num = rand(0,11)
|
||||
icon_state = "ano[icon_num]0"
|
||||
if(icon_num == 7 || icon_num == 8)
|
||||
name = "large crystal"
|
||||
desc = pick("It shines faintly as it catches the light.",\
|
||||
"It appears to have a faint inner glow.",\
|
||||
"It seems to draw you inward as you look it at.",\
|
||||
"Something twinkles faintly as you look at it.",\
|
||||
"It's mesmerizing to behold.")
|
||||
if(prob(50))
|
||||
my_effect.trigger = TRIGGER_ENERGY
|
||||
else if(icon_num == 9)
|
||||
name = "alien computer"
|
||||
desc = "It is covered in strange markings."
|
||||
if(prob(75))
|
||||
my_effect.trigger = TRIGGER_TOUCH
|
||||
else if(icon_num == 10)
|
||||
desc = "A large alien device, there appear to be some kind of vents in the side."
|
||||
if(prob(50))
|
||||
my_effect.trigger = rand(6,12)
|
||||
else if(icon_num == 11)
|
||||
name = "sealed alien pod"
|
||||
desc = "A strange alien device."
|
||||
if(prob(25))
|
||||
my_effect.trigger = rand(1,4)
|
||||
|
||||
#define TRIGGER_PLASMA 9
|
||||
#define TRIGGER_OXY 10
|
||||
#define TRIGGER_CO2 11
|
||||
#define TRIGGER_NITRO 12
|
||||
|
||||
/obj/machinery/artifact/process()
|
||||
|
||||
var/turf/L = loc
|
||||
if(isnull(L) || !istype(L)) // We're inside a container or on null turf, either way stop processing effects
|
||||
return
|
||||
|
||||
if(my_effect)
|
||||
my_effect.process()
|
||||
if(secondary_effect)
|
||||
secondary_effect.process()
|
||||
|
||||
if(pulledby)
|
||||
Bumped(pulledby)
|
||||
|
||||
//if either of our effects rely on environmental factors, work that out
|
||||
var/trigger_cold = 0
|
||||
var/trigger_hot = 0
|
||||
var/trigger_plasma = 0
|
||||
var/trigger_oxy = 0
|
||||
var/trigger_co2 = 0
|
||||
var/trigger_nitro = 0
|
||||
if( (my_effect.trigger >= TRIGGER_HEAT && my_effect.trigger <= TRIGGER_NITRO) || (my_effect.trigger >= TRIGGER_HEAT && my_effect.trigger <= TRIGGER_NITRO) )
|
||||
var/turf/T = get_turf(src)
|
||||
var/datum/gas_mixture/env = T.return_air()
|
||||
if(env)
|
||||
if(env.temperature < 225)
|
||||
trigger_cold = 1
|
||||
else if(env.temperature > 375)
|
||||
trigger_hot = 1
|
||||
|
||||
if(env.toxins >= 10)
|
||||
trigger_plasma = 1
|
||||
if(env.oxygen >= 10)
|
||||
trigger_oxy = 1
|
||||
if(env.carbon_dioxide >= 10)
|
||||
trigger_co2 = 1
|
||||
if(env.nitrogen >= 10)
|
||||
trigger_nitro = 1
|
||||
|
||||
//COLD ACTIVATION
|
||||
if(trigger_cold)
|
||||
if(my_effect.trigger == TRIGGER_COLD && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_COLD && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_COLD && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_COLD && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//HEAT ACTIVATION
|
||||
if(trigger_hot)
|
||||
if(my_effect.trigger == TRIGGER_HEAT && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_HEAT && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_HEAT && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_HEAT && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//PLASMA GAS ACTIVATION
|
||||
if(trigger_plasma)
|
||||
if(my_effect.trigger == TRIGGER_PLASMA && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_PLASMA && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_PLASMA && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_PLASMA && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//OXYGEN GAS ACTIVATION
|
||||
if(trigger_oxy)
|
||||
if(my_effect.trigger == TRIGGER_OXY && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_OXY && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_OXY && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_OXY && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//CO2 GAS ACTIVATION
|
||||
if(trigger_co2)
|
||||
if(my_effect.trigger == TRIGGER_CO2 && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_CO2 && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_CO2 && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_CO2 && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//NITROGEN GAS ACTIVATION
|
||||
if(trigger_nitro)
|
||||
if(my_effect.trigger == TRIGGER_NITRO && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_NITRO && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_NITRO && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_NITRO && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
/obj/machinery/artifact/attack_hand(var/mob/user as mob)
|
||||
if (get_dist(user, src) > 1)
|
||||
user << "\red You can't reach [src] from here."
|
||||
return
|
||||
if(ishuman(user) && user:gloves)
|
||||
user << "<b>You touch [src]</b> with your gloved hands, [pick("but nothing of note happens","but nothing happens","but nothing interesting happens","but you notice nothing different","but nothing seems to have happened")]."
|
||||
return
|
||||
|
||||
src.add_fingerprint(user)
|
||||
|
||||
if(my_effect.trigger == TRIGGER_TOUCH)
|
||||
user << "<b>You touch [src].<b>"
|
||||
my_effect.ToggleActivate()
|
||||
else
|
||||
user << "<b>You touch [src],</b> [pick("but nothing of note happens","but nothing happens","but nothing interesting happens","but you notice nothing different","but nothing seems to have happened")]."
|
||||
|
||||
if(prob(25) && secondary_effect && secondary_effect.trigger == TRIGGER_TOUCH)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
if (my_effect.effect == EFFECT_TOUCH)
|
||||
my_effect.DoEffectTouch(user)
|
||||
|
||||
if(secondary_effect && secondary_effect.effect == EFFECT_TOUCH && secondary_effect.activated)
|
||||
secondary_effect.DoEffectTouch(user)
|
||||
|
||||
/obj/machinery/artifact/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
|
||||
if (istype(W, /obj/item/weapon/reagent_containers/))
|
||||
if(W.reagents.has_reagent("hydrogen", 1) || W.reagents.has_reagent("water", 1))
|
||||
if(my_effect.trigger == TRIGGER_WATER)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_WATER && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(W.reagents.has_reagent("acid", 1) || W.reagents.has_reagent("pacid", 1) || W.reagents.has_reagent("diethylamine", 1))
|
||||
if(my_effect.trigger == TRIGGER_ACID)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_ACID && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(W.reagents.has_reagent("plasma", 1) || W.reagents.has_reagent("thermite", 1))
|
||||
if(my_effect.trigger == TRIGGER_VOLATILE)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_VOLATILE && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(W.reagents.has_reagent("toxin", 1) || W.reagents.has_reagent("cyanide", 1) || W.reagents.has_reagent("amanitin", 1) || W.reagents.has_reagent("neurotoxin", 1))
|
||||
if(my_effect.trigger == TRIGGER_TOXIN)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_TOXIN && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(istype(W,/obj/item/weapon/melee/baton) && W:status ||\
|
||||
istype(W,/obj/item/weapon/melee/energy) ||\
|
||||
istype(W,/obj/item/weapon/melee/cultblade) ||\
|
||||
istype(W,/obj/item/weapon/card/emag) ||\
|
||||
istype(W,/obj/item/device/multitool))
|
||||
if (my_effect.trigger == TRIGGER_ENERGY)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_ENERGY && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
else if (istype(W,/obj/item/weapon/match) && W:lit ||\
|
||||
istype(W,/obj/item/weapon/weldingtool) && W:welding ||\
|
||||
istype(W,/obj/item/weapon/lighter) && W:lit)
|
||||
if(my_effect.trigger == TRIGGER_HEAT)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_HEAT && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
..()
|
||||
if (my_effect.trigger == TRIGGER_FORCE && W.force >= 10)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
/obj/machinery/artifact/Bumped(M as mob|obj)
|
||||
..()
|
||||
if(istype(M,/obj))
|
||||
if(M:throwforce >= 10)
|
||||
if(my_effect.trigger == TRIGGER_FORCE)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(ishuman(M) && !istype(M:gloves,/obj/item/clothing/gloves))
|
||||
var/warn = 0
|
||||
|
||||
if (my_effect.trigger == TRIGGER_TOUCH && prob(50))
|
||||
my_effect.ToggleActivate()
|
||||
warn = 1
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_TOUCH && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
warn = 1
|
||||
|
||||
if (my_effect.effect == EFFECT_TOUCH && prob(50))
|
||||
my_effect.DoEffectTouch(M)
|
||||
warn = 1
|
||||
if(secondary_effect && secondary_effect.effect == EFFECT_TOUCH && secondary_effect.activated && prob(50))
|
||||
secondary_effect.DoEffectTouch(M)
|
||||
warn = 1
|
||||
|
||||
if(warn)
|
||||
M << "<b>You accidentally touch [src].<b>"
|
||||
..()
|
||||
|
||||
/obj/machinery/artifact/bullet_act(var/obj/item/projectile/P)
|
||||
if(istype(P,/obj/item/projectile/bullet) ||\
|
||||
istype(P,/obj/item/projectile/hivebotbullet))
|
||||
if(my_effect.trigger == TRIGGER_FORCE)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
else if(istype(P,/obj/item/projectile/beam) ||\
|
||||
istype(P,/obj/item/projectile/ion) ||\
|
||||
istype(P,/obj/item/projectile/energy))
|
||||
if(my_effect.trigger == TRIGGER_ENERGY)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_ENERGY && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
/obj/machinery/artifact/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0) del src
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
del src
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_FORCE || my_effect.trigger == TRIGGER_HEAT)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && (secondary_effect.trigger == TRIGGER_FORCE || secondary_effect.trigger == TRIGGER_HEAT) && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
if(3.0)
|
||||
if (my_effect.trigger == TRIGGER_FORCE || my_effect.trigger == TRIGGER_HEAT)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && (secondary_effect.trigger == TRIGGER_FORCE || secondary_effect.trigger == TRIGGER_HEAT) && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
return
|
||||
|
||||
/obj/machinery/artifact/Move()
|
||||
..()
|
||||
if(my_effect)
|
||||
my_effect.UpdateMove()
|
||||
if(secondary_effect)
|
||||
secondary_effect.UpdateMove()
|
||||
@@ -0,0 +1,110 @@
|
||||
|
||||
//override procs in children as necessary
|
||||
/datum/artifact_effect
|
||||
var/effecttype = "unknown" //purely used for admin checks ingame, not needed any more
|
||||
var/effect = EFFECT_TOUCH
|
||||
var/effectrange = 4
|
||||
var/trigger = TRIGGER_TOUCH
|
||||
var/atom/holder
|
||||
var/activated = 0
|
||||
var/chargelevel = 0
|
||||
var/chargelevelmax = 10
|
||||
var/artifact_id = ""
|
||||
var/effect_type = 0
|
||||
|
||||
//0 = Unknown / none detectable
|
||||
//1 = Concentrated energy
|
||||
//2 = Intermittent psionic wavefront
|
||||
//3 = Electromagnetic energy
|
||||
//4 = Particle field
|
||||
//5 = Organically reactive exotic particles
|
||||
//6 = Interdimensional/bluespace? phasing
|
||||
//7 = Atomic synthesis
|
||||
|
||||
/datum/artifact_effect/New(var/atom/location)
|
||||
..()
|
||||
holder = location
|
||||
effect = rand(0,MAX_EFFECT)
|
||||
trigger = rand(0,MAX_TRIGGER)
|
||||
|
||||
//this will be replaced by the excavation code later, but it's here just in case
|
||||
artifact_id = "[pick("kappa","sigma","antaeres","beta","omicron","iota","epsilon","omega","gamma","delta","tau","alpha")]-[rand(100,999)]"
|
||||
|
||||
//random charge time and distance
|
||||
switch(pick(100;1, 50;2, 25;3))
|
||||
if(1)
|
||||
//short range, short charge time
|
||||
chargelevelmax = rand(3, 20)
|
||||
effectrange = rand(1, 3)
|
||||
if(2)
|
||||
//medium range, medium charge time
|
||||
chargelevelmax = rand(15, 40)
|
||||
effectrange = rand(5, 15)
|
||||
if(3)
|
||||
//large range, long charge time
|
||||
chargelevelmax = rand(20, 120)
|
||||
effectrange = rand(20, 200)
|
||||
|
||||
/datum/artifact_effect/proc/ToggleActivate(var/reveal_toggle = 1)
|
||||
//so that other stuff happens first
|
||||
spawn(0)
|
||||
if(activated)
|
||||
activated = 0
|
||||
else
|
||||
activated = 1
|
||||
if(reveal_toggle && holder)
|
||||
if(istype(holder, /obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/A = holder
|
||||
A.icon_state = "ano[A.icon_num][activated]"
|
||||
var/display_msg
|
||||
if(activated)
|
||||
display_msg = pick("momentarily glows brightly!","distorts slightly for a moment!","flickers slightly!","vibrates!","shimmers slightly for a moment!")
|
||||
else
|
||||
display_msg = pick("grows dull!","fades in intensity!","suddenly becomes very still!","suddenly becomes very quiet!")
|
||||
var/atom/toplevelholder = holder
|
||||
while(!istype(toplevelholder.loc, /turf))
|
||||
toplevelholder = toplevelholder.loc
|
||||
toplevelholder.visible_message("\red \icon[toplevelholder] [toplevelholder] [display_msg]")
|
||||
|
||||
/datum/artifact_effect/proc/DoEffectTouch(var/mob/user)
|
||||
/datum/artifact_effect/proc/DoEffectAura(var/atom/holder)
|
||||
/datum/artifact_effect/proc/DoEffectPulse(var/atom/holder)
|
||||
/datum/artifact_effect/proc/UpdateMove()
|
||||
|
||||
/datum/artifact_effect/proc/process()
|
||||
if(chargelevel < chargelevelmax)
|
||||
chargelevel++
|
||||
|
||||
if(activated)
|
||||
if(effect == EFFECT_AURA)
|
||||
DoEffectAura()
|
||||
else if(effect == EFFECT_PULSE && chargelevel >= chargelevelmax)
|
||||
chargelevel = 0
|
||||
DoEffectPulse()
|
||||
|
||||
//returns 0..1, with 1 being no protection and 0 being fully protected
|
||||
proc/GetAnomalySusceptibility(var/mob/living/carbon/human/H)
|
||||
if(!H || !istype(H))
|
||||
return 1
|
||||
|
||||
var/protected = 0
|
||||
|
||||
//anomaly suits give best protection, but excavation suits are almost as good
|
||||
if(istype(H.wear_suit,/obj/item/clothing/suit/bio_suit/anomaly))
|
||||
protected += 0.6
|
||||
else if(istype(H.wear_suit,/obj/item/clothing/suit/space/anomaly))
|
||||
protected += 0.5
|
||||
|
||||
if(istype(H.head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
protected += 0.3
|
||||
else if(istype(H.head,/obj/item/clothing/head/helmet/space/anomaly))
|
||||
protected += 0.2
|
||||
|
||||
//latex gloves and science goggles also give a bit of bonus protection
|
||||
if(istype(H.gloves,/obj/item/clothing/gloves/latex))
|
||||
protected += 0.1
|
||||
|
||||
if(istype(H.glasses,/obj/item/clothing/glasses/science))
|
||||
protected += 0.1
|
||||
|
||||
return 1 - protected
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
//inverse of /datum/artifact_effect/heat, the two effects split up for neatness' sake
|
||||
/datum/artifact_effect/cold
|
||||
effecttype = "cold"
|
||||
var/target_temp
|
||||
|
||||
/datum/artifact_effect/cold/New()
|
||||
..()
|
||||
target_temp = rand(0, 250)
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
effect_type = pick(5,6,7)
|
||||
|
||||
/datum/artifact_effect/cold/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.temperature = max(env.temperature - rand(5,50), 0)
|
||||
|
||||
/datum/artifact_effect/cold/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.temperature > target_temp)
|
||||
env.temperature -= pick(0, 0, 1)
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
/datum/artifact_effect/badfeeling
|
||||
effecttype = "badfeeling"
|
||||
effect_type = 2
|
||||
var/list/messages = list("You feel worried.",\
|
||||
"Something doesn't feel right.",\
|
||||
"You get a strange feeling in your gut.",\
|
||||
"Your instincts are trying to warn you about something.",\
|
||||
"Someone just walked over your grave.",\
|
||||
"There's a strange feeling in the air.",\
|
||||
"There's a strange smell in the air.",\
|
||||
"The tips of your fingers feel tingly.",\
|
||||
"You feel witchy.",\
|
||||
"You have a terrible sense of foreboding.",\
|
||||
"You've got a bad feeling about this.",\
|
||||
"Your scalp prickles.",\
|
||||
"The light seems to flicker.",\
|
||||
"The shadows seem to lengthen.",\
|
||||
"The walls are getting closer.",\
|
||||
"Something is wrong")
|
||||
|
||||
var/list/drastic_messages = list("You've got to get out of here!",\
|
||||
"Someone's trying to kill you!",\
|
||||
"There's something out there!",\
|
||||
"What's happening to you?",\
|
||||
"OH GOD!",\
|
||||
"HELP ME!")
|
||||
|
||||
/datum/artifact_effect/badfeeling/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if (istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(prob(50))
|
||||
if(prob(75))
|
||||
H << "<b><font color='red' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
else
|
||||
H << "<font color='red'>[pick(messages)]</font>"
|
||||
|
||||
if(prob(50))
|
||||
H.dizziness += rand(3,5)
|
||||
|
||||
/datum/artifact_effect/badfeeling/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
if(prob(5))
|
||||
if(prob(75))
|
||||
H << "<font color='red'>[pick(messages)]</font>"
|
||||
else
|
||||
H << "<font color='red' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
|
||||
if(prob(10))
|
||||
H.dizziness += rand(3,5)
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/badfeeling/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
if(prob(50))
|
||||
if(prob(95))
|
||||
H << "<font color='red' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
else
|
||||
H << "<font color='red'>[pick(messages)]</font>"
|
||||
|
||||
if(prob(50))
|
||||
H.dizziness += rand(3,5)
|
||||
else if(prob(25))
|
||||
H.dizziness += rand(5,15)
|
||||
return 1
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
//todo
|
||||
/datum/artifact_effect/cellcharge
|
||||
effecttype = "cellcharge"
|
||||
effect_type = 3
|
||||
|
||||
/datum/artifact_effect/cellcharge/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if(istype(user, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
for (var/obj/item/weapon/cell/D in R.contents)
|
||||
D.charge += rand() * 100 + 50
|
||||
R << "\blue SYSTEM ALERT: Large energy boost detected!"
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/cellcharge/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/obj/machinery/power/apc/C in range(200, holder))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge += 25
|
||||
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
|
||||
S.charge += 25
|
||||
for (var/mob/living/silicon/robot/M in mob_list)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge += 25
|
||||
M << "\blue SYSTEM ALERT: Energy boost detected!"
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/cellcharge/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/obj/machinery/power/apc/C in range(200, holder))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge += rand() * 100
|
||||
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
|
||||
S.charge += 250
|
||||
for (var/mob/living/silicon/robot/M in mob_list)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge += rand() * 100
|
||||
M << "\blue SYSTEM ALERT: Energy boost detected!"
|
||||
return 1
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
//todo
|
||||
/datum/artifact_effect/celldrain
|
||||
effecttype = "celldrain"
|
||||
effect_type = 3
|
||||
|
||||
/datum/artifact_effect/celldrain/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if(istype(user, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
for (var/obj/item/weapon/cell/D in R.contents)
|
||||
D.charge = max(D.charge - rand() * 100, 0)
|
||||
R << "\blue SYSTEM ALERT: Energy drain detected!"
|
||||
return 1
|
||||
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/celldrain/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/obj/machinery/power/apc/C in range(200, holder))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge = max(B.charge - 50,0)
|
||||
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
|
||||
S.charge = max(S.charge - 100,0)
|
||||
for (var/mob/living/silicon/robot/M in mob_list)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge = max(D.charge - 50,0)
|
||||
M << "\red SYSTEM ALERT: Energy drain detected!"
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/celldrain/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/obj/machinery/power/apc/C in range(200, holder))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge = max(B.charge - rand() * 150,0)
|
||||
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
|
||||
S.charge = max(S.charge - 250,0)
|
||||
for (var/mob/living/silicon/robot/M in mob_list)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge = max(D.charge - rand() * 150,0)
|
||||
M << "\red SYSTEM ALERT: Energy drain detected!"
|
||||
return 1
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
//todo
|
||||
/datum/artifact_effect/dnaswitch
|
||||
effecttype = "dnaswitch"
|
||||
effect_type = 5
|
||||
var/severity
|
||||
|
||||
/datum/artifact_effect/dnaswitch/New()
|
||||
..()
|
||||
if(effect == EFFECT_AURA)
|
||||
severity = rand(5,30)
|
||||
else
|
||||
severity = rand(25,95)
|
||||
|
||||
/datum/artifact_effect/dnaswitch/DoEffectTouch(var/mob/toucher)
|
||||
var/weakness = GetAnomalySusceptibility(toucher)
|
||||
if(ishuman(toucher) && prob(weakness * 100))
|
||||
toucher << pick("\green You feel a little different.",\
|
||||
"\green You feel very strange.",\
|
||||
"\green Your stomach churns.",\
|
||||
"\green Your skin feels loose.",\
|
||||
"\green You feel a stabbing pain in your head.",\
|
||||
"\green You feel a tingling sensation in your chest.",\
|
||||
"\green Your entire body vibrates.")
|
||||
if(prob(75))
|
||||
scramble(1, toucher, weakness * severity)
|
||||
else
|
||||
scramble(0, toucher, weakness * severity)
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/dnaswitch/DoEffectAura()
|
||||
if(holder)
|
||||
for(var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(H)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(30))
|
||||
H << pick("\green You feel a little different.",\
|
||||
"\green You feel very strange.",\
|
||||
"\green Your stomach churns.",\
|
||||
"\green Your skin feels loose.",\
|
||||
"\green You feel a stabbing pain in your head.",\
|
||||
"\green You feel a tingling sensation in your chest.",\
|
||||
"\green Your entire body vibrates.")
|
||||
if(prob(50))
|
||||
scramble(1, H, weakness * severity)
|
||||
else
|
||||
scramble(0, H, weakness * severity)
|
||||
|
||||
/datum/artifact_effect/dnaswitch/DoEffectPulse()
|
||||
if(holder)
|
||||
for(var/mob/living/carbon/human/H in range(200, holder))
|
||||
var/weakness = GetAnomalySusceptibility(H)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(75))
|
||||
H << pick("\green You feel a little different.",\
|
||||
"\green You feel very strange.",\
|
||||
"\green Your stomach churns.",\
|
||||
"\green Your skin feels loose.",\
|
||||
"\green You feel a stabbing pain in your head.",\
|
||||
"\green You feel a tingling sensation in your chest.",\
|
||||
"\green Your entire body vibrates.")
|
||||
if(prob(25))
|
||||
if(prob(75))
|
||||
scramble(1, H, weakness * severity)
|
||||
else
|
||||
scramble(0, H, weakness * severity)
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
/datum/artifact_effect/emp
|
||||
effecttype = "emp"
|
||||
effect_type = 3
|
||||
|
||||
/datum/artifact_effect/emp/New()
|
||||
..()
|
||||
effect = EFFECT_PULSE
|
||||
|
||||
/datum/artifact_effect/emp/DoEffectPulse()
|
||||
if(holder)
|
||||
empulse(get_turf(holder), effectrange/2, effectrange)
|
||||
return 1
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
/datum/artifact_effect/forcefield
|
||||
effecttype = "forcefield"
|
||||
var/list/created_field = list()
|
||||
effect_type = 4
|
||||
|
||||
/datum/artifact_effect/forcefield/New()
|
||||
..()
|
||||
trigger = TRIGGER_TOUCH
|
||||
|
||||
/datum/artifact_effect/forcefield/ToggleActivate()
|
||||
..()
|
||||
if(created_field.len)
|
||||
for(var/obj/effect/energy_field/F in created_field)
|
||||
created_field.Remove(F)
|
||||
del F
|
||||
else if(holder)
|
||||
var/turf/T = get_turf(holder)
|
||||
while(created_field.len < 16)
|
||||
var/obj/effect/energy_field/E = new (locate(T.x,T.y,T.z))
|
||||
created_field.Add(E)
|
||||
E.strength = 1
|
||||
E.density = 1
|
||||
E.anchored = 1
|
||||
E.invisibility = 0
|
||||
spawn(10)
|
||||
UpdateMove()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/forcefield/process()
|
||||
..()
|
||||
for(var/obj/effect/energy_field/E in created_field)
|
||||
if(E.strength < 1)
|
||||
E.Strengthen(0.15)
|
||||
else if(E.strength < 5)
|
||||
E.Strengthen(0.25)
|
||||
|
||||
/datum/artifact_effect/forcefield/UpdateMove()
|
||||
if(created_field.len && holder)
|
||||
var/turf/T = get_turf(holder)
|
||||
while(created_field.len < 16)
|
||||
//for now, just instantly respawn the fields when they get destroyed
|
||||
var/obj/effect/energy_field/E = new (locate(T.x,T.y,T))
|
||||
created_field.Add(E)
|
||||
E.anchored = 1
|
||||
E.density = 1
|
||||
E.invisibility = 0
|
||||
|
||||
var/obj/effect/energy_field/E = created_field[1]
|
||||
E.loc = locate(T.x + 2,T.y + 2,T.z)
|
||||
E = created_field[2]
|
||||
E.loc = locate(T.x + 2,T.y + 1,T.z)
|
||||
E = created_field[3]
|
||||
E.loc = locate(T.x + 2,T.y,T.z)
|
||||
E = created_field[4]
|
||||
E.loc = locate(T.x + 2,T.y - 1,T.z)
|
||||
E = created_field[5]
|
||||
E.loc = locate(T.x + 2,T.y - 2,T.z)
|
||||
E = created_field[6]
|
||||
E.loc = locate(T.x + 1,T.y + 2,T.z)
|
||||
E = created_field[7]
|
||||
E.loc = locate(T.x + 1,T.y - 2,T.z)
|
||||
E = created_field[8]
|
||||
E.loc = locate(T.x,T.y + 2,T.z)
|
||||
E = created_field[9]
|
||||
E.loc = locate(T.x,T.y - 2,T.z)
|
||||
E = created_field[10]
|
||||
E.loc = locate(T.x - 1,T.y + 2,T.z)
|
||||
E = created_field[11]
|
||||
E.loc = locate(T.x - 1,T.y - 2,T.z)
|
||||
E = created_field[12]
|
||||
E.loc = locate(T.x - 2,T.y + 2,T.z)
|
||||
E = created_field[13]
|
||||
E.loc = locate(T.x - 2,T.y + 1,T.z)
|
||||
E = created_field[14]
|
||||
E.loc = locate(T.x - 2,T.y,T.z)
|
||||
E = created_field[15]
|
||||
E.loc = locate(T.x - 2,T.y - 1,T.z)
|
||||
E = created_field[16]
|
||||
E.loc = locate(T.x - 2,T.y - 2,T.z)
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
/datum/artifact_effect/gasco2
|
||||
effecttype = "gasco2"
|
||||
var/max_pressure
|
||||
var/target_percentage
|
||||
|
||||
/datum/artifact_effect/heat/New()
|
||||
..()
|
||||
effect_type = pick(6,7)
|
||||
|
||||
/datum/artifact_effect/gasco2/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
max_pressure = rand(115,1000)
|
||||
|
||||
/datum/artifact_effect/gasco2/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.carbon_dioxide += rand(2,15)
|
||||
|
||||
/datum/artifact_effect/gasco2/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
env.carbon_dioxide += pick(0, 0, 0.1, rand())
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
/datum/artifact_effect/gasnitro
|
||||
effecttype = "gasnitro"
|
||||
var/max_pressure
|
||||
var/target_percentage
|
||||
|
||||
/datum/artifact_effect/gasnitro/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
effect_type = pick(6,7)
|
||||
max_pressure = rand(115,1000)
|
||||
|
||||
/datum/artifact_effect/gasnitro/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.nitrogen += rand(2,15)
|
||||
|
||||
/datum/artifact_effect/gasnitro/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
env.nitrogen += pick(0, 0, 0.1, rand())
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
/datum/artifact_effect/gasoxy
|
||||
effecttype = "gasoxy"
|
||||
var/max_pressure
|
||||
|
||||
/datum/artifact_effect/gasoxy/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
max_pressure = rand(115,1000)
|
||||
effect_type = pick(6,7)
|
||||
|
||||
|
||||
/datum/artifact_effect/gasoxy/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.oxygen += rand(2,15)
|
||||
|
||||
/datum/artifact_effect/gasoxy/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
env.oxygen += pick(0, 0, 0.1, rand())
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
/datum/artifact_effect/gasplasma
|
||||
effecttype = "gasplasma"
|
||||
var/max_pressure
|
||||
var/target_percentage
|
||||
|
||||
/datum/artifact_effect/gasplasma/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
max_pressure = rand(115,1000)
|
||||
effect_type = pick(6,7)
|
||||
|
||||
/datum/artifact_effect/gasplasma/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.toxins += rand(2,15)
|
||||
|
||||
/datum/artifact_effect/gasplasma/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
env.toxins += pick(0, 0, 0.1, rand())
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
/datum/artifact_effect/gassleeping
|
||||
effecttype = "gassleeping"
|
||||
var/max_pressure
|
||||
var/target_percentage
|
||||
|
||||
/datum/artifact_effect/gassleeping/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
max_pressure = rand(115,1000)
|
||||
effect_type = pick(6,7)
|
||||
|
||||
/datum/artifact_effect/gassleeping/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
var/datum/gas/sleeping_agent/trace_gas = new
|
||||
env.trace_gases += trace_gas
|
||||
trace_gas.moles = rand(2,15)
|
||||
env.update_values()
|
||||
|
||||
|
||||
/datum/artifact_effect/gassleeping/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
var/datum/gas/sleeping_agent/trace_gas = new
|
||||
env.trace_gases += trace_gas
|
||||
trace_gas.moles = pick(0, 0, 0.1, rand())
|
||||
env.update_values()
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
/datum/artifact_effect/goodfeeling
|
||||
effecttype = "goodfeeling"
|
||||
effect_type = 2
|
||||
var/list/messages = list("You feel good.",\
|
||||
"Everything seems to be going alright",\
|
||||
"You've got a good feeling about this",\
|
||||
"Your instincts tell you everything is going to be getting better.",\
|
||||
"There's a good feeling in the air.",\
|
||||
"Something smells... good.",\
|
||||
"The tips of your fingers feel tingly.",\
|
||||
"You've got a good feeling about this.",\
|
||||
"You feel happy.",\
|
||||
"You fight the urge to smile.",\
|
||||
"Your scalp prickles.",\
|
||||
"All the colours seem a bit more vibrant.",\
|
||||
"Everything seems a little lighter.",\
|
||||
"The troubles of the world seem to fade away.")
|
||||
|
||||
var/list/drastic_messages = list("You want to hug everyone you meet!",\
|
||||
"Everything is going so well!",\
|
||||
"You feel euphoric.",\
|
||||
"You feel giddy.",\
|
||||
"You're so happy suddenly, you almost want to dance and sing.",\
|
||||
"You feel like the world is out to help you.")
|
||||
|
||||
/datum/artifact_effect/goodfeeling/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if (istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(prob(50))
|
||||
if(prob(75))
|
||||
H << "<b><font color='blue' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
else
|
||||
H << "<font color='blue'>[pick(messages)]</font>"
|
||||
|
||||
if(prob(50))
|
||||
H.dizziness += rand(3,5)
|
||||
|
||||
/datum/artifact_effect/goodfeeling/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
if(prob(5))
|
||||
if(prob(75))
|
||||
H << "<font color='blue'>[pick(messages)]</font>"
|
||||
else
|
||||
H << "<font color='blue' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
|
||||
if(prob(5))
|
||||
H.dizziness += rand(3,5)
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/goodfeeling/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
if(prob(50))
|
||||
if(prob(95))
|
||||
H << "<font color='blue' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
else
|
||||
H << "<font color='blue'>[pick(messages)]</font>"
|
||||
|
||||
if(prob(50))
|
||||
H.dizziness += rand(3,5)
|
||||
else if(prob(25))
|
||||
H.dizziness += rand(5,15)
|
||||
return 1
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
/datum/artifact_effect/heal
|
||||
effecttype = "heal"
|
||||
effect_type = 5
|
||||
|
||||
/datum/artifact_effect/heal/DoEffectTouch(var/mob/toucher)
|
||||
//todo: check over this properly
|
||||
if(toucher && iscarbon(toucher))
|
||||
var/weakness = GetAnomalySusceptibility(toucher)
|
||||
if(prob(weakness * 100))
|
||||
var/mob/living/carbon/C = toucher
|
||||
C << "\blue You feel a soothing energy invigorate you."
|
||||
|
||||
if(ishuman(toucher))
|
||||
var/mob/living/carbon/human/H = toucher
|
||||
for(var/datum/organ/external/affecting in H.organs)
|
||||
if(affecting && istype(affecting))
|
||||
affecting.heal_damage(25 * weakness, 25 * weakness)
|
||||
//H:heal_organ_damage(25, 25)
|
||||
H.vessel.add_reagent("blood",5)
|
||||
H.nutrition += 50 * weakness
|
||||
H.adjustBrainLoss(-25 * weakness)
|
||||
H.radiation -= min(H.radiation, 25 * weakness)
|
||||
H.bodytemperature = initial(H.bodytemperature)
|
||||
spawn(1)
|
||||
H.fixblood()
|
||||
//
|
||||
C.adjustOxyLoss(-25 * weakness)
|
||||
C.adjustToxLoss(-25 * weakness)
|
||||
C.adjustBruteLoss(-25 * weakness)
|
||||
C.adjustFireLoss(-25 * weakness)
|
||||
//
|
||||
C.regenerate_icons()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/heal/DoEffectAura()
|
||||
//todo: check over this properly
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(10))
|
||||
C << "\blue You feel a soothing energy radiating from something nearby."
|
||||
C.adjustBruteLoss(-1 * weakness)
|
||||
C.adjustFireLoss(-1 * weakness)
|
||||
C.adjustToxLoss(-1 * weakness)
|
||||
C.adjustOxyLoss(-1 * weakness)
|
||||
C.adjustBrainLoss(-1 * weakness)
|
||||
C.updatehealth()
|
||||
|
||||
/datum/artifact_effect/heal/DoEffectPulse()
|
||||
//todo: check over this properly
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
C << "\blue A wave of energy invigorates you."
|
||||
C.adjustBruteLoss(-5 * weakness)
|
||||
C.adjustFireLoss(-5 * weakness)
|
||||
C.adjustToxLoss(-5 * weakness)
|
||||
C.adjustOxyLoss(-5 * weakness)
|
||||
C.adjustBrainLoss(-5 * weakness)
|
||||
C.updatehealth()
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
//inverse of /datum/artifact_effect/cold, the two effects split up for neatness' sake
|
||||
/datum/artifact_effect/heat
|
||||
effecttype = "heat"
|
||||
var/target_temp
|
||||
|
||||
/datum/artifact_effect/heat/New()
|
||||
..()
|
||||
effect_type = pick(5,6,7)
|
||||
|
||||
/datum/artifact_effect/heat/New()
|
||||
..()
|
||||
target_temp = rand(300,600)
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
|
||||
/datum/artifact_effect/heat/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.temperature += rand(5,50)
|
||||
|
||||
/datum/artifact_effect/heat/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.temperature < target_temp)
|
||||
env.temperature += pick(0, 0, 1)
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
/datum/artifact_effect/hurt
|
||||
effecttype = "hurt"
|
||||
effect_type = 5
|
||||
|
||||
/datum/artifact_effect/hurt/DoEffectTouch(var/mob/toucher)
|
||||
if(toucher)
|
||||
var/weakness = GetAnomalySusceptibility(toucher)
|
||||
if(iscarbon(toucher) && prob(weakness * 100))
|
||||
var/mob/living/carbon/C = toucher
|
||||
C << "\red A painful discharge of energy strikes you!"
|
||||
C.adjustOxyLoss(rand(5,25) * weakness)
|
||||
C.adjustToxLoss(rand(5,25) * weakness)
|
||||
C.adjustBruteLoss(rand(5,25) * weakness)
|
||||
C.adjustFireLoss(rand(5,25) * weakness)
|
||||
C.adjustBrainLoss(rand(5,25) * weakness)
|
||||
C.radiation += 25 * weakness
|
||||
C.nutrition -= min(50 * weakness, C.nutrition)
|
||||
C.make_dizzy(6 * weakness)
|
||||
C.weakened += 6 * weakness
|
||||
|
||||
/datum/artifact_effect/hurt/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(10))
|
||||
C << "\red You feel a painful force radiating from something nearby."
|
||||
C.adjustBruteLoss(1 * weakness)
|
||||
C.adjustFireLoss(1 * weakness)
|
||||
C.adjustToxLoss(1 * weakness)
|
||||
C.adjustOxyLoss(1 * weakness)
|
||||
C.adjustBrainLoss(1 * weakness)
|
||||
C.updatehealth()
|
||||
|
||||
/datum/artifact_effect/hurt/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(effectrange, holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
C << "\red A wave of painful energy strikes you!"
|
||||
C.adjustBruteLoss(3 * weakness)
|
||||
C.adjustFireLoss(3 * weakness)
|
||||
C.adjustToxLoss(3 * weakness)
|
||||
C.adjustOxyLoss(3 * weakness)
|
||||
C.adjustBrainLoss(3 * weakness)
|
||||
C.updatehealth()
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
/datum/artifact_effect/radiate
|
||||
effecttype = "radiate"
|
||||
var/radiation_amount
|
||||
|
||||
/datum/artifact_effect/radiate/New()
|
||||
..()
|
||||
radiation_amount = rand(1, 10)
|
||||
effect_type = pick(4,5)
|
||||
|
||||
/datum/artifact_effect/radiate/DoEffectTouch(var/mob/living/user)
|
||||
if(user)
|
||||
user.apply_effect(radiation_amount * 5,IRRADIATE,0)
|
||||
user.updatehealth()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/radiate/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/M in range(src.effectrange,holder))
|
||||
M.apply_effect(radiation_amount,IRRADIATE,0)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/radiate/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/M in range(src.effectrange,holder))
|
||||
M.apply_effect(radiation_amount * 25,IRRADIATE,0)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
/datum/artifact_effect/roboheal
|
||||
effecttype = "roboheal"
|
||||
|
||||
/datum/artifact_effect/roboheal/New()
|
||||
..()
|
||||
effect_type = pick(3,4)
|
||||
|
||||
/datum/artifact_effect/roboheal/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if (istype(user, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
R << "\blue Your systems report damaged components mending by themselves!"
|
||||
R.adjustBruteLoss(rand(-10,-30))
|
||||
R.adjustFireLoss(rand(-10,-30))
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/roboheal/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
|
||||
if(prob(10))
|
||||
M << "\blue SYSTEM ALERT: Beneficial energy field detected!"
|
||||
M.adjustBruteLoss(-1)
|
||||
M.adjustFireLoss(-1)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/roboheal/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
|
||||
M << "\blue SYSTEM ALERT: Structural damage has been repaired by energy pulse!"
|
||||
M.adjustBruteLoss(-10)
|
||||
M.adjustFireLoss(-10)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
/datum/artifact_effect/robohurt
|
||||
effecttype = "robohurt"
|
||||
|
||||
/datum/artifact_effect/robohurt/New()
|
||||
..()
|
||||
effect_type = pick(3,4)
|
||||
|
||||
/datum/artifact_effect/robohurt/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if (istype(user, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
R << "\red Your systems report severe damage has been inflicted!"
|
||||
R.adjustBruteLoss(rand(10,50))
|
||||
R.adjustFireLoss(rand(10,50))
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/robohurt/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
|
||||
if(prob(10)) M << "\red SYSTEM ALERT: Harmful energy field detected!"
|
||||
M.adjustBruteLoss(1)
|
||||
M.adjustFireLoss(1)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/robohurt/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
|
||||
M << "\red SYSTEM ALERT: Structural damage inflicted by energy pulse!"
|
||||
M.adjustBruteLoss(10)
|
||||
M.adjustFireLoss(10)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
//todo
|
||||
/datum/artifact_effect/sleepy
|
||||
effecttype = "sleepy"
|
||||
|
||||
/datum/artifact_effect/sleepy/New()
|
||||
..()
|
||||
effect_type = pick(5,2)
|
||||
|
||||
/datum/artifact_effect/sleepy/DoEffectTouch(var/mob/toucher)
|
||||
if(toucher)
|
||||
var/weakness = GetAnomalySusceptibility(toucher)
|
||||
if(ishuman(toucher) && prob(weakness * 100))
|
||||
var/mob/living/carbon/human/H = toucher
|
||||
H << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
|
||||
H.drowsyness = min(H.drowsyness + rand(5,25) * weakness, 50 * weakness)
|
||||
H.eye_blurry = min(H.eye_blurry + rand(1,3) * weakness, 50 * weakness)
|
||||
return 1
|
||||
else if(isrobot(toucher))
|
||||
toucher << "\red SYSTEM ALERT: CPU cycles slowing down."
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/sleepy/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(H)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(10))
|
||||
H << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
|
||||
H.drowsyness = min(H.drowsyness + 1 * weakness, 25 * weakness)
|
||||
H.eye_blurry = min(H.eye_blurry + 1 * weakness, 25 * weakness)
|
||||
for (var/mob/living/silicon/robot/R in range(src.effectrange,holder))
|
||||
R << "\red SYSTEM ALERT: CPU cycles slowing down."
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/sleepy/DoEffectPulse()
|
||||
if(holder)
|
||||
for(var/mob/living/carbon/human/H in range(src.effectrange, holder))
|
||||
var/weakness = GetAnomalySusceptibility(H)
|
||||
if(prob(weakness * 100))
|
||||
H << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
|
||||
H.drowsyness = min(H.drowsyness + rand(5,15) * weakness, 50 * weakness)
|
||||
H.eye_blurry = min(H.eye_blurry + rand(5,15) * weakness, 50 * weakness)
|
||||
for (var/mob/living/silicon/robot/R in range(src.effectrange,holder))
|
||||
R << "\red SYSTEM ALERT: CPU cycles slowing down."
|
||||
return 1
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
/datum/artifact_effect/stun
|
||||
effecttype = "stun"
|
||||
|
||||
/datum/artifact_effect/stun/New()
|
||||
..()
|
||||
effect_type = pick(2,5)
|
||||
|
||||
/datum/artifact_effect/stun/DoEffectTouch(var/mob/toucher)
|
||||
if(toucher && iscarbon(toucher))
|
||||
var/mob/living/carbon/C = toucher
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
C << "\red A powerful force overwhelms your consciousness."
|
||||
C.weakened += 45 * weakness
|
||||
C.stuttering += 45 * weakness
|
||||
C.stunned += rand(1,10) * weakness
|
||||
|
||||
/datum/artifact_effect/stun/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(10 * weakness))
|
||||
C << "\red Your body goes numb for a moment."
|
||||
C.weakened += 2
|
||||
C.stuttering += 2
|
||||
if(prob(10))
|
||||
C.stunned += 1
|
||||
else if(prob(10))
|
||||
C << "\red You feel numb."
|
||||
|
||||
/datum/artifact_effect/stun/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(100 * weakness))
|
||||
C << "\red A wave of energy overwhelms your senses!"
|
||||
C.weakened += 4 * weakness
|
||||
C.stuttering += 4 * weakness
|
||||
if(prob(10))
|
||||
C.stunned += 1 * weakness
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
/datum/artifact_effect/teleport
|
||||
effecttype = "teleport"
|
||||
effect_type = 6
|
||||
|
||||
/datum/artifact_effect/teleport/DoEffectTouch(var/mob/user)
|
||||
var/weakness = GetAnomalySusceptibility(user)
|
||||
if(prob(100 * weakness))
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/simulated/floor/T in orange(user, 50))
|
||||
randomturfs.Add(T)
|
||||
if(randomturfs.len > 0)
|
||||
user << "\red You are suddenly zapped away elsewhere!"
|
||||
if (user.buckled)
|
||||
user.buckled.unbuckle()
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(user))
|
||||
sparks.start()
|
||||
user.loc = pick(randomturfs)
|
||||
sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(user))
|
||||
sparks.start()
|
||||
|
||||
/datum/artifact_effect/teleport/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/M in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(M)
|
||||
if(prob(100 * weakness))
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/simulated/floor/T in orange(M, 30))
|
||||
randomturfs.Add(T)
|
||||
if(randomturfs.len > 0)
|
||||
M << "\red You are displaced by a strange force!"
|
||||
if(M.buckled)
|
||||
M.buckled.unbuckle()
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(M))
|
||||
sparks.start()
|
||||
M.loc = pick(randomturfs)
|
||||
sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(M))
|
||||
sparks.start()
|
||||
|
||||
/datum/artifact_effect/teleport/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/M in range(src.effectrange, holder))
|
||||
var/weakness = GetAnomalySusceptibility(M)
|
||||
if(prob(100 * weakness))
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/simulated/floor/T in orange(M, 15))
|
||||
randomturfs.Add(T)
|
||||
if(randomturfs.len > 0)
|
||||
M << "\red You are displaced by a strange force!"
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(M))
|
||||
sparks.start()
|
||||
if(M.buckled)
|
||||
M.buckled.unbuckle()
|
||||
M.loc = pick(randomturfs)
|
||||
sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(M))
|
||||
sparks.start()
|
||||
@@ -0,0 +1,160 @@
|
||||
|
||||
//chemistry stuff here so that it can be easily viewed/modified
|
||||
datum
|
||||
reagent
|
||||
tungsten
|
||||
name = "Tungsten"
|
||||
id = "tungsten"
|
||||
description = "A chemical element, and a strong oxidising agent."
|
||||
reagent_state = SOLID
|
||||
color = "#DCDCDC" // rgb: 220, 220, 220, silver
|
||||
|
||||
lithiumsodiumtungstate
|
||||
name = "Lithium Sodium Tungstate"
|
||||
id = "lithiumsodiumtungstate"
|
||||
description = "A reducing agent for geological compounds."
|
||||
reagent_state = LIQUID
|
||||
color = "#C0C0C0" // rgb: 192, 192, 192, darker silver
|
||||
|
||||
ground_rock
|
||||
name = "Ground Rock"
|
||||
id = "ground_rock"
|
||||
description = "A fine dust made of ground up rock."
|
||||
reagent_state = SOLID
|
||||
color = "#A0522D" //rgb: 160, 82, 45, brown
|
||||
|
||||
density_separated_sample
|
||||
name = "Density separated sample"
|
||||
id = "density_separated_sample"
|
||||
description = "A watery paste used in chemical analysis, there are some chunks floating in it."
|
||||
reagent_state = LIQUID
|
||||
color = "#DEB887" //rgb: 222, 184, 135, light brown
|
||||
|
||||
analysis_sample
|
||||
name = "Analysis liquid"
|
||||
id = "analysis_sample"
|
||||
description = "A watery paste used in chemical analysis."
|
||||
reagent_state = LIQUID
|
||||
color = "#F5FFFA" //rgb: 245, 255, 250, almost white
|
||||
|
||||
chemical_waste
|
||||
name = "Chemical Waste"
|
||||
id = "chemical_waste"
|
||||
description = "A viscous, toxic liquid left over from many chemical processes."
|
||||
reagent_state = LIQUID
|
||||
color = "#ADFF2F" //rgb: 173, 255, 47, toxic green
|
||||
|
||||
datum
|
||||
chemical_reaction
|
||||
lithiumsodiumtungstate //LiNa2WO4, not the easiest chem to mix
|
||||
name = "Lithium Sodium Tungstate"
|
||||
id = "lithiumsodiumtungstate"
|
||||
result = "lithiumsodiumtungstate"
|
||||
required_reagents = list("lithium" = 1, "sodium" = 2, "tungsten" = 1, "oxygen" = 4)
|
||||
result_amount = 8
|
||||
|
||||
density_separated_liquid
|
||||
name = "Density separated sample"
|
||||
id = "density_separated_sample"
|
||||
result = "density_separated_sample"
|
||||
secondary_results = list("chemical_waste" = 1)
|
||||
required_reagents = list("ground_rock" = 1, "lithiumsodiumtungstate" = 2)
|
||||
result_amount = 2
|
||||
|
||||
analysis_liquid
|
||||
name = "Analysis sample"
|
||||
id = "analysis_sample"
|
||||
result = "analysis_sample"
|
||||
secondary_results = list("chemical_waste" = 1)
|
||||
required_reagents = list("density_separated_sample" = 5)
|
||||
result_amount = 4
|
||||
requires_heating = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/solution_tray
|
||||
name = "solution tray"
|
||||
desc = "A small, open-topped glass container for delicate research samples. It sports a re-useable strip for labelling with a pen."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "solution_tray"
|
||||
m_amt = 0
|
||||
g_amt = 5
|
||||
w_class = 1.0
|
||||
amount_per_transfer_from_this = 1
|
||||
possible_transfer_amounts = list(1, 2)
|
||||
volume = 2
|
||||
flags = FPRINT | OPENCONTAINER
|
||||
|
||||
obj/item/weapon/reagent_containers/glass/solution_tray/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
var/new_label = input("What should the new label be?","Label solution tray")
|
||||
if(new_label)
|
||||
name = "solution tray ([new_label])"
|
||||
user << "\blue You write on the label of the solution tray."
|
||||
else
|
||||
..(W, user)
|
||||
|
||||
/obj/item/weapon/storage/box/solution_trays
|
||||
name = "solution tray box"
|
||||
icon_state = "solution_trays"
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/tungsten
|
||||
name = "beaker 'tungsten'"
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("tungsten",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/oxygen
|
||||
name = "beaker 'oxygen'"
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("oxygen",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/sodium
|
||||
name = "beaker 'sodium'"
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("sodium",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/lithium
|
||||
name = "beaker 'lithium'"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("lithium",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/water
|
||||
name = "beaker 'water'"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("water",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/water
|
||||
name = "beaker 'water'"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("water",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/fuel
|
||||
name = "beaker 'fuel'"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("fuel",50)
|
||||
update_icon()
|
||||
@@ -0,0 +1,538 @@
|
||||
//original code and idea from Alfie275 (luna era) and ISaidNo (goonservers) - with thanks
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Xenoarchaeological finds
|
||||
|
||||
/datum/find
|
||||
var/find_type = 0 //random according to the digsite type
|
||||
var/excavation_required = 0 //random 5-95%
|
||||
var/view_range = 20 //how close excavation has to come to show an overlay on the turf
|
||||
var/clearance_range = 3 //how close excavation has to come to extract the item
|
||||
//if excavation hits var/excavation_required exactly, it's contained find is extracted cleanly without the ore
|
||||
var/prob_delicate = 90 //probability it requires an active suspension field to not insta-crumble
|
||||
var/dissonance_spread = 1 //proportion of the tile that is affected by this find
|
||||
//used in conjunction with analysis machines to determine correct suspension field type
|
||||
|
||||
/datum/find/New(var/digsite, var/exc_req)
|
||||
excavation_required = exc_req
|
||||
find_type = get_random_find_type(digsite)
|
||||
clearance_range = rand(2,6)
|
||||
dissonance_spread = rand(1500,2500) / 100
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Strange rocks
|
||||
|
||||
//have all strange rocks be cleared away using welders for now
|
||||
/obj/item/weapon/ore/strangerock
|
||||
name = "Strange rock"
|
||||
desc = "Seems to have some unusal strata evident throughout it."
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "strange"
|
||||
var/obj/item/weapon/inside
|
||||
var/method = 0// 0 = fire, 1 = brush, 2 = pick
|
||||
origin_tech = "materials=5"
|
||||
|
||||
/obj/item/weapon/ore/strangerock/New(loc, var/inside_item_type = 0)
|
||||
..(loc)
|
||||
|
||||
//method = rand(0,2)
|
||||
if(inside_item_type)
|
||||
inside = new/obj/item/weapon/archaeological_find(src, new_item_type = inside_item_type)
|
||||
if(!inside)
|
||||
inside = locate() in contents
|
||||
|
||||
/*/obj/item/weapon/ore/strangerock/ex_act(var/severity)
|
||||
if(severity && prob(30))
|
||||
src.visible_message("The [src] crumbles away, leaving some dust and gravel behind.")*/
|
||||
|
||||
/obj/item/weapon/ore/strangerock/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/weldingtool/))
|
||||
var/obj/item/weapon/weldingtool/w = W
|
||||
if(w.isOn())
|
||||
if(w.get_fuel() >= 4 && !src.method)
|
||||
if(inside)
|
||||
inside.loc = get_turf(src)
|
||||
for(var/mob/M in viewers(world.view, user))
|
||||
M.show_message("<span class='info'>[src] burns away revealing [inside].</span>",1)
|
||||
else
|
||||
for(var/mob/M in viewers(world.view, user))
|
||||
M.show_message("<span class='info'>[src] burns away into nothing.</span>",1)
|
||||
del(src)
|
||||
w.remove_fuel(4)
|
||||
else
|
||||
for(var/mob/M in viewers(world.view, user))
|
||||
M.show_message("<span class='info'>A few sparks fly off [src], but nothing else happens.</span>",1)
|
||||
w.remove_fuel(1)
|
||||
return
|
||||
|
||||
else if(istype(W,/obj/item/device/core_sampler/))
|
||||
var/obj/item/device/core_sampler/S = W
|
||||
S.sample_item(src, user)
|
||||
return
|
||||
|
||||
..()
|
||||
if(prob(33))
|
||||
src.visible_message("<span class='warning'>[src] crumbles away, leaving some dust and gravel behind.</span>")
|
||||
del(src)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Archaeological finds
|
||||
|
||||
/obj/item/weapon/archaeological_find
|
||||
name = "object"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "ano01"
|
||||
var/find_type = 0
|
||||
|
||||
/obj/item/weapon/archaeological_find/New(loc, var/new_item_type)
|
||||
if(new_item_type)
|
||||
find_type = new_item_type
|
||||
else
|
||||
find_type = rand(1,34) //update this when you add new find types
|
||||
|
||||
var/item_type = "object"
|
||||
icon_state = "unknown[rand(1,4)]"
|
||||
var/additional_desc = ""
|
||||
var/obj/item/weapon/new_item
|
||||
var/source_material = ""
|
||||
var/apply_material_decorations = 1
|
||||
var/apply_image_decorations = 0
|
||||
var/material_descriptor = ""
|
||||
var/apply_prefix = 1
|
||||
if(prob(40))
|
||||
material_descriptor = pick("rusted ","dusty ","archaic ","fragile ")
|
||||
source_material = pick("cordite","quadrinium","steel","titanium","aluminium","ferritic-alloy","plasteel","duranium")
|
||||
|
||||
var/talkative = 0
|
||||
if(prob(5))
|
||||
talkative = 1
|
||||
|
||||
//for all items here:
|
||||
//icon_state
|
||||
//item_state
|
||||
switch(find_type)
|
||||
if(1)
|
||||
item_type = "bowl"
|
||||
new_item = new /obj/item/weapon/reagent_containers/glass(src.loc)
|
||||
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
new_item.icon_state = "bowl"
|
||||
apply_image_decorations = 1
|
||||
if(prob(20))
|
||||
additional_desc = "There appear to be [pick("dark","faintly glowing","pungent","bright")] [pick("red","purple","green","blue")] stains inside."
|
||||
if(2)
|
||||
item_type = "urn"
|
||||
new_item = new /obj/item/weapon/reagent_containers/glass(src.loc)
|
||||
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
new_item.icon_state = "urn"
|
||||
apply_image_decorations = 1
|
||||
if(prob(20))
|
||||
additional_desc = "It [pick("whispers faintly","makes a quiet roaring sound","whistles softly","thrums quietly","throbs")] if you put it to your ear."
|
||||
if(3)
|
||||
item_type = "[pick("fork","spoon","knife")]"
|
||||
if(prob(25))
|
||||
new_item = new /obj/item/weapon/kitchen/utensil/fork(src.loc)
|
||||
else if(prob(50))
|
||||
new_item = new /obj/item/weapon/kitchen/utensil/knife(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/kitchen/utensil/spoon(src.loc)
|
||||
additional_desc = "[pick("It's like no [item_type] you've ever seen before",\
|
||||
"It's a mystery how anyone is supposed to eat with this",\
|
||||
"You wonder what the creator's mouth was shaped like")]."
|
||||
if(4)
|
||||
item_type = "statuette"
|
||||
icon_state = "statuette"
|
||||
additional_desc = "It depicts a [pick("small","ferocious","wild","pleasing","hulking")] \
|
||||
[pick("alien figure","rodent-like creature","reptilian alien","primate","unidentifiable object")] \
|
||||
[pick("performing unspeakable acts","posing heroically","in a fetal position","cheering","sobbing","making a plaintive gesture","making a rude gesture")]."
|
||||
if(5)
|
||||
item_type = "instrument"
|
||||
icon_state = "instrument"
|
||||
if(prob(30))
|
||||
apply_image_decorations = 1
|
||||
additional_desc = "[pick("You're not sure how anyone could have played this",\
|
||||
"You wonder how many mouths the creator had",\
|
||||
"You wonder what it sounds like",\
|
||||
"You wonder what kind of music was made with it")]."
|
||||
if(6)
|
||||
item_type = "[pick("bladed knife","serrated blade","sharp cutting implement")]"
|
||||
new_item = new /obj/item/weapon/kitchenknife(src.loc)
|
||||
additional_desc = "[pick("It doesn't look safe.",\
|
||||
"It looks wickedly jagged",\
|
||||
"There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains along the edges")]."
|
||||
if(7)
|
||||
//assuming there are 10 types of coins
|
||||
var/chance = 10
|
||||
for(var/type in typesof(/obj/item/weapon/coin))
|
||||
if(prob(chance))
|
||||
new_item = new type(src.loc)
|
||||
break
|
||||
chance += 10
|
||||
|
||||
item_type = new_item.name
|
||||
apply_prefix = 0
|
||||
apply_material_decorations = 0
|
||||
apply_image_decorations = 1
|
||||
if(8)
|
||||
item_type = "handcuffs"
|
||||
new_item = new /obj/item/weapon/handcuffs(src.loc)
|
||||
additional_desc = "[pick("They appear to be for securing two things together","Looks kinky","Doesn't seem like a children's toy")]."
|
||||
if(9)
|
||||
item_type = "[pick("wicked","evil","byzantine","dangerous")] looking [pick("device","contraption","thing","trap")]"
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/weapon/legcuffs/beartrap(src.loc)
|
||||
additional_desc = "[pick("It looks like it could take a limb off",\
|
||||
"Could be some kind of animal trap",\
|
||||
"There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains along part of it")]."
|
||||
if(10)
|
||||
item_type = "[pick("cylinder","tank","chamber")]"
|
||||
new_item = new /obj/item/weapon/lighter(src.loc)
|
||||
additional_desc = "There is a tiny device attached."
|
||||
if(prob(30))
|
||||
apply_image_decorations = 1
|
||||
if(11)
|
||||
item_type = "box"
|
||||
new_item = new /obj/item/weapon/storage/box(src.loc)
|
||||
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
new_item.icon_state = "box"
|
||||
if(prob(30))
|
||||
apply_image_decorations = 1
|
||||
if(12)
|
||||
item_type = "[pick("cylinder","tank","chamber")]"
|
||||
if(prob(25))
|
||||
new_item = new /obj/item/weapon/tank/air(src.loc)
|
||||
else if(prob(50))
|
||||
new_item = new /obj/item/weapon/tank/anesthetic(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/tank/plasma(src.loc)
|
||||
icon_state = pick("oxygen","oxygen_fr","oxygen_f","plasma","anesthetic")
|
||||
additional_desc = "It [pick("gloops","sloshes")] slightly when you shake it."
|
||||
if(13)
|
||||
item_type = "tool"
|
||||
if(prob(25))
|
||||
new_item = new /obj/item/weapon/wrench(src.loc)
|
||||
else if(prob(25))
|
||||
new_item = new /obj/item/weapon/crowbar(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/screwdriver(src.loc)
|
||||
additional_desc = "[pick("It doesn't look safe.",\
|
||||
"You wonder what it was used for",\
|
||||
"There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains on it")]."
|
||||
if(14)
|
||||
apply_material_decorations = 0
|
||||
var/list/possible_spawns = list()
|
||||
possible_spawns += /obj/item/stack/sheet/metal
|
||||
possible_spawns += /obj/item/stack/sheet/plasteel
|
||||
possible_spawns += /obj/item/stack/sheet/glass
|
||||
possible_spawns += /obj/item/stack/sheet/rglass
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/plasma
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/mythril
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/gold
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/silver
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/enruranium
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/sandstone
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/silver
|
||||
|
||||
var/new_type = pick(possible_spawns)
|
||||
new_item = new new_type(src.loc)
|
||||
new_item:amount = rand(5,45)
|
||||
if(15)
|
||||
if(prob(75))
|
||||
new_item = new /obj/item/weapon/pen(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/pen/sleepypen(src.loc)
|
||||
if(prob(30))
|
||||
apply_image_decorations = 1
|
||||
if(16)
|
||||
apply_prefix = 0
|
||||
if(prob(25))
|
||||
item_type = "smooth green crystal"
|
||||
icon_state = "Green lump"
|
||||
else if(prob(33))
|
||||
item_type = "irregular purple crystal"
|
||||
icon_state = "Phazon"
|
||||
else if(prob(50))
|
||||
item_type = "rough red crystal"
|
||||
icon_state = "changerock"
|
||||
else
|
||||
item_type = "smooth red crystal"
|
||||
icon_state = "ore"
|
||||
additional_desc = pick("It shines faintly as it catches the light.","It appears to have a faint inner glow.","It seems to draw you inward as you look it at.","Something twinkles faintly as you look at it.","It's mesmerizing to behold.")
|
||||
|
||||
apply_material_decorations = 0
|
||||
if(prob(10))
|
||||
apply_image_decorations = 1
|
||||
if(17)
|
||||
//cultblade
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/weapon/melee/cultblade(src.loc)
|
||||
apply_material_decorations = 0
|
||||
apply_image_decorations = 0
|
||||
if(18)
|
||||
new_item = new /obj/item/device/radio/beacon(src.loc)
|
||||
talkative = 0
|
||||
new_item.icon_state = "unknown[rand(1,4)]"
|
||||
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
new_item.desc = ""
|
||||
if(19)
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/weapon/claymore(src.loc)
|
||||
new_item.force = 10
|
||||
item_type = new_item.name
|
||||
if(20)
|
||||
//arcane clothing
|
||||
apply_prefix = 0
|
||||
var/list/possible_spawns = list(/obj/item/clothing/head/culthood,
|
||||
/obj/item/clothing/head/magus,
|
||||
/obj/item/clothing/head/culthood/alt,
|
||||
/obj/item/clothing/head/helmet/space/cult)
|
||||
|
||||
var/new_type = pick(possible_spawns)
|
||||
new_item = new new_type(src.loc)
|
||||
if(21)
|
||||
//soulstone
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/device/soulstone(src.loc)
|
||||
item_type = new_item.name
|
||||
apply_material_decorations = 0
|
||||
if(22)
|
||||
if(prob(50))
|
||||
new_item = new /obj/item/weapon/shard(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/shard/plasma(src.loc)
|
||||
apply_prefix = 0
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(23)
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/stack/rods(src.loc)
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(24)
|
||||
var/list/possible_spawns = typesof(/obj/item/weapon/stock_parts)
|
||||
possible_spawns -= /obj/item/weapon/stock_parts
|
||||
possible_spawns -= /obj/item/weapon/stock_parts/subspace
|
||||
|
||||
var/new_type = pick(possible_spawns)
|
||||
new_item = new new_type(src.loc)
|
||||
item_type = new_item.name
|
||||
apply_material_decorations = 0
|
||||
if(25)
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/weapon/katana(src.loc)
|
||||
new_item.force = 10
|
||||
item_type = new_item.name
|
||||
if(26)
|
||||
//energy gun
|
||||
var/spawn_type = pick(\
|
||||
/obj/item/weapon/gun/energy/laser/practice,\
|
||||
/obj/item/weapon/gun/energy/laser,\
|
||||
/obj/item/weapon/gun/energy/xray,\
|
||||
/obj/item/weapon/gun/energy/laser/captain)
|
||||
if(spawn_type)
|
||||
var/obj/item/weapon/gun/energy/new_gun = new spawn_type(src.loc)
|
||||
new_item = new_gun
|
||||
new_item.icon_state = "egun[rand(1,6)]"
|
||||
new_gun.desc = "This is an antique energy weapon, you're not sure if it will fire or not."
|
||||
|
||||
//5% chance to explode when first fired
|
||||
//10% chance to have an unchargeable cell
|
||||
//15% chance to gain a random amount of starting energy, otherwise start with an empty cell
|
||||
if(prob(5))
|
||||
new_gun.power_supply.rigged = 1
|
||||
if(prob(10))
|
||||
new_gun.power_supply.maxcharge = 0
|
||||
if(prob(15))
|
||||
new_gun.power_supply.charge = rand(0, new_gun.power_supply.maxcharge)
|
||||
else
|
||||
new_gun.power_supply.charge = 0
|
||||
|
||||
item_type = "gun"
|
||||
if(27)
|
||||
//revolver
|
||||
var/obj/item/weapon/gun/projectile/new_gun = new /obj/item/weapon/gun/projectile(src.loc)
|
||||
new_item = new_gun
|
||||
new_item.icon_state = "gun[rand(1,4)]"
|
||||
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
|
||||
//33% chance to be able to reload the gun with human ammunition
|
||||
if(prob(66))
|
||||
new_gun.caliber = "999"
|
||||
|
||||
//33% chance to fill it with a random amount of bullets
|
||||
new_gun.max_shells = rand(1,12)
|
||||
if(prob(33))
|
||||
var/num_bullets = rand(1,new_gun.max_shells)
|
||||
if(num_bullets < new_gun.loaded.len)
|
||||
new_gun.loaded.Cut()
|
||||
for(var/i = 1, i <= num_bullets, i++)
|
||||
var/A = text2path(new_gun.ammo_type)
|
||||
new_gun.loaded += new A(new_gun)
|
||||
else
|
||||
for(var/obj/item/I in new_gun)
|
||||
if(new_gun.loaded.len > num_bullets)
|
||||
if(I in new_gun.loaded)
|
||||
new_gun.loaded.Remove(I)
|
||||
I.loc = null
|
||||
else
|
||||
break
|
||||
else
|
||||
for(var/obj/item/I in new_gun)
|
||||
if(I in new_gun.loaded)
|
||||
new_gun.loaded.Remove(I)
|
||||
I.loc = null
|
||||
|
||||
item_type = "gun"
|
||||
if(28)
|
||||
//completely unknown alien device
|
||||
if(prob(50))
|
||||
apply_image_decorations = 0
|
||||
if(29)
|
||||
//fossil bone/skull
|
||||
//new_item = new /obj/item/weapon/fossil/base(src.loc)
|
||||
|
||||
//the replacement item propogation isn't working, and it's messy code anyway so just do it here
|
||||
var/list/candidates = list("/obj/item/weapon/fossil/bone"=9,"/obj/item/weapon/fossil/skull"=3,
|
||||
"/obj/item/weapon/fossil/skull/horned"=2)
|
||||
var/spawn_type = pickweight(candidates)
|
||||
new_item = new spawn_type(src.loc)
|
||||
|
||||
apply_prefix = 0
|
||||
additional_desc = "A fossilised part of an alien, long dead."
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(30)
|
||||
//fossil shell
|
||||
new_item = new /obj/item/weapon/fossil/shell(src.loc)
|
||||
apply_prefix = 0
|
||||
additional_desc = "A fossilised, pre-Stygian alien crustacean."
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(prob(10))
|
||||
apply_image_decorations = 1
|
||||
if(31)
|
||||
//fossil plant
|
||||
new_item = new /obj/item/weapon/fossil/plant(src.loc)
|
||||
item_type = new_item.name
|
||||
additional_desc = "A fossilised shred of alien plant matter."
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
apply_prefix = 0
|
||||
if(32)
|
||||
//humanoid remains
|
||||
apply_prefix = 0
|
||||
item_type = "humanoid [pick("remains","skeleton")]"
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remains"
|
||||
additional_desc = pick("They appear almost human.",\
|
||||
"They are contorted in a most gruesome way.",\
|
||||
"They look almost peaceful.",\
|
||||
"The bones are yellowing and old, but remarkably well preserved.",\
|
||||
"The bones are scored by numerous burns and partially melted.",\
|
||||
"The are battered and broken, in some cases less than splinters are left.",\
|
||||
"The mouth is wide open in a death rictus, the victim would appear to have died screaming.")
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(33)
|
||||
//robot remains
|
||||
apply_prefix = 0
|
||||
item_type = "[pick("mechanical","robotic","cyborg")] [pick("remains","chassis","debris")]"
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remainsrobot"
|
||||
additional_desc = pick("Almost mistakeable for the remains of a modern cyborg.",\
|
||||
"They are barely recognisable as anything other than a pile of waste metals.",\
|
||||
"It looks like the battered remains of an ancient robot chassis.",\
|
||||
"The chassis is rusting and old, but remarkably well preserved.",\
|
||||
"The chassis is scored by numerous burns and partially melted.",\
|
||||
"The chassis is battered and broken, in some cases only chunks of metal are left.",\
|
||||
"A pile of wires and crap metal that looks vaguely robotic.")
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(34)
|
||||
//xenos remains
|
||||
apply_prefix = 0
|
||||
item_type = "alien [pick("remains","skeleton")]"
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remainsxeno"
|
||||
additional_desc = pick("It looks vaguely reptilian, but with more teeth.",\
|
||||
"They are faintly unsettling.",\
|
||||
"There is a faint aura of unease about them.",\
|
||||
"The bones are yellowing and old, but remarkably well preserved.",\
|
||||
"The bones are scored by numerous burns and partially melted.",\
|
||||
"The are battered and broken, in some cases less than splinters are left.",\
|
||||
"This creature would have been twisted and monstrous when it was alive.",\
|
||||
"It doesn't look human.")
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
|
||||
var/decorations = ""
|
||||
if(apply_material_decorations)
|
||||
source_material = pick("cordite","quadrinium","steel","titanium","aluminium","ferritic-alloy","plasteel","duranium")
|
||||
desc = "A [material_descriptor ? "[material_descriptor] " : ""][item_type] made of [source_material], all craftsmanship is of [pick("the lowest","low","average","high","the highest")] quality."
|
||||
|
||||
var/list/descriptors = list()
|
||||
if(prob(30))
|
||||
descriptors.Add("is encrusted with [pick("","synthetic ","multi-faceted ","uncut ","sparkling ") + pick("rubies","emeralds","diamonds","opals","lapiz lazuli")]")
|
||||
if(prob(30))
|
||||
descriptors.Add("is studded with [pick("gold","silver","aluminium","titanium")]")
|
||||
if(prob(30))
|
||||
descriptors.Add("is encircled with bands of [pick("quadrinium","cordite","ferritic-alloy","plasteel","duranium")]")
|
||||
if(prob(30))
|
||||
descriptors.Add("menaces with spikes of [pick("solid plasma","uranium","white pearl","black steel")]")
|
||||
if(descriptors.len > 0)
|
||||
decorations = "It "
|
||||
for(var/index=1, index <= descriptors.len, index++)
|
||||
if(index > 1)
|
||||
if(index == descriptors.len)
|
||||
decorations += " and "
|
||||
else
|
||||
decorations += ", "
|
||||
decorations += descriptors[index]
|
||||
decorations += "."
|
||||
if(decorations)
|
||||
desc += " " + decorations
|
||||
|
||||
var/engravings = ""
|
||||
if(apply_image_decorations)
|
||||
engravings = "[pick("Engraved","Carved","Etched")] on the item is [pick("an image of","a frieze of","a depiction of")] \
|
||||
[pick("an alien humanoid","an amorphic blob","a short, hairy being","a rodent-like creature","a robot","a primate","a reptilian alien","an unidentifiable object","a statue","a starship","unusual devices","a structure")] \
|
||||
[pick("surrounded by","being held aloft by","being struck by","being examined by","communicating with")] \
|
||||
[pick("alien humanoids","amorphic blobs","short, hairy beings","rodent-like creatures","robots","primates","reptilian aliens")]"
|
||||
if(prob(50))
|
||||
engravings += ", [pick("they seem to be enjoying themselves","they seem extremely angry","they look pensive","they are making gestures of supplication","the scene is one of subtle horror","the scene conveys a sense of desperation","the scene is completely bizarre")]"
|
||||
engravings += "."
|
||||
|
||||
if(desc)
|
||||
desc += " "
|
||||
desc += engravings
|
||||
|
||||
if(apply_prefix)
|
||||
name = "[pick("Strange","Ancient","Alien","")] [item_type]"
|
||||
else
|
||||
name = item_type
|
||||
|
||||
if(desc)
|
||||
desc += " "
|
||||
desc += additional_desc
|
||||
if(!desc)
|
||||
desc = "This item is completely [pick("alien","bizarre")]."
|
||||
|
||||
//icon and icon_state should have already been set
|
||||
if(new_item)
|
||||
new_item.name = name
|
||||
new_item.desc = src.desc
|
||||
|
||||
if(talkative && istype(new_item,/obj/item/weapon))
|
||||
new_item.listening_to_players = 1
|
||||
if(prob(25))
|
||||
new_item.speaking_to_players = 1
|
||||
processing_objects.Add(src)
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T, /turf/simulated/mineral))
|
||||
T:last_find = new_item
|
||||
del(src)
|
||||
|
||||
else if(talkative)
|
||||
listening_to_players = 1
|
||||
if(prob(25))
|
||||
speaking_to_players = 1
|
||||
processing_objects.Add(src)
|
||||
@@ -0,0 +1,271 @@
|
||||
|
||||
#define ARCHAEO_BOWL 1
|
||||
#define ARCHAEO_URN 2
|
||||
#define ARCHAEO_CUTLERY 3
|
||||
#define ARCHAEO_STATUETTE 4
|
||||
#define ARCHAEO_INSTRUMENT 5
|
||||
#define ARCHAEO_KNIFE 6
|
||||
#define ARCHAEO_COIN 7
|
||||
#define ARCHAEO_HANDCUFFS 8
|
||||
#define ARCHAEO_BEARTRAP 9
|
||||
#define ARCHAEO_LIGHTER 10
|
||||
#define ARCHAEO_BOX 11
|
||||
#define ARCHAEO_GASTANK 12
|
||||
#define ARCHAEO_TOOL 13
|
||||
#define ARCHAEO_METAL 14
|
||||
#define ARCHAEO_PEN 15
|
||||
#define ARCHAEO_CRYSTAL 16
|
||||
#define ARCHAEO_CULTBLADE 17
|
||||
#define ARCHAEO_TELEBEACON 18
|
||||
#define ARCHAEO_CLAYMORE 19
|
||||
#define ARCHAEO_CULTROBES 20
|
||||
#define ARCHAEO_SOULSTONE 21
|
||||
#define ARCHAEO_SHARD 22
|
||||
#define ARCHAEO_RODS 23
|
||||
#define ARCHAEO_STOCKPARTS 24
|
||||
#define ARCHAEO_KATANA 25
|
||||
#define ARCHAEO_LASER 26
|
||||
#define ARCHAEO_GUN 27
|
||||
#define ARCHAEO_UNKNOWN 28
|
||||
#define ARCHAEO_FOSSIL 29
|
||||
#define ARCHAEO_SHELL 30
|
||||
#define ARCHAEO_PLANT 31
|
||||
#define ARCHAEO_REMAINS_HUMANOID 32
|
||||
#define ARCHAEO_REMAINS_ROBOT 33
|
||||
#define ARCHAEO_REMAINS_XENO 34
|
||||
#define MAX_ARCHAEO 34
|
||||
//eggs
|
||||
//droppings
|
||||
//footprints
|
||||
//alien clothing
|
||||
|
||||
//DNA sampling from fossils, or a new archaeo type specifically for it?
|
||||
|
||||
//descending order of likeliness to spawn
|
||||
#define DIGSITE_GARDEN 1
|
||||
#define DIGSITE_ANIMAL 2
|
||||
#define DIGSITE_HOUSE 3
|
||||
#define DIGSITE_TECHNICAL 4
|
||||
#define DIGSITE_TEMPLE 5
|
||||
#define DIGSITE_WAR 6
|
||||
|
||||
/proc/get_responsive_reagent(var/find_type)
|
||||
switch(find_type)
|
||||
if(ARCHAEO_BOWL)
|
||||
return "mercury"
|
||||
if(ARCHAEO_URN)
|
||||
return "mercury"
|
||||
if(ARCHAEO_CUTLERY)
|
||||
return "mercury"
|
||||
if(ARCHAEO_STATUETTE)
|
||||
return "mercury"
|
||||
if(ARCHAEO_INSTRUMENT)
|
||||
return "mercury"
|
||||
if(ARCHAEO_COIN)
|
||||
return "iron"
|
||||
if(ARCHAEO_KNIFE)
|
||||
return "iron"
|
||||
if(ARCHAEO_HANDCUFFS)
|
||||
return "mercury"
|
||||
if(ARCHAEO_BEARTRAP)
|
||||
return "mercury"
|
||||
if(ARCHAEO_LIGHTER)
|
||||
return "mercury"
|
||||
if(ARCHAEO_BOX)
|
||||
return "mercury"
|
||||
if(ARCHAEO_GASTANK)
|
||||
return "mercury"
|
||||
if(ARCHAEO_TOOL)
|
||||
return "iron"
|
||||
if(ARCHAEO_METAL)
|
||||
return "iron"
|
||||
if(ARCHAEO_PEN)
|
||||
return "mercury"
|
||||
if(ARCHAEO_CRYSTAL)
|
||||
return "nitrogen"
|
||||
if(ARCHAEO_CULTBLADE)
|
||||
return "potassium"
|
||||
if(ARCHAEO_TELEBEACON)
|
||||
return "potassium"
|
||||
if(ARCHAEO_CLAYMORE)
|
||||
return "iron"
|
||||
if(ARCHAEO_CULTROBES)
|
||||
return "potassium"
|
||||
if(ARCHAEO_SOULSTONE)
|
||||
return "nitrogen"
|
||||
if(ARCHAEO_SHARD)
|
||||
return "nitrogen"
|
||||
if(ARCHAEO_RODS)
|
||||
return "iron"
|
||||
if(ARCHAEO_STOCKPARTS)
|
||||
return "potassium"
|
||||
if(ARCHAEO_KATANA)
|
||||
return "iron"
|
||||
if(ARCHAEO_LASER)
|
||||
return "iron"
|
||||
if(ARCHAEO_GUN)
|
||||
return "iron"
|
||||
if(ARCHAEO_UNKNOWN)
|
||||
return "mercury"
|
||||
if(ARCHAEO_FOSSIL)
|
||||
return "carbon"
|
||||
if(ARCHAEO_SHELL)
|
||||
return "carbon"
|
||||
if(ARCHAEO_PLANT)
|
||||
return "carbon"
|
||||
if(ARCHAEO_REMAINS_HUMANOID)
|
||||
return "carbon"
|
||||
if(ARCHAEO_REMAINS_ROBOT)
|
||||
return "carbon"
|
||||
if(ARCHAEO_REMAINS_XENO)
|
||||
return "carbon"
|
||||
return "plasma"
|
||||
|
||||
//see /turf/simulated/mineral/New() in code/modules/mining/mine_turfs.dm
|
||||
/proc/get_random_digsite_type()
|
||||
return pick(100;DIGSITE_GARDEN,95;DIGSITE_ANIMAL,90;DIGSITE_HOUSE,85;DIGSITE_TECHNICAL,80;DIGSITE_TEMPLE,75;DIGSITE_WAR)
|
||||
|
||||
/proc/get_random_find_type(var/digsite)
|
||||
|
||||
var/find_type = 0
|
||||
switch(digsite)
|
||||
if(DIGSITE_GARDEN)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_PLANT,\
|
||||
25;ARCHAEO_SHELL,\
|
||||
25;ARCHAEO_FOSSIL,\
|
||||
5;ARCHAEO_BEARTRAP\
|
||||
)
|
||||
if(DIGSITE_ANIMAL)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_FOSSIL,\
|
||||
50;ARCHAEO_SHELL,\
|
||||
50;ARCHAEO_PLANT,\
|
||||
25;ARCHAEO_BEARTRAP\
|
||||
)
|
||||
if(DIGSITE_HOUSE)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_BOWL,\
|
||||
100;ARCHAEO_URN,\
|
||||
100;ARCHAEO_CUTLERY,\
|
||||
100;ARCHAEO_STATUETTE,\
|
||||
100;ARCHAEO_INSTRUMENT,\
|
||||
100;ARCHAEO_PEN,\
|
||||
100;ARCHAEO_LIGHTER,\
|
||||
100;ARCHAEO_BOX,\
|
||||
75;ARCHAEO_COIN,\
|
||||
75;ARCHAEO_UNKNOWN,\
|
||||
50;ARCHAEO_SHARD,\
|
||||
50;ARCHAEO_RODS,\
|
||||
25;ARCHAEO_METAL\
|
||||
)
|
||||
if(DIGSITE_TECHNICAL)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_METAL,\
|
||||
100;ARCHAEO_GASTANK,\
|
||||
100;ARCHAEO_TELEBEACON,\
|
||||
100;ARCHAEO_TOOL,\
|
||||
100;ARCHAEO_STOCKPARTS,\
|
||||
75;ARCHAEO_SHARD,\
|
||||
75;ARCHAEO_RODS,\
|
||||
75;ARCHAEO_UNKNOWN,\
|
||||
50;ARCHAEO_HANDCUFFS,\
|
||||
50;ARCHAEO_BEARTRAP,\
|
||||
)
|
||||
if(DIGSITE_TEMPLE)
|
||||
find_type = pick(\
|
||||
200;ARCHAEO_CULTROBES,\
|
||||
100;ARCHAEO_URN,\
|
||||
100;ARCHAEO_BOWL,\
|
||||
100;ARCHAEO_KNIFE,\
|
||||
100;ARCHAEO_CRYSTAL,\
|
||||
75;ARCHAEO_CULTBLADE,\
|
||||
50;ARCHAEO_SOULSTONE,\
|
||||
50;ARCHAEO_UNKNOWN,\
|
||||
25;ARCHAEO_HANDCUFFS,\
|
||||
25;ARCHAEO_BEARTRAP,\
|
||||
10;ARCHAEO_KATANA,\
|
||||
10;ARCHAEO_CLAYMORE,\
|
||||
10;ARCHAEO_SHARD,\
|
||||
10;ARCHAEO_RODS,\
|
||||
10;ARCHAEO_METAL\
|
||||
)
|
||||
if(DIGSITE_WAR)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_GUN,\
|
||||
100;ARCHAEO_KNIFE,\
|
||||
75;ARCHAEO_LASER,\
|
||||
75;ARCHAEO_KATANA,\
|
||||
75;ARCHAEO_CLAYMORE,\
|
||||
50;ARCHAEO_UNKNOWN,\
|
||||
50;ARCHAEO_CULTROBES,\
|
||||
50;ARCHAEO_CULTBLADE,\
|
||||
25;ARCHAEO_HANDCUFFS,\
|
||||
25;ARCHAEO_BEARTRAP,\
|
||||
25;ARCHAEO_TOOL\
|
||||
)
|
||||
return find_type
|
||||
|
||||
var/list/responsive_carriers = list( \
|
||||
"carbon", \
|
||||
"potassium", \
|
||||
"hydrogen", \
|
||||
"nitrogen", \
|
||||
"mercury", \
|
||||
"iron", \
|
||||
"chlorine", \
|
||||
"phosphorus", \
|
||||
"plasma")
|
||||
|
||||
var/list/finds_as_strings = list( \
|
||||
"Trace organic cells", \
|
||||
"Long exposure particles", \
|
||||
"Trace water particles", \
|
||||
"Crystalline structures", \
|
||||
"Metallic derivative", \
|
||||
"Metallic composite", \
|
||||
"Metamorphic/igneous rock composite", \
|
||||
"Metamorphic/sedimentary rock composite", \
|
||||
"Anomalous material" )
|
||||
|
||||
#undef ARCHAEO_BOWL
|
||||
#undef ARCHAEO_URN
|
||||
#undef ARCHAEO_CUTLERY
|
||||
#undef ARCHAEO_STATUETTE
|
||||
#undef ARCHAEO_INSTRUMENT
|
||||
#undef ARCHAEO_KNIFE
|
||||
#undef ARCHAEO_COIN
|
||||
#undef ARCHAEO_HANDCUFFS
|
||||
#undef ARCHAEO_BEARTRAP
|
||||
#undef ARCHAEO_LIGHTER
|
||||
#undef ARCHAEO_BOX
|
||||
#undef ARCHAEO_GASTANK
|
||||
#undef ARCHAEO_TOOL
|
||||
#undef ARCHAEO_METAL
|
||||
#undef ARCHAEO_PEN
|
||||
#undef ARCHAEO_CRYSTAL
|
||||
#undef ARCHAEO_CULTBLADE
|
||||
#undef ARCHAEO_TELEBEACON
|
||||
#undef ARCHAEO_CLAYMORE
|
||||
#undef ARCHAEO_CULTROBES
|
||||
#undef ARCHAEO_SOULSTONE
|
||||
#undef ARCHAEO_SHARD
|
||||
#undef ARCHAEO_RODS
|
||||
#undef ARCHAEO_STOCKPARTS
|
||||
#undef ARCHAEO_KATANA
|
||||
#undef ARCHAEO_LASER
|
||||
#undef ARCHAEO_GUN
|
||||
#undef ARCHAEO_UNKNOWN
|
||||
#undef ARCHAEO_FOSSIL
|
||||
#undef ARCHAEO_SHELL
|
||||
#undef ARCHAEO_PLANT
|
||||
#undef ARCHAEO_REMAINS_HUMANOID
|
||||
#undef ARCHAEO_REMAINS_ROBOT
|
||||
#undef ARCHAEO_REMAINS_XENO
|
||||
|
||||
#undef DIGSITE_GARDEN
|
||||
#undef DIGSITE_ANIMAL
|
||||
#undef DIGSITE_HOUSE
|
||||
#undef DIGSITE_TECHNICAL
|
||||
#undef DIGSITE_TEMPLE
|
||||
#undef DIGSITE_WAR
|
||||
@@ -0,0 +1,102 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// fossils
|
||||
|
||||
/obj/item/weapon/fossil
|
||||
name = "Fossil"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "bone"
|
||||
desc = "It's a fossil."
|
||||
|
||||
/obj/item/weapon/fossil/base/New()
|
||||
var/list/l = list("/obj/item/weapon/fossil/bone"=9,"/obj/item/weapon/fossil/skull"=3,
|
||||
"/obj/item/weapon/fossil/skull/horned"=2)
|
||||
var/t = pickweight(l)
|
||||
var/obj/item/weapon/W = new t(src.loc)
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T, /turf/simulated/mineral))
|
||||
T:last_find = W
|
||||
del src
|
||||
|
||||
/obj/item/weapon/fossil/bone
|
||||
name = "Fossilised bone"
|
||||
icon_state = "bone"
|
||||
desc = "It's a fossilised bone."
|
||||
|
||||
/obj/item/weapon/fossil/skull
|
||||
name = "Fossilised skull"
|
||||
icon_state = "skull"
|
||||
desc = "It's a fossilised skull."
|
||||
|
||||
/obj/item/weapon/fossil/skull/horned
|
||||
icon_state = "hskull"
|
||||
desc = "It's a fossilised, horned skull."
|
||||
|
||||
/obj/item/weapon/fossil/skull/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/fossil/bone))
|
||||
var/obj/o = new /obj/skeleton(get_turf(src))
|
||||
var/a = new /obj/item/weapon/fossil/bone
|
||||
var/b = new src.type
|
||||
o.contents.Add(a)
|
||||
o.contents.Add(b)
|
||||
del W
|
||||
del src
|
||||
|
||||
/obj/skeleton
|
||||
name = "Incomplete skeleton"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "uskel"
|
||||
desc = "Incomplete skeleton."
|
||||
var/bnum = 1
|
||||
var/breq
|
||||
var/bstate = 0
|
||||
var/plaque_contents = "Unnamed alien creature"
|
||||
|
||||
/obj/skeleton/New()
|
||||
src.breq = rand(6)+3
|
||||
src.desc = "An incomplete skeleton, looks like it could use [src.breq-src.bnum] more bones."
|
||||
|
||||
/obj/skeleton/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/fossil/bone))
|
||||
if(!bstate)
|
||||
bnum++
|
||||
src.contents.Add(new/obj/item/weapon/fossil/bone)
|
||||
del W
|
||||
if(bnum==breq)
|
||||
usr = user
|
||||
icon_state = "skel"
|
||||
src.bstate = 1
|
||||
src.density = 1
|
||||
src.name = "alien skeleton display"
|
||||
if(src.contents.Find(/obj/item/weapon/fossil/skull/horned))
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a horned skull. The plaque reads \'[plaque_contents]\'."
|
||||
else
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a skull. The plaque reads \'[plaque_contents]\'."
|
||||
else
|
||||
src.desc = "Incomplete skeleton, looks like it could use [src.breq-src.bnum] more bones."
|
||||
user << "Looks like it could use [src.breq-src.bnum] more bones."
|
||||
else
|
||||
..()
|
||||
else if(istype(W,/obj/item/weapon/pen))
|
||||
plaque_contents = input("What would you like to write on the plaque:","Skeleton plaque","")
|
||||
user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of \icon[src] [src].")
|
||||
if(src.contents.Find(/obj/item/weapon/fossil/skull/horned))
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a horned skull. The plaque reads \'[plaque_contents]\'."
|
||||
else
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a skull. The plaque reads \'[plaque_contents]\'."
|
||||
else
|
||||
..()
|
||||
|
||||
//shells and plants do not make skeletons
|
||||
/obj/item/weapon/fossil/shell
|
||||
name = "Fossilised shell"
|
||||
icon_state = "shell"
|
||||
desc = "It's a fossilised shell."
|
||||
|
||||
/obj/item/weapon/fossil/plant
|
||||
name = "Fossilised plant"
|
||||
icon_state = "plant1"
|
||||
desc = "It's fossilised plant remains."
|
||||
|
||||
/obj/item/weapon/fossil/plant/New()
|
||||
icon_state = "plant[rand(1,4)]"
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
/obj/item/weapon/shard/plasma
|
||||
name = "plasma shard"
|
||||
desc = "A shard of plasma glass. Considerably tougher then normal glass shards. Apparently not tough enough to be a window."
|
||||
force = 8.0
|
||||
throwforce = 15.0
|
||||
icon_state = "plasmalarge"
|
||||
/obj/item/weapon/shard/plasma/New()
|
||||
|
||||
src.icon_state = pick("plasmalarge", "plasmamedium", "plasmasmall")
|
||||
switch(src.icon_state)
|
||||
if("plasmasmall")
|
||||
src.pixel_x = rand(-12, 12)
|
||||
src.pixel_y = rand(-12, 12)
|
||||
if("plasmamedium")
|
||||
src.pixel_x = rand(-8, 8)
|
||||
src.pixel_y = rand(-8, 8)
|
||||
if("plasmalarge")
|
||||
src.pixel_x = rand(-5, 5)
|
||||
src.pixel_y = rand(-5, 5)
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/weapon/shard/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
if ( istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0, user))
|
||||
var/obj/item/stack/sheet/glass/plasmaglass/NG = new (user.loc)
|
||||
for (var/obj/item/stack/sheet/glass/plasmaglass/G in user.loc)
|
||||
if(G==NG)
|
||||
continue
|
||||
if(G.amount>=G.max_amount)
|
||||
continue
|
||||
G.attackby(NG, user)
|
||||
usr << "You add the newly-formed plasma glass to the stack. It now contains [NG.amount] sheets."
|
||||
//SN src = null
|
||||
del(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
//legacy crystal
|
||||
/obj/machinery/crystal
|
||||
name = "Crystal"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "crystal"
|
||||
|
||||
/obj/machinery/crystal/New()
|
||||
if(prob(50))
|
||||
icon_state = "crystal2"
|
||||
|
||||
//large finds
|
||||
/*
|
||||
/obj/machinery/syndicate_beacon
|
||||
/obj/machinery/wish_granter
|
||||
if(18)
|
||||
item_type = "jagged green crystal"
|
||||
additional_desc = pick("It shines faintly as it catches the light.","It appears to have a faint inner glow.","It seems to draw you inward as you look it at.","Something twinkles faintly as you look at it.","It's mesmerizing to behold.")
|
||||
icon_state = "crystal"
|
||||
apply_material_decorations = 0
|
||||
if(prob(10))
|
||||
apply_image_decorations = 1
|
||||
if(19)
|
||||
item_type = "jagged pink crystal"
|
||||
additional_desc = pick("It shines faintly as it catches the light.","It appears to have a faint inner glow.","It seems to draw you inward as you look it at.","Something twinkles faintly as you look at it.","It's mesmerizing to behold.")
|
||||
icon_state = "crystal2"
|
||||
apply_material_decorations = 0
|
||||
if(prob(10))
|
||||
apply_image_decorations = 1
|
||||
*/
|
||||
//machinery type artifacts?
|
||||
@@ -0,0 +1,109 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Formerly talking crystals - these procs are now modular so that you can make any /obj/item/weapon 'parrot' player speech back to them
|
||||
// This could be extended to atoms, but it's bad enough as is
|
||||
// I genuinely tried to Add and Remove them from var and proc lists, but just couldn't get it working
|
||||
|
||||
/obj/item/weapon
|
||||
var/list/heard_words = list()
|
||||
var/lastsaid
|
||||
var/listening_to_players = 0
|
||||
var/speaking_to_players = 0
|
||||
|
||||
/obj/item/weapon/process()
|
||||
if(!speaking_to_players)
|
||||
processing_objects.Remove(src)
|
||||
return
|
||||
if(prob(10) && world.timeofday >= lastsaid && heard_words.len >= 1)
|
||||
SaySomething()
|
||||
|
||||
/obj/item/weapon/proc/catchMessage(var/msg, var/mob/source)
|
||||
if(speaking_to_players)
|
||||
var/list/seperate = list()
|
||||
if(findtext(msg,"(("))
|
||||
return
|
||||
else if(findtext(msg,"))"))
|
||||
return
|
||||
else if(findtext(msg," ")==0)
|
||||
return
|
||||
else
|
||||
/*var/l = lentext(msg)
|
||||
if(findtext(msg," ",l,l+1)==0)
|
||||
msg+=" "*/
|
||||
seperate = text2list(msg, " ")
|
||||
|
||||
for(var/Xa = 1,Xa<seperate.len,Xa++)
|
||||
var/next = Xa + 1
|
||||
if(heard_words.len > 20 + rand(10,20))
|
||||
heard_words.Remove(heard_words[1])
|
||||
if(!heard_words["[lowertext(seperate[Xa])]"])
|
||||
heard_words["[lowertext(seperate[Xa])]"] = list()
|
||||
var/list/w = heard_words["[lowertext(seperate[Xa])]"]
|
||||
if(w)
|
||||
w.Add("[lowertext(seperate[next])]")
|
||||
//world << "Adding [lowertext(seperate[next])] to [lowertext(seperate[Xa])]"
|
||||
|
||||
if(!rand(0, 5))
|
||||
spawn(2) SaySomething(pick(seperate))
|
||||
if(prob(30))
|
||||
for(var/mob/O in viewers(src))
|
||||
O.show_message("\blue [src] hums for bit then stops...", 1)
|
||||
|
||||
/*/obj/item/weapon/talkingcrystal/proc/debug()
|
||||
//set src in view()
|
||||
for(var/v in heard_words)
|
||||
world << "[uppertext(v)]"
|
||||
var/list/d = heard_words["[v]"]
|
||||
for(var/X in d)
|
||||
world << "[X]"*/
|
||||
|
||||
/obj/item/weapon/proc/SaySomething(var/word = null)
|
||||
|
||||
var/msg
|
||||
var/limit = rand(max(5,heard_words.len/2))+3
|
||||
var/text
|
||||
if(!word)
|
||||
text = "[pick(heard_words)]"
|
||||
else
|
||||
text = pick(text2list(word, " "))
|
||||
if(lentext(text)==1)
|
||||
text=uppertext(text)
|
||||
else
|
||||
var/cap = copytext(text,1,2)
|
||||
cap = uppertext(cap)
|
||||
cap += copytext(text,2,lentext(text)+1)
|
||||
text=cap
|
||||
var/q = 0
|
||||
msg+=text
|
||||
if(msg=="What" | msg == "Who" | msg == "How" | msg == "Why" | msg == "Are")
|
||||
q=1
|
||||
|
||||
text=lowertext(text)
|
||||
for(var/ya,ya <= limit,ya++)
|
||||
|
||||
if(heard_words.Find("[text]"))
|
||||
var/list/w = heard_words["[text]"]
|
||||
text=pick(w)
|
||||
else
|
||||
text = "[pick(heard_words)]"
|
||||
msg+=" [text]"
|
||||
if(q)
|
||||
msg+="?"
|
||||
else
|
||||
if(rand(0,10))
|
||||
msg+="."
|
||||
else
|
||||
msg+="!"
|
||||
|
||||
var/list/listening = viewers(src)
|
||||
for(var/mob/M in mob_list)
|
||||
if (!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
if (istype(M, /mob/new_player))
|
||||
continue
|
||||
if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
|
||||
listening|=M
|
||||
|
||||
for(var/mob/M in listening)
|
||||
M << "<b>[src]</b> reverberates, \blue\"[msg]\""
|
||||
lastsaid = world.timeofday + rand(300,800)
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
#define FIND_PLANT 1
|
||||
#define FIND_BIO 2
|
||||
#define FIND_METEORIC 3
|
||||
#define FIND_ICE 4
|
||||
#define FIND_CRYSTALLINE 5
|
||||
#define FIND_METALLIC 6
|
||||
#define FIND_IGNEOUS 7
|
||||
#define FIND_METAMORPHIC 8
|
||||
#define FIND_SEDIMENTARY 9
|
||||
#define FIND_NOTHING 10
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Rock sliver
|
||||
|
||||
/obj/item/weapon/rocksliver
|
||||
name = "rock sliver"
|
||||
desc = "It looks extremely delicate."
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "sliver1" //0-4
|
||||
w_class = 1
|
||||
//item_state = "electronic"
|
||||
var/source_rock = "/turf/simulated/mineral/"
|
||||
var/datum/geosample/geological_data
|
||||
|
||||
/obj/item/weapon/rocksliver/New()
|
||||
icon_state = "sliver[rand(1,3)]"
|
||||
pixel_x = rand(0,16)-8
|
||||
pixel_y = rand(0,8)-8
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Geosample datum
|
||||
|
||||
/datum/geosample
|
||||
var/age = 0 //age can correspond to different archaeological finds
|
||||
var/age_thousand = 0
|
||||
var/age_million = 0
|
||||
var/age_billion = 0
|
||||
var/artifact_id = "" //id of a nearby artifact, if there is one
|
||||
var/artifact_distance = -1 //proportional to distance
|
||||
var/source_mineral = "chlorine" //machines will pop up a warning telling players that the sample may be confused
|
||||
//
|
||||
//var/source_mineral
|
||||
//all potential finds are initialised to null, so nullcheck before you access them
|
||||
var/list/find_presence = list()
|
||||
|
||||
/datum/geosample/New(var/turf/simulated/mineral/container)
|
||||
|
||||
UpdateTurf(container)
|
||||
|
||||
//this should only need to be called once
|
||||
/datum/geosample/proc/UpdateTurf(var/turf/simulated/mineral/container)
|
||||
set background = 1
|
||||
if(!container || !istype(container))
|
||||
return
|
||||
|
||||
age = rand(1,999)
|
||||
|
||||
if(container.mineral)
|
||||
switch(container.mineral.name)
|
||||
if("Uranium")
|
||||
age_million = rand(1, 704)
|
||||
age_thousand = rand(1,999)
|
||||
find_presence["potassium"] = rand(1,1000) / 100
|
||||
source_mineral = "potassium"
|
||||
if("Iron")
|
||||
age_thousand = rand(1, 999)
|
||||
age_million = rand(1, 999)
|
||||
find_presence["iron"] = rand(1,1000) / 100
|
||||
source_mineral = "iron"
|
||||
if("Diamond")
|
||||
age_thousand = rand(1,999)
|
||||
age_million = rand(1,999)
|
||||
find_presence["nitrogen"] = rand(1,1000) / 100
|
||||
source_mineral = "nitrogen"
|
||||
if("Gold")
|
||||
age_thousand = rand(1,999)
|
||||
age_million = rand(1,999)
|
||||
age_billion = rand(3,4)
|
||||
find_presence["iron"] = rand(1,1000) / 100
|
||||
source_mineral = "iron"
|
||||
if("Silver")
|
||||
age_thousand = rand(1,999)
|
||||
age_million = rand(1,999)
|
||||
find_presence["iron"] = rand(1,1000) / 100
|
||||
source_mineral = "iron"
|
||||
if("Plasma")
|
||||
age_thousand = rand(1,999)
|
||||
age_million = rand(1,999)
|
||||
age_billion = rand(10, 13)
|
||||
find_presence["plasma"] = rand(1,1000) / 100
|
||||
source_mineral = "plasma"
|
||||
if("Clown")
|
||||
age = rand(-1,-999) //thats the joke
|
||||
age_thousand = rand(-1,-999)
|
||||
find_presence["plasma"] = rand(1,1000) / 100
|
||||
source_mineral = "plasma"
|
||||
|
||||
if(prob(75))
|
||||
find_presence["phosphorus"] = rand(1,500) / 100
|
||||
if(prob(25))
|
||||
find_presence["mercury"] = rand(1,500) / 100
|
||||
find_presence["chlorine"] = rand(500,2500) / 100
|
||||
|
||||
//loop over finds, grab any relevant stuff
|
||||
for(var/datum/find/F in container.finds)
|
||||
var/responsive_reagent = get_responsive_reagent(F.find_type)
|
||||
find_presence[responsive_reagent] = F.dissonance_spread
|
||||
|
||||
//loop over again to reset values to percentages
|
||||
var/total_presence = 0
|
||||
for(var/carrier in find_presence)
|
||||
total_presence += find_presence[carrier]
|
||||
for(var/carrier in find_presence)
|
||||
find_presence[carrier] = find_presence[carrier] / total_presence
|
||||
|
||||
/*for(var/entry in find_presence)
|
||||
total_spread += find_presence[entry]*/
|
||||
|
||||
//have this separate from UpdateTurf() so that we dont have a billion turfs being updated (redundantly) every time an artifact spawns
|
||||
/datum/geosample/proc/UpdateNearbyArtifactInfo(var/turf/simulated/mineral/container)
|
||||
if(!container || !istype(container))
|
||||
return
|
||||
|
||||
if(container.artifact_find)
|
||||
artifact_distance = rand()
|
||||
artifact_id = container.artifact_find.artifact_id
|
||||
else
|
||||
if(master_controller) //Sanity check due to runtimes ~Z
|
||||
for(var/turf/simulated/mineral/T in master_controller.artifact_spawning_turfs)
|
||||
if(T.artifact_find)
|
||||
var/cur_dist = get_dist(container, T) * 2
|
||||
if( (artifact_distance < 0 || cur_dist < artifact_distance) && cur_dist <= T.artifact_find.artifact_detect_range )
|
||||
artifact_distance = cur_dist + rand() * 2 - 1
|
||||
artifact_id = T.artifact_find.artifact_id
|
||||
else
|
||||
master_controller.artifact_spawning_turfs.Remove(T)
|
||||
|
||||
/*
|
||||
#undef FIND_PLANT
|
||||
#undef FIND_BIO
|
||||
#undef FIND_METEORIC
|
||||
#undef FIND_ICE
|
||||
#undef FIND_CRYSTALLINE
|
||||
#undef FIND_METALLIC
|
||||
#undef FIND_IGNEOUS
|
||||
#undef FIND_METAMORPHIC
|
||||
#undef FIND_SEDIMENTARY
|
||||
#undef FIND_NOTHING
|
||||
*/
|
||||
@@ -0,0 +1,251 @@
|
||||
|
||||
/obj/machinery/artifact_analyser
|
||||
name = "Anomaly Analyser"
|
||||
desc = "Studies the emissions of anomalous materials to discover their uses."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "isolator"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/scan_in_progress = 0
|
||||
var/scan_num = 0
|
||||
var/obj/scanned_obj
|
||||
var/obj/machinery/artifact_scanpad/owned_scanner = null
|
||||
var/scan_completion_time = 0
|
||||
var/scan_duration = 120
|
||||
var/obj/scanned_object
|
||||
var/report_num = 0
|
||||
|
||||
/obj/machinery/artifact_analyser/New()
|
||||
..()
|
||||
reconnect_scanner()
|
||||
|
||||
/obj/machinery/artifact_analyser/proc/reconnect_scanner()
|
||||
//connect to a nearby scanner pad
|
||||
owned_scanner = locate(/obj/machinery/artifact_scanpad) in get_step(src, dir)
|
||||
if(!owned_scanner)
|
||||
owned_scanner = locate(/obj/machinery/artifact_scanpad) in orange(1, src)
|
||||
|
||||
/obj/machinery/artifact_analyser/attack_hand(var/mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/artifact_analyser/interact(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN) || get_dist(src, user) > 1)
|
||||
user.unset_machine(src)
|
||||
return
|
||||
|
||||
var/dat = "<B>Anomalous material analyser</B><BR>"
|
||||
dat += "<HR>"
|
||||
if(!owned_scanner)
|
||||
owned_scanner = locate() in orange(1, src)
|
||||
|
||||
if(!owned_scanner)
|
||||
dat += "<b><font color=red>Unable to locate analysis pad.</font></b><br>"
|
||||
else if(scan_in_progress)
|
||||
dat += "Please wait. Analysis in progress.<br>"
|
||||
dat += "<a href='?src=\ref[src];halt_scan=1'>Halt scanning.</a><br>"
|
||||
else
|
||||
dat += "Scanner is ready.<br>"
|
||||
dat += "<a href='?src=\ref[src];begin_scan=1'>Begin scanning.</a><br>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<hr>"
|
||||
dat += "<a href='?src=\ref[src]'>Refresh</a> <a href='?src=\ref[src];close=1'>Close</a>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
user.set_machine(src)
|
||||
onclose(user, "artanalyser")
|
||||
|
||||
/obj/machinery/artifact_analyser/process()
|
||||
if(scan_in_progress && world.time > scan_completion_time)
|
||||
//finish scanning
|
||||
scan_in_progress = 0
|
||||
updateDialog()
|
||||
|
||||
//print results
|
||||
var/results = ""
|
||||
if(!owned_scanner)
|
||||
reconnect_scanner()
|
||||
if(!owned_scanner)
|
||||
results = "Error communicating with scanner."
|
||||
else if(!scanned_object || scanned_object.loc != owned_scanner.loc)
|
||||
results = "Unable to locate scanned object. Ensure it was not moved in the process."
|
||||
else
|
||||
results = get_scan_info(scanned_object)
|
||||
|
||||
src.visible_message("<b>[name]</b> states, \"Scanning complete.\"")
|
||||
var/obj/item/weapon/paper/P = new(src.loc)
|
||||
P.name = "[src] report #[++report_num]"
|
||||
P.info = "<b>[src] analysis report #[report_num]</b><br>"
|
||||
P.info += "<br>"
|
||||
P.info += "\icon[scanned_object] [results]"
|
||||
P.stamped = list(/obj/item/weapon/stamp)
|
||||
P.overlays = list("paper_stamped")
|
||||
|
||||
if(scanned_object && istype(scanned_object, /obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/A = scanned_object
|
||||
A.anchored = 0
|
||||
A.being_used = 0
|
||||
|
||||
/obj/machinery/artifact_analyser/Topic(href, href_list)
|
||||
if(href_list["begin_scan"])
|
||||
if(!owned_scanner)
|
||||
reconnect_scanner()
|
||||
if(owned_scanner)
|
||||
var/artifact_in_use = 0
|
||||
for(var/obj/O in owned_scanner.loc)
|
||||
if(O == owned_scanner)
|
||||
continue
|
||||
if(O.invisibility)
|
||||
continue
|
||||
if(istype(scanned_object, /obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/A = scanned_object
|
||||
if(A.being_used)
|
||||
artifact_in_use = 1
|
||||
else
|
||||
A.anchored = 1
|
||||
A.being_used = 1
|
||||
|
||||
if(artifact_in_use)
|
||||
src.visible_message("<b>[name]</b> states, \"Cannot harvest. Too much interference.\"")
|
||||
else
|
||||
scanned_object = O
|
||||
scan_in_progress = 1
|
||||
scan_completion_time = world.time + scan_duration
|
||||
src.visible_message("<b>[name]</b> states, \"Scanning begun.\"")
|
||||
break
|
||||
if(!scanned_object)
|
||||
src.visible_message("<b>[name]</b> states, \"Unable to isolate scan target.\"")
|
||||
if(href_list["halt_scan"])
|
||||
scan_in_progress = 0
|
||||
src.visible_message("<b>[name]</b> states, \"Scanning halted.\"")
|
||||
|
||||
if(href_list["close"])
|
||||
usr.unset_machine(src)
|
||||
usr << browse(null, "window=artanalyser")
|
||||
|
||||
..()
|
||||
updateDialog()
|
||||
|
||||
//hardcoded responses, oh well
|
||||
/obj/machinery/artifact_analyser/proc/get_scan_info(var/obj/scanned_obj)
|
||||
switch(scanned_obj.type)
|
||||
if(/obj/machinery/auto_cloner)
|
||||
return "Automated cloning pod - appears to rely on organic nanomachines with a self perpetuating \
|
||||
ecosystem involving self cannibalism and a symbiotic relationship with the contained liquid.<br><br>\
|
||||
Structure is composed of a carbo-titanium alloy with interlaced reinforcing energy fields, and the contained liquid \
|
||||
resembles proto-plasmic residue supportive of single cellular developmental conditions."
|
||||
if(/obj/machinery/power/supermatter)
|
||||
return "Super dense plasma clump - Appears to have been shaped or hewn, structure is composed of matter 2000% denser than ordinary carbon matter residue.\
|
||||
Potential application as unrefined plasma source."
|
||||
if(/obj/machinery/power/supermatter)
|
||||
return "Super dense plasma clump - Appears to have been shaped or hewn, structure is composed of matter 2000% denser than ordinary carbon matter residue.\
|
||||
Potential application as unrefined plasma source."
|
||||
if(/obj/structure/constructshell)
|
||||
return "Tribal idol - Item resembles statues/emblems built by superstitious pre-warp civilisations to honour their gods. Material appears to be a \
|
||||
rock/plastcrete composite."
|
||||
if(/obj/machinery/giga_drill)
|
||||
return "Automated mining drill - structure composed of titanium-carbide alloy, with tip and drill lines edged in an alloy of diamond and plasma."
|
||||
if(/obj/structure/cult/pylon)
|
||||
return "Tribal pylon - Item resembles statues/emblems built by cargo cult civilisations to honour energy systems from post-warp civilisations."
|
||||
if(/obj/mecha/working/hoverpod)
|
||||
return "Vacuum capable repair pod - Item is a remarkably intact single man repair craft capable of flight in a vacuum. Outer shell composed of primarily \
|
||||
post-warp hull alloys, with internal wiring and circuitry consistent with modern electronics and engineering."
|
||||
if(/obj/machinery/replicator)
|
||||
return "Automated construction unit - Item appears to be able to synthesize synthetic items, some with simple internal circuitry. Method unknown, \
|
||||
phasing suggested?"
|
||||
if(/obj/structure/crystal)
|
||||
return "Crystal formation - Pseudo organic crystalline matrix, unlikely to have formed naturally. No known technology exists to synthesize this exact composition."
|
||||
if(/obj/machinery/artifact)
|
||||
//the fun one
|
||||
var/obj/machinery/artifact/A = scanned_obj
|
||||
var/out = "Anomalous alien device - Composed of an unknown alloy, "
|
||||
|
||||
//primary effect
|
||||
if(A.my_effect)
|
||||
//what kind of effect the artifact has
|
||||
switch(A.my_effect.effect_type)
|
||||
if(1)
|
||||
out += "concentrated energy emissions"
|
||||
if(2)
|
||||
out += "intermittent psionic wavefront"
|
||||
if(3)
|
||||
out += "electromagnetic energy"
|
||||
if(4)
|
||||
out += "high frequency particles"
|
||||
if(5)
|
||||
out += "organically reactive exotic particles"
|
||||
if(6)
|
||||
out += "interdimensional/bluespace? phasing"
|
||||
if(7)
|
||||
out += "atomic synthesis"
|
||||
else
|
||||
out += "low level energy emissions"
|
||||
out += " have been detected "
|
||||
|
||||
//how the artifact does it's effect
|
||||
switch(A.my_effect.effect_type)
|
||||
if(1)
|
||||
out += " emitting in an ambient energy field."
|
||||
if(2)
|
||||
out += " emitting in periodic bursts."
|
||||
else
|
||||
out += " interspersed throughout substructure and shell."
|
||||
|
||||
if(A.my_effect.trigger >= 0 && A.my_effect.trigger <= 4)
|
||||
out += " Activation index involves physical interaction with artifact surface."
|
||||
else if(A.my_effect.trigger >= 5 && A.my_effect.trigger <= 8)
|
||||
out += " Activation index involves energetic interaction with artifact surface."
|
||||
else if(A.my_effect.trigger >= 9 && A.my_effect.trigger <= 12)
|
||||
out += " Activation index involves precise local atmospheric conditions."
|
||||
else
|
||||
out += " Unable to determine any data about activation trigger."
|
||||
|
||||
//secondary:
|
||||
if(A.secondary_effect && A.secondary_effect.activated)
|
||||
//sciencey words go!
|
||||
out += "<br><br>Warning, internal scans indicate ongoing [pick("subluminous","subcutaneous","superstructural")] activity operating \
|
||||
independantly from primary systems. Auxiliary activity involves "
|
||||
|
||||
//what kind of effect the artifact has
|
||||
switch(A.secondary_effect.effect_type)
|
||||
if(1)
|
||||
out += "concentrated energy emissions"
|
||||
if(2)
|
||||
out += "intermittent psionic wavefront"
|
||||
if(3)
|
||||
out += "electromagnetic energy"
|
||||
if(4)
|
||||
out += "high frequency particles"
|
||||
if(5)
|
||||
out += "organically reactive exotic particles"
|
||||
if(6)
|
||||
out += "interdimensional/bluespace? phasing"
|
||||
if(7)
|
||||
out += "atomic synthesis"
|
||||
else
|
||||
out += "low level radiation"
|
||||
|
||||
//how the artifact does it's effect
|
||||
switch(A.secondary_effect.effect_type)
|
||||
if(1)
|
||||
out += " emitting in an ambient energy field."
|
||||
if(2)
|
||||
out += " emitting in periodic bursts."
|
||||
else
|
||||
out += " interspersed throughout substructure and shell."
|
||||
|
||||
if(A.secondary_effect.trigger >= 0 && A.secondary_effect.trigger <= 4)
|
||||
out += " Activation index involves physical interaction with artifact surface, but subsystems indicate \
|
||||
anomalous interference with standard attempts at triggering."
|
||||
else if(A.secondary_effect.trigger >= 5 && A.secondary_effect.trigger <= 8)
|
||||
out += " Activation index involves energetic interaction with artifact surface, but subsystems indicate \
|
||||
anomalous interference with standard attempts at triggering."
|
||||
else if(A.secondary_effect.trigger >= 9 && A.secondary_effect.trigger <= 12)
|
||||
out += " Activation index involves precise local atmospheric conditions, but subsystems indicate \
|
||||
anomalous interference with standard attempts at triggering."
|
||||
else
|
||||
out += " Unable to determine any data about activation trigger."
|
||||
return out
|
||||
else
|
||||
//it was an ordinary item
|
||||
return "[scanned_obj.name] - Mundane application, composed of carbo-ferritic alloy composite."
|
||||
@@ -0,0 +1,227 @@
|
||||
|
||||
/obj/machinery/artifact_harvester
|
||||
name = "Exotic Particle Harvester"
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "incubator" //incubator_on
|
||||
anchored = 1
|
||||
density = 1
|
||||
idle_power_usage = 50
|
||||
active_power_usage = 750
|
||||
use_power = 1
|
||||
var/harvesting = 0
|
||||
var/obj/item/weapon/anobattery/inserted_battery
|
||||
var/obj/machinery/artifact/cur_artifact
|
||||
var/obj/machinery/artifact_scanpad/owned_scanner = null
|
||||
|
||||
/obj/machinery/artifact_harvester/New()
|
||||
..()
|
||||
//connect to a nearby scanner pad
|
||||
owned_scanner = locate(/obj/machinery/artifact_scanpad) in get_step(src, dir)
|
||||
if(!owned_scanner)
|
||||
owned_scanner = locate(/obj/machinery/artifact_scanpad) in orange(1, src)
|
||||
|
||||
/obj/machinery/artifact_harvester/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(istype(I,/obj/item/weapon/anobattery))
|
||||
if(!inserted_battery)
|
||||
user << "\blue You insert [I] into [src]."
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
src.inserted_battery = I
|
||||
updateDialog()
|
||||
else
|
||||
user << "\red There is already a battery in [src]."
|
||||
else
|
||||
return..()
|
||||
|
||||
/obj/machinery/artifact_harvester/attack_hand(var/mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/artifact_harvester/interact(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<B>Artifact Power Harvester</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
//
|
||||
if(owned_scanner)
|
||||
if(harvesting)
|
||||
if(harvesting > 0)
|
||||
dat += "Please wait. Harvesting in progress ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%).<br>"
|
||||
else
|
||||
dat += "Please wait. Energy dump in progress ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%).<br>"
|
||||
dat += "<A href='?src=\ref[src];stopharvest=1'>Halt early</A><BR>"
|
||||
else
|
||||
if(inserted_battery)
|
||||
dat += "<b>[inserted_battery.name]</b> inserted, charge level: [inserted_battery.stored_charge]/[inserted_battery.capacity] ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%)<BR>"
|
||||
dat += "<b>Energy signature ID:</b>[inserted_battery.battery_effect.artifact_id == "" ? "???" : "[inserted_battery.battery_effect.artifact_id]"]<BR>"
|
||||
dat += "<A href='?src=\ref[src];ejectbattery=1'>Eject battery</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];drainbattery=1'>Drain battery of all charge</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];harvest=1'>Begin harvesting</a><BR>"
|
||||
|
||||
else
|
||||
dat += "No battery inserted.<BR>"
|
||||
else
|
||||
dat += "<B><font color=red>Unable to locate analysis pad.</font><BR></b>"
|
||||
//
|
||||
dat += "<HR>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</A> <A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artharvester;size=450x500")
|
||||
onclose(user, "artharvester")
|
||||
|
||||
/obj/machinery/artifact_harvester/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
if(harvesting > 0)
|
||||
//gain a bit of charge
|
||||
inserted_battery.stored_charge += 0.5
|
||||
|
||||
//check if we've finished
|
||||
if(inserted_battery.stored_charge >= inserted_battery.capacity)
|
||||
use_power = 1
|
||||
harvesting = 0
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
src.visible_message("<b>[name]</b> states, \"Battery is full.\"")
|
||||
icon_state = "incubator"
|
||||
|
||||
else if(harvesting < 0)
|
||||
//dump some charge
|
||||
inserted_battery.stored_charge -= 2
|
||||
|
||||
//do the effect
|
||||
if(inserted_battery.battery_effect)
|
||||
inserted_battery.battery_effect.process()
|
||||
|
||||
//if the effect works by touch, activate it on anyone viewing the console
|
||||
if(inserted_battery.battery_effect.effect == 0)
|
||||
var/list/nearby = viewers(1, src)
|
||||
for(var/mob/M in nearby)
|
||||
if(M.machine == src)
|
||||
inserted_battery.battery_effect.DoEffectTouch(M)
|
||||
|
||||
//if there's no charge left, finish
|
||||
if(inserted_battery.stored_charge <= 0)
|
||||
use_power = 1
|
||||
inserted_battery.stored_charge = 0
|
||||
harvesting = 0
|
||||
if(inserted_battery.battery_effect && inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate()
|
||||
src.visible_message("<b>[name]</b> states, \"Battery dump completed.\"")
|
||||
icon_state = "incubator"
|
||||
|
||||
/obj/machinery/artifact_harvester/Topic(href, href_list)
|
||||
|
||||
if (href_list["harvest"])
|
||||
//locate artifact on analysis pad
|
||||
cur_artifact = null
|
||||
var/articount = 0
|
||||
var/obj/machinery/artifact/analysed
|
||||
for(var/obj/machinery/artifact/A in get_turf(owned_scanner))
|
||||
analysed = A
|
||||
articount++
|
||||
|
||||
var/mundane = 0
|
||||
for(var/obj/O in get_turf(owned_scanner))
|
||||
if(O.invisibility)
|
||||
continue
|
||||
if(!istype(O, /obj/machinery/artifact) && !istype(O, /obj/machinery/artifact_scanpad))
|
||||
mundane++
|
||||
break
|
||||
for(var/mob/O in get_turf(owned_scanner))
|
||||
if(O.invisibility)
|
||||
continue
|
||||
mundane++
|
||||
break
|
||||
|
||||
if(analysed.being_used)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. Too much interference.\""
|
||||
src.visible_message(message)
|
||||
else if(articount == 1 && !mundane)
|
||||
cur_artifact = analysed
|
||||
//there should already be a battery inserted, but this is just in case
|
||||
if(inserted_battery)
|
||||
//see if we can clear out an old effect
|
||||
//delete it when the ids match to account for duplicate ids having different effects
|
||||
if(inserted_battery.battery_effect && inserted_battery.stored_charge <= 0)
|
||||
del(inserted_battery.battery_effect)
|
||||
|
||||
//only charge up
|
||||
var/matching_id = 0
|
||||
if(inserted_battery.battery_effect)
|
||||
matching_id = (inserted_battery.battery_effect.artifact_id == cur_artifact.my_effect.artifact_id)
|
||||
var/matching_effecttype = 0
|
||||
if(inserted_battery.battery_effect)
|
||||
matching_effecttype = (inserted_battery.battery_effect.type == cur_artifact.my_effect.type)
|
||||
if(!inserted_battery.battery_effect || (matching_id && matching_effecttype))
|
||||
harvesting = 1
|
||||
use_power = 2
|
||||
cur_artifact.anchored = 1
|
||||
cur_artifact.being_used = 1
|
||||
icon_state = "incubator_on"
|
||||
var/message = "<b>[src]</b> states, \"Beginning artifact energy harvesting.\""
|
||||
src.visible_message(message)
|
||||
|
||||
//duplicate the artifact's effect datum
|
||||
if(!inserted_battery.battery_effect)
|
||||
var/effecttype = cur_artifact.my_effect.type
|
||||
var/datum/artifact_effect/E = new effecttype(inserted_battery)
|
||||
|
||||
//duplicate it's unique settings
|
||||
for(var/varname in list("chargelevelmax","artifact_id","effect","effectrange","trigger"))
|
||||
E.vars[varname] = cur_artifact.my_effect.vars[varname]
|
||||
|
||||
//copy the new datum into the battery
|
||||
inserted_battery.battery_effect = E
|
||||
inserted_battery.stored_charge = 0
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. Incompatible energy signatures detected.\""
|
||||
src.visible_message(message)
|
||||
else if(cur_artifact)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. No battery inserted.\""
|
||||
src.visible_message(message)
|
||||
else if(articount > 1 || mundane)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. Error isolating energy signature.\""
|
||||
src.visible_message(message)
|
||||
else if(!articount)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. No noteworthy energy signature isolated.\""
|
||||
src.visible_message(message)
|
||||
|
||||
if (href_list["stopharvest"])
|
||||
if(harvesting)
|
||||
if(harvesting < 0 && inserted_battery.battery_effect && inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate()
|
||||
harvesting = 0
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
src.visible_message("<b>[name]</b> states, \"Activity interrupted.\"")
|
||||
icon_state = "incubator"
|
||||
|
||||
if (href_list["ejectbattery"])
|
||||
src.inserted_battery.loc = src.loc
|
||||
src.inserted_battery = null
|
||||
|
||||
if (href_list["drainbattery"])
|
||||
if(inserted_battery)
|
||||
if(inserted_battery.battery_effect && inserted_battery.stored_charge > 0)
|
||||
if(alert("This action will dump all charge, safety gear is recommended before proceeding","Warning","Continue","Cancel"))
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(0)
|
||||
harvesting = -1
|
||||
use_power = 2
|
||||
icon_state = "incubator_on"
|
||||
var/message = "<b>[src]</b> states, \"Warning, battery charge dump commencing.\""
|
||||
src.visible_message(message)
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot dump energy. Battery is drained of charge already.\""
|
||||
src.visible_message(message)
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot dump energy. No battery inserted.\""
|
||||
src.visible_message(message)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artharvester")
|
||||
usr.unset_machine(src)
|
||||
|
||||
updateDialog()
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
/obj/machinery/artifact_scanpad
|
||||
name = "Anomaly Scanner Pad"
|
||||
desc = "Place things here for scanning."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "tele0"
|
||||
anchored = 1
|
||||
density = 0
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
datum/reagent/coolant
|
||||
name = "Coolant"
|
||||
id = "coolant"
|
||||
description = "Industrial cooling substance."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC" // rgb: 200, 165, 220
|
||||
|
||||
datum/chemical_reaction/coolant
|
||||
name = "Coolant"
|
||||
id = "coolant"
|
||||
result = "coolant"
|
||||
required_reagents = list("tungsten" = 1, "oxygen" = 1, "water" = 1)
|
||||
result_amount = 3
|
||||
|
||||
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank
|
||||
name = "coolant tank"
|
||||
desc = "A tank of industrial coolant"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "coolanttank"
|
||||
amount_per_transfer_from_this = 10
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("coolant",1000)
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if(!istype(Proj ,/obj/item/projectile/beam/lastertag) && !istype(Proj ,/obj/item/projectile/beam/practice) )
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank/blob_act()
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank/ex_act()
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/coolanttank/proc/explode()
|
||||
var/datum/effect/effect/system/smoke_spread/S = new /datum/effect/effect/system/smoke_spread
|
||||
//S.attach(src)
|
||||
S.set_up(5, 0, src.loc)
|
||||
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
spawn(0)
|
||||
S.start()
|
||||
|
||||
var/datum/gas_mixture/env = src.loc.return_air()
|
||||
if(env)
|
||||
if (reagents.total_volume > 750)
|
||||
env.temperature = 0
|
||||
else if (reagents.total_volume > 500)
|
||||
env.temperature -= 100
|
||||
else
|
||||
env.temperature -= 50
|
||||
|
||||
sleep(10)
|
||||
if(src)
|
||||
del(src)
|
||||
@@ -0,0 +1,362 @@
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer
|
||||
name = "Radiocarbon spectrometer"
|
||||
desc = "A specialised, complex scanner for gleaning information on all manner of small things."
|
||||
anchored = 1
|
||||
density = 1
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
use_power = 1 //1 = idle, 2 = active
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 300
|
||||
|
||||
//var/obj/item/weapon/reagent_containers/glass/coolant_container
|
||||
var/scanning = 0
|
||||
var/report_num = 0
|
||||
//
|
||||
var/obj/item/scanned_item
|
||||
var/last_scan_data = "No scans on record."
|
||||
//
|
||||
var/last_process_worldtime = 0
|
||||
//
|
||||
var/scanner_progress = 0
|
||||
var/scanner_rate = 1.25 //80 seconds per scan
|
||||
var/scanner_rpm = 0
|
||||
var/scanner_rpm_dir = 1
|
||||
var/scanner_temperature = 0
|
||||
var/scanner_seal_integrity = 100
|
||||
//
|
||||
var/coolant_usage_rate = 0 //measured in u/microsec
|
||||
var/fresh_coolant = 0
|
||||
var/coolant_purity = 0
|
||||
var/datum/reagents/coolant_reagents
|
||||
var/used_coolant = 0
|
||||
var/list/coolant_reagents_purity = list()
|
||||
//
|
||||
var/maser_wavelength = 0
|
||||
var/optimal_wavelength = 0
|
||||
var/optimal_wavelength_target = 0
|
||||
var/tleft_retarget_optimal_wavelength = 0
|
||||
var/maser_efficiency = 0
|
||||
//
|
||||
var/radiation = 0 //0-100 mSv
|
||||
var/t_left_radspike = 0
|
||||
var/rad_shield = 0
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/New()
|
||||
..()
|
||||
create_reagents(500)
|
||||
coolant_reagents_purity["water"] = 0.5
|
||||
coolant_reagents_purity["icecoffee"] = 0.6
|
||||
coolant_reagents_purity["icetea"] = 0.6
|
||||
coolant_reagents_purity["milkshake"] = 0.6
|
||||
coolant_reagents_purity["leporazine"] = 0.7
|
||||
coolant_reagents_purity["kelotane"] = 0.7
|
||||
coolant_reagents_purity["sterilizine"] = 0.7
|
||||
coolant_reagents_purity["dermaline"] = 0.7
|
||||
coolant_reagents_purity["hyperzine"] = 0.8
|
||||
coolant_reagents_purity["cryoxadone"] = 0.9
|
||||
coolant_reagents_purity["coolant"] = 1
|
||||
coolant_reagents_purity["adminordrazine"] = 2
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/attack_hand(var/mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(scanning)
|
||||
user << "<span class='warning'>You can't do that while [src] is scanning!</span>"
|
||||
else
|
||||
if(istype(I, /obj/item/stack/nanopaste))
|
||||
var/choice = alert("What do you want to do with the nanopaste?","Radiometric Scanner","Scan nanopaste","Fix seal integrity")
|
||||
if(choice == "Fix seal integrity")
|
||||
var/obj/item/stack/nanopaste/N = I
|
||||
var/amount_used = min(N.amount, 10 - scanner_seal_integrity / 10)
|
||||
N.use(amount_used)
|
||||
scanner_seal_integrity = round(scanner_seal_integrity + amount_used * 10)
|
||||
return
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
var/choice = alert("What do you want to do with the container?","Radiometric Scanner","Add coolant","Empty coolant","Scan container")
|
||||
if(choice == "Add coolant")
|
||||
var/obj/item/weapon/reagent_containers/glass/G = I
|
||||
var/amount_transferred = min(src.reagents.maximum_volume - src.reagents.total_volume, G.reagents.total_volume)
|
||||
G.reagents.trans_to(src, amount_transferred)
|
||||
user << "<span class='info'>You empty [amount_transferred]u of coolant into [src].</span>"
|
||||
update_coolant()
|
||||
return
|
||||
else if(choice == "Empty coolant")
|
||||
var/obj/item/weapon/reagent_containers/glass/G = I
|
||||
var/amount_transferred = min(G.reagents.maximum_volume - G.reagents.total_volume, src.reagents.total_volume)
|
||||
src.reagents.trans_to(G, amount_transferred)
|
||||
user << "<span class='info'>You remove [amount_transferred]u of coolant from [src].</span>"
|
||||
update_coolant()
|
||||
return
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
scanned_item = I
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/proc/update_coolant()
|
||||
var/total_purity = 0
|
||||
fresh_coolant = 0
|
||||
coolant_purity = 0
|
||||
var/num_reagent_types = 0
|
||||
for (var/datum/reagent/current_reagent in src.reagents.reagent_list)
|
||||
if (!current_reagent)
|
||||
continue
|
||||
var/cur_purity = coolant_reagents_purity[current_reagent.id]
|
||||
if(!cur_purity)
|
||||
cur_purity = 0.1
|
||||
else if(cur_purity > 1)
|
||||
cur_purity = 1
|
||||
total_purity += cur_purity * current_reagent.volume
|
||||
fresh_coolant += current_reagent.volume
|
||||
num_reagent_types += 1
|
||||
if(total_purity && fresh_coolant)
|
||||
coolant_purity = total_purity / fresh_coolant
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
|
||||
|
||||
if(user.stat)
|
||||
return
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
var/data[0]
|
||||
data["scanned_item"] = (scanned_item ? scanned_item.name : "")
|
||||
data["scanned_item_desc"] = (scanned_item ? (scanned_item.desc ? scanned_item.desc : "No information on record.") : "")
|
||||
data["last_scan_data"] = last_scan_data
|
||||
//
|
||||
data["scan_progress"] = round(scanner_progress)
|
||||
data["scanning"] = scanning
|
||||
//
|
||||
data["scanner_seal_integrity"] = round(scanner_seal_integrity)
|
||||
data["scanner_rpm"] = round(scanner_rpm)
|
||||
data["scanner_temperature"] = round(scanner_temperature)
|
||||
//
|
||||
data["coolant_usage_rate"] = "[coolant_usage_rate]"
|
||||
data["unused_coolant_abs"] = round(fresh_coolant)
|
||||
data["unused_coolant_per"] = round(fresh_coolant / reagents.maximum_volume * 100)
|
||||
data["coolant_purity"] = "[coolant_purity * 100]"
|
||||
//
|
||||
data["optimal_wavelength"] = round(optimal_wavelength)
|
||||
data["maser_wavelength"] = round(maser_wavelength)
|
||||
data["maser_efficiency"] = round(maser_efficiency * 100)
|
||||
//
|
||||
data["radiation"] = round(radiation)
|
||||
data["t_left_radspike"] = round(t_left_radspike)
|
||||
data["rad_shield_on"] = rad_shield
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "geoscanner.tmpl", "High Res Radiocarbon Spectrometer", 900, 825)
|
||||
// when the ui is first opened this is the data it will use
|
||||
ui.set_initial_data(data)
|
||||
// open the new ui window
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/process()
|
||||
if(scanning)
|
||||
if(!scanned_item || scanned_item.loc != src)
|
||||
scanned_item = null
|
||||
stop_scanning()
|
||||
else if(scanner_progress >= 100)
|
||||
complete_scan()
|
||||
else
|
||||
//calculate time difference
|
||||
var/deltaT = (world.time - last_process_worldtime) * 0.1
|
||||
|
||||
//modify the RPM over time
|
||||
//i want 1u to last for 10 sec at 500 RPM, scaling linearly
|
||||
scanner_rpm += scanner_rpm_dir * 50 * deltaT
|
||||
if(scanner_rpm > 1000)
|
||||
scanner_rpm = 1000
|
||||
scanner_rpm_dir = -1 * pick(0.5, 2.5, 5.5)
|
||||
else if(scanner_rpm < 1)
|
||||
scanner_rpm = 1
|
||||
scanner_rpm_dir = 1 * pick(0.5, 2.5, 5.5)
|
||||
|
||||
//heat up according to RPM
|
||||
//each unit of coolant
|
||||
scanner_temperature += scanner_rpm * deltaT * 0.05
|
||||
|
||||
//radiation
|
||||
t_left_radspike -= deltaT
|
||||
if(t_left_radspike > 0)
|
||||
//ordinary radiation
|
||||
radiation = rand() * 15
|
||||
else
|
||||
//radspike
|
||||
if(t_left_radspike > -5)
|
||||
radiation = rand() * 15 + 85
|
||||
if(!rad_shield)
|
||||
//irradiate nearby mobs
|
||||
for(var/mob/living/M in view(7,src))
|
||||
M.apply_effect(radiation / 25, IRRADIATE, 0)
|
||||
else
|
||||
t_left_radspike = pick(10,15,25)
|
||||
|
||||
//use some coolant to cool down
|
||||
if(coolant_usage_rate > 0)
|
||||
var/coolant_used = min(fresh_coolant, coolant_usage_rate * deltaT)
|
||||
if(coolant_used > 0)
|
||||
fresh_coolant -= coolant_used
|
||||
used_coolant += coolant_used
|
||||
scanner_temperature = max(scanner_temperature - coolant_used * coolant_purity * 20, 0)
|
||||
|
||||
//modify the optimal wavelength
|
||||
tleft_retarget_optimal_wavelength -= deltaT
|
||||
if(tleft_retarget_optimal_wavelength <= 0)
|
||||
tleft_retarget_optimal_wavelength = pick(4,8,15)
|
||||
optimal_wavelength_target = rand() * 9900 + 100
|
||||
//
|
||||
if(optimal_wavelength < optimal_wavelength_target)
|
||||
optimal_wavelength = min(optimal_wavelength + 700 * deltaT, optimal_wavelength_target)
|
||||
else if(optimal_wavelength > optimal_wavelength_target)
|
||||
optimal_wavelength = max(optimal_wavelength - 700 * deltaT, optimal_wavelength_target)
|
||||
//
|
||||
maser_efficiency = 1 - max(min(10000, abs(optimal_wavelength - maser_wavelength) * 3), 1) / 10000
|
||||
|
||||
//make some scan progress
|
||||
if(!rad_shield)
|
||||
scanner_progress = min(100, scanner_progress + scanner_rate * maser_efficiency * deltaT)
|
||||
|
||||
//degrade the seal over time according to temperature
|
||||
//i want temperature of 50K to degrade at 1%/sec
|
||||
scanner_seal_integrity -= (max(scanner_temperature, 1) / 1000) * deltaT
|
||||
|
||||
//emergency stop if seal integrity reaches 0
|
||||
if(scanner_seal_integrity <= 0 || (scanner_temperature >= 1273 && !rad_shield))
|
||||
stop_scanning()
|
||||
src.visible_message("\blue \icon[src] buzzes unhappily. It has failed mid-scan!", 2)
|
||||
|
||||
if(prob(5))
|
||||
src.visible_message("\blue \icon[src] [pick("whirrs","chuffs","clicks")][pick(" excitedly"," energetically"," busily")].", 2)
|
||||
else
|
||||
//gradually cool down over time
|
||||
if(scanner_temperature > 0)
|
||||
scanner_temperature = max(scanner_temperature - 5 - 10 * rand(), 0)
|
||||
if(prob(0.75))
|
||||
src.visible_message("\blue \icon[src] [pick("plinks","hisses")][pick(" quietly"," softly"," sadly"," plaintively")].", 2)
|
||||
last_process_worldtime = world.time
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/proc/stop_scanning()
|
||||
scanning = 0
|
||||
scanner_rpm_dir = 1
|
||||
scanner_rpm = 0
|
||||
optimal_wavelength = 0
|
||||
maser_efficiency = 0
|
||||
maser_wavelength = 0
|
||||
coolant_usage_rate = 0
|
||||
radiation = 0
|
||||
t_left_radspike = 0
|
||||
if(used_coolant)
|
||||
src.reagents.remove_any(used_coolant)
|
||||
used_coolant = 0
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/proc/complete_scan()
|
||||
src.visible_message("\blue \icon[src] makes an insistent chime.", 2)
|
||||
|
||||
if(scanned_item)
|
||||
//create report
|
||||
var/obj/item/weapon/paper/P = new(src)
|
||||
P.name = "[src] report #[++report_num]: [scanned_item.name]"
|
||||
P.stamped = list(/obj/item/weapon/stamp)
|
||||
P.overlays = list("paper_stamped")
|
||||
|
||||
//work out data
|
||||
var/data = " - Mundane object: [scanned_item.desc ? scanned_item.desc : "No information on record."]<br>"
|
||||
var/datum/geosample/G
|
||||
switch(scanned_item.type)
|
||||
if(/obj/item/weapon/ore)
|
||||
var/obj/item/weapon/ore/O = scanned_item
|
||||
if(O.geologic_data)
|
||||
G = O.geologic_data
|
||||
|
||||
if(/obj/item/weapon/rocksliver)
|
||||
var/obj/item/weapon/rocksliver/O = scanned_item
|
||||
if(O.geological_data)
|
||||
G = O.geological_data
|
||||
|
||||
if(/obj/item/weapon/archaeological_find)
|
||||
data = " - Mundane object (archaic xenos origins)<br>"
|
||||
|
||||
var/obj/item/weapon/archaeological_find/A = scanned_item
|
||||
if(A.speaking_to_players)
|
||||
data = " - Exhibits properties consistent with sonic reproduction.<br>"
|
||||
if(A.listening_to_players)
|
||||
data = " - Exhibits properties similar to audio capture technology.<br>"
|
||||
|
||||
var/anom_found = 0
|
||||
if(G)
|
||||
data = " - Spectometric analysis on mineral sample has determined type [finds_as_strings[responsive_carriers.Find(G.source_mineral)]]<br>"
|
||||
if(G.age_billion > 0)
|
||||
data += " - Radiometric dating shows age of [G.age_billion].[G.age_million] billion years<br>"
|
||||
else if(G.age_million > 0)
|
||||
data += " - Radiometric dating shows age of [G.age_million].[G.age_thousand] million years<br>"
|
||||
else
|
||||
data += " - Radiometric dating shows age of [G.age_thousand * 1000 + G.age] years<br>"
|
||||
data += " - Chromatographic analysis shows the following materials present:<br>"
|
||||
for(var/carrier in G.find_presence)
|
||||
if(G.find_presence[carrier])
|
||||
var/index = responsive_carriers.Find(carrier)
|
||||
if(index > 0 && index <= finds_as_strings.len)
|
||||
data += " > [100 * G.find_presence[carrier]]% [finds_as_strings[index]]<br>"
|
||||
|
||||
if(G.artifact_id && G.artifact_distance >= 0)
|
||||
anom_found = 1
|
||||
data += " - Hyperspectral imaging reveals exotic energy wavelength detected with ID: [G.artifact_id]<br>"
|
||||
data += " - Fourier transform analysis on anomalous energy absorption indicates energy source located inside emission radius of [G.artifact_distance]m<br>"
|
||||
|
||||
if(!anom_found)
|
||||
data += " - No anomalous data<br>"
|
||||
|
||||
P.info = "<b>[src] analysis report #[report_num]</b><br>"
|
||||
P.info += "<b>Scanned item:</b> [scanned_item.name]<br><br>" + data
|
||||
last_scan_data = P.info
|
||||
P.loc = src.loc
|
||||
|
||||
scanned_item.loc = src.loc
|
||||
scanned_item = null
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/Topic(href, href_list)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0 // don't update UIs attached to this object
|
||||
|
||||
if(href_list["scanItem"])
|
||||
if(scanning)
|
||||
stop_scanning()
|
||||
else
|
||||
if(scanned_item)
|
||||
if(scanner_seal_integrity > 0)
|
||||
scanner_progress = 0
|
||||
scanning = 1
|
||||
t_left_radspike = pick(5,10,15)
|
||||
usr << "<span class='notice'>Scan initiated.</span>"
|
||||
else
|
||||
usr << "<span class='warning'>Could not initiate scan, seal requires replacing.</span>"
|
||||
else
|
||||
usr << "<span class='warning'>Insert an item to scan.</span>"
|
||||
|
||||
if(href_list["maserWavelength"])
|
||||
maser_wavelength = max(min(maser_wavelength + 1000 * text2num(href_list["maserWavelength"]), 10000), 1)
|
||||
|
||||
if(href_list["coolantRate"])
|
||||
coolant_usage_rate = max(min(coolant_usage_rate + text2num(href_list["coolantRate"]), 10000), 0)
|
||||
|
||||
if(href_list["toggle_rad_shield"])
|
||||
if(rad_shield)
|
||||
rad_shield = 0
|
||||
else
|
||||
rad_shield = 1
|
||||
|
||||
if(href_list["ejectItem"])
|
||||
if(scanned_item)
|
||||
scanned_item.loc = src.loc
|
||||
scanned_item = null
|
||||
|
||||
add_fingerprint(usr)
|
||||
return 1 // update UIs attached to this object
|
||||
@@ -0,0 +1,370 @@
|
||||
|
||||
/obj/item/weapon/book/manual/excavation
|
||||
name = "Out on the dig"
|
||||
icon_state = "excavation"
|
||||
author = "Professor Patrick Mason, Curator of the Antiquities Museum on Ichar VII"
|
||||
title = "Out on the dig"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Prep">Prepping the expedition</a></li>
|
||||
<li><a href="#Tools">Knowing your tools</a></li>
|
||||
<li><a href="#Find">Finding the dig</a></li>
|
||||
<li><a href="#Analyse">Analysing deposits</a></li>
|
||||
<li><a href="#Excavate">Extracting your first find</a></li>
|
||||
</ol>
|
||||
<br>
|
||||
|
||||
<h1><a name="Prep">Prepping the expedition</a></h1>
|
||||
Every digsite I've been to, someone has forgotten something and I've never yet been to a dig that hasn't had me hiking to get to it - so gather your gear
|
||||
and get it to the site the first time. You learn quick that time is money, when you've got a shipful of bandits searching for you the next valley over,
|
||||
but don't be afraid to clear some space if there are any inconvenient boulders in the way.<br>
|
||||
<list>
|
||||
<li>Floodlights (if it's dark)</li>
|
||||
<li>Wooden trestle tables (for holding tools and finds)</li>
|
||||
<li>Suspension field generator</li>
|
||||
<li>Load bearing servitors (such as a mulebot, or hover-tray)</li>
|
||||
<li>Spare energy packs</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Tools">Knowing your tools</a></h1>
|
||||
Every archaeologist has a plethora of tools at their disposal, but here's the important ones:<br>
|
||||
<list>
|
||||
<li><b>Picks, pickaxes and brushes</b> - don't underestimate the the smallest or largest in your arsenal, each one clears a different amount
|
||||
of the rockface so each one has a use.</li>
|
||||
<li><b>Measuring tape</b> - don't leave home without it, you can use it to measure the depth a rock face has been excavated to.</li>
|
||||
<li><b>GPS locater</b> - knowing where you are is the first step to not be lost.</li>
|
||||
<li><b>Core sampler</b> - use this to take core samples from rock faces, which you can then run to the lab for analysis.</li>
|
||||
<li><b>Depth scanner</b> - uses x-ray diffraction to locate anomalous densities in rock, indicating archaeological deposits or mineral veins.
|
||||
Comes with a handy reference log containing co-ordinates and time of each scan.</li>
|
||||
<li><b>Alden-Saraspova counter</b> - uses a patented application of Fourier Transform analysis to determine the difference between background and
|
||||
exotic radiation. Use it to determine how far you are from anomalous energy sources.</li>
|
||||
<li><b>Radio beacon locater</b> - leave a beacon at an item of interest, then track it down later with this handy gadget. Watch for interference from other
|
||||
devices though.</li>
|
||||
<li><b>Flashlight or portable light source</b> - Self explanatory, I hope.</li>
|
||||
<li><b>Environmental safety gear</b> - This one's dependant on the environment you're working in, but enclosed footwear and pack of internals
|
||||
could save your life.</li>
|
||||
<li><b>Anomaly safety gear</b> - A biosealed and catalysis-resistant suit along with eye shielding, tinted hood and non-reactive disposable gloves are
|
||||
the best kind of protection you can hope for from the errors our forbears may have unleashed.</li>
|
||||
<li><b>Personal defence weapon</b> - Never know what you'll find on the dig: pirates, natives, ancient guardians, carnivorous wildlife...
|
||||
it pays in blood to be prepared.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Find">Finding the dig</a></h1>
|
||||
Wouldn't be an archaeologist without their dig, but everyone has to start somewhere. Here's a basic procedure I go through when cataloguing a new planet:<br>
|
||||
<list>
|
||||
<li><b>Get in touch with the locals</b> (in particular geologists, miners and farmers) - Never know what's been turned up by accident, then left to
|
||||
gather dust on a shelf.</li>
|
||||
<li><b>Check the obvious areas first</b> - even if you're pressed for time, these ones are the generally easiest to search, and the most likely targets
|
||||
of your rivals.</li>
|
||||
<li><b>Do some prospecting</b> - the earth mother isn't in the habit of displaying her secrets to the world (although sometimes you get lucky).
|
||||
Drop a shaft and clear away a bit of surface rock here and there, you never know what might be lurking below the surface.</li>
|
||||
<li><b>Tips on unearthing a deposit</b> - How do you know when you're golden? Look for telltale white strata that looks strange or out of place, or if
|
||||
something has broken under your pick while you're digging. Your depth scanner is your best friend, but even it can't distinguish between
|
||||
ordinary minerals and ancient leavings, if in doubt then err on the side of caution.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Analyse">Analysing the contents of a dig</a></h1>
|
||||
You've found some unusual strata, but it's not all peaches from here. No archaeologist ever managed to pull a bone from the earth without doing thorough
|
||||
chemical analysis on every two meters of rock face nearby.<br>
|
||||
<list>
|
||||
<li><b>Take core samples</b> - Grab a rock core for every 4m^2.</li>
|
||||
<li><b>Clear around any potential finds</b> - Clear away ordinary rock, leaving your prizes reachable in a clearly marked area.</li>
|
||||
<li><b>Haul off excess rock</b> - It's easy for a dig to get cluttered, and a neat archaeologist is a successful archaeologist.</li>
|
||||
<li><b>Don't be afraid to be cautious</b> - It's slower sometimes, but the extra time will be worth the payoff when you find an Exolitic relic.</li>
|
||||
<li><b>Chemical analysis</b> - I won't go into detail here, but the labwork is essential to any successful extraction. Marshal your core samples, and
|
||||
send them off to the labcoated geniuses</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Excavate">Extracting your first find</a></h1>
|
||||
<list>
|
||||
<li><b>Scan the rock</b> - Use a depth scanner to determine the find's depth and clearance. DON'T FORGET THESE.</li>
|
||||
<li><b>Choose stasis field</b> - Chemical analysis on a core sample from the rock face will tell you which field is necessary to extract the find safely</li>
|
||||
<li><b>Setup field gen</b> - Bolt it down, choose the field, check the charge and activate it. If you forget it, you'll wish you hadn't when that priceless
|
||||
Uryom vase crumbles as it sees the light of day.</li>
|
||||
<li><b>FUNCTIONAL AND SAFE digging</b> - Dig into the rock until you've cleared away a depth equal to (the anomaly depth MINUS the clearance range). The find
|
||||
should come loose on it's own, but it will be in the midst of a chunk of rock. Use a welder or miniature excavation tool to clear away the excess.</li>
|
||||
<li><b>FANCY AND SPEEDY digging</b> - Dig into the rock until you've cleared away a depth equal to the anomaly depth, but without any of your strokes
|
||||
entering the clearance range.</li>
|
||||
<li><b>The Big Find</b> - Sometimes, you'll chance upon something big, both literally and figuratively. Giant statues and functioning remnants of Precursor
|
||||
technology are just as exciting, to the right buyers. If your digging leaves a large boulder behind, dig into it normally and see if anything's hidden
|
||||
inside.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/mass_spectrometry
|
||||
name = "High power mass spectrometry, a comprehensive guide"
|
||||
icon_state = "analysis"
|
||||
author = "Winton Rice, Chief Mass Spectrometry Technician at the Institute of Applied Sciences on Arcadia"
|
||||
title = "High powered mass spectrometry, a comprehensive guide"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Terms">A note on terms</a></li>
|
||||
<li><a href="#Analysis">Analysis progression</a></li>
|
||||
<li><a href="#Heat">Heat management</a></li>
|
||||
<li><a href="#Radiation">Ambient radiation</a></li>
|
||||
</ol>
|
||||
|
||||
<br>
|
||||
<h1><a name="Terms">A note on terms</a></h1>
|
||||
<list>
|
||||
<li><b>Mass spectrometry</b> - MS is the procedure used used to measure and quantify the components of matter. The most prized tool in the field of
|
||||
'Materials analysis'</li>
|
||||
<li><b>Radiometric dating</b> - MS applied using the right carrier reagents can be used to accurately determine the age of a sample.</li>
|
||||
<li><b>Dissonance ratio</b> - This is a pseudoarbitrary value indicating the overal presence of a particular element in a greater composite.
|
||||
It takes into account volume, density, molecular excitation and isotope spread.</li>
|
||||
<li><b>Vacuum seal integrity</b> - A reference to how close an airtight seal is to failure.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Analysis">Analysis progression</a></h1>
|
||||
Modern mass spectrometry requires constant attention from the diligant researcher in order to be successul. There are many different elements to juggle,
|
||||
and later chapters will delve into them. For the spectrometry assistant, the first thing you need to know is that the scanner wavelength is automatically
|
||||
calculated for you. Just tweak the settings and try to match it with the actual wavelength as closely as possible.<br>
|
||||
<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Seal">Seal integrity</a></h1>
|
||||
In order to maintain sterile and environmentally static procedures, a special chamber is setup inside the spectrometer. It's protected by a proprietary vacuum seal
|
||||
produced by top tier industrial science. It will only last for a certain number of scans before failing outright, but it can be resealed through use of nanite paste.
|
||||
Unfortunately, it's susceptible to malforming under heat stress so exposing it to higher temperatures will cause it's operation life to drop significantly.<br>
|
||||
<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Heat">Heat management</a></h1>
|
||||
The scanner relies on a gyro-rotational system that varies in speed and intensity. Over the course of an ordinary scan, the RPMs can change dramatically. Higher RPMs
|
||||
means greater heat generation, but is necessary for the ongoing continuation of the scan. To offset heat production, spectrometers have an inbuilt cooling system.
|
||||
Researchers can modify the flow rate of coolant to aid in dropping temperature as necessary, but are advised that frequent coolant replacements may be necessary
|
||||
depending on coolant purity. Water and substances such as cryoxadone are viable substitutes, but nowhere near as effective as pure coolant itself.<br>
|
||||
<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Radiation">Ambient radiation</a></h1>
|
||||
Researchers are warned that while operational, mass spectrometers emit period bursts of radiation and are thus advised to wear protective gear. In the event of
|
||||
radiation spikes, there is also a special shield that can be lowered to block emissions. Lowering this, however, will have the effect of blocking the scanner
|
||||
so use it sparingly.<br>
|
||||
<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/anomaly_spectroscopy
|
||||
name = "Spectroscopy: Analysing the anomalies of the cosmos"
|
||||
icon_state = "anomaly"
|
||||
author = "Doctor Martin Boyle, Director Research at the Lower Hydrolian Sector Listening Array"
|
||||
title = "Spectroscopy: Analysing the anomalies of the cosmos"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
It's perhaps one of the most exciting times to be alive, with the recent breakthroughs in understanding and categorisation of things we may one day no longer call
|
||||
'anomalies,' but rather 'infrequent or rare occurrences of certain celestial weather or phenomena.' Perhaps a little more long winded, but no less eloquent all the
|
||||
same! Why, look at the strides we're making in piercing the walls of bluespace or our steadily improving ability to clarify and stabilise subspace emissions; it's
|
||||
certainly an exciting time to be alive. For the moment the Hydrolian hasn't seen two spatial anomalies alike but the day will come and it is soon, I can feel it.
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/materials_chemistry_analysis
|
||||
name = "Materials analysis and the chemical implications"
|
||||
icon_state = "chemistry"
|
||||
author = "Jasper Pascal, Senior Lecturer in Materials Analysis at the University of Jol'Nar"
|
||||
title = "Materials analysis and the chemical implications"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
In today's high tech research fields, leaps and bounds are being made every day. Whether it's great strides forward in our understanding of the physical universe
|
||||
or the operation of some fancy new piece of equipment, it seems like all the cool fields are producing new toys to play with leaving doddery old fields such as
|
||||
materials analysis and chemistry relegated to the previous few centuries, when we were still learning the makeup and structure of the elements.<br>
|
||||
<br>
|
||||
Well, when you're out there building the next gryo-whatsitron or isotope mobility thingummy, remember how the field of archaeology experienced a massive new rebirth
|
||||
following the excavations at Paranol IV and consider how all of the scientific greats will come crawling back to basic paradigms of natural philosophy when they discover
|
||||
a new element that defies classification. I defy you to classify it without reviving this once great field!
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/anomaly_testing
|
||||
name = "Anomalous materials and energies"
|
||||
icon_state = "triangulate"
|
||||
author = "Norman York, formerly of the Tyrolion Institute on Titan"
|
||||
title = "Anomalous materials and energies"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Anomalies">Forward: Modern attitude towards anomalies</a></li>
|
||||
<li><a href="#Tri">Triangulating anomalous energy readings</a></li>
|
||||
<li><a href="#Synthetic">Harvesting and utilising anomalous energy signatures</a></li>
|
||||
</ol>
|
||||
<br>
|
||||
<h1><a name="Anomalies">Modern attitude towards anomalies</a></h1>
|
||||
It's only when confronted with things we don't know, that we may push back our knowledge of the world around us. Nowhere is this more obvious than the
|
||||
vast and inscrutable mysterious of the cosmos that scholars from such august institutions as the Elysian Institute of the Sciences present
|
||||
formulas and hypotheses for every few decades.<br>
|
||||
<br>
|
||||
Using our vast telescopic array installations and deep space satellite networks, we are able to detect anomalous energy fields and formations in deep space,
|
||||
but are limited to those that are large enough to output energy that will stretch across light years worth of distance between stars.<br>
|
||||
<br>
|
||||
While some sectors (such as the Hydrolian Rift and Keppel's Run) are replete with inexplicable energetic activity and unique phenomena found nowhere else in
|
||||
the galaxy, the majority of space is dry, barren and cold - and if past experience has told us anything, it is that there are always more things we are
|
||||
unable to explain.<br>
|
||||
<br>
|
||||
Indeed, a great source of knowledge and technology has always been those who come before us, in the form of the multitudinous ancient alien precursors that
|
||||
have left scattered remnants of their great past all over settled (and unexplored) space.<br>
|
||||
<br>
|
||||
It is from xenoarchaeologists, high energy materials researchers and technology reconstruction authorities that we are able to theorise on the gifts these
|
||||
species have left behind, and in some cases even reverse engineer or rebuild the technology in question. My colleague Doctor Raymond Ward of the
|
||||
Tyrolian Institute on Titan has made great breakthroughs in a related field through his pioneering development of universally reflective materials capable
|
||||
of harvesting and 'bottling' up virtually any energy emissions yet encountered by spacefaring civilisations.<br>
|
||||
<br>
|
||||
And yet, there are some amongst us who do not see the benefits of those who have come before us - indeed, some among them profess the opinion that there
|
||||
is no species that could possibly match humanity in it's achievements and knowledge, or simply that employing non-human technology is dangerous and unethical.
|
||||
Folly, say I. If it is their desire to throw onto the wayside the greatest achievements <i>in the history of the galaxy</i>, simply for preferment of the
|
||||
greatest achievements <i>in the history of mankind</i>, then they have no business in the establishment of science.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Tri">Triangulating anomalous energy readings</a></h1>
|
||||
Strong energy emissions, when remaining constant from any one fixed location for millenia, can leave an 'imprint' or distinctive energy signature on other
|
||||
matter composites that are spatially fixed relative to the source.<br>
|
||||
<br>
|
||||
By taking samples of such 'fixed' matter, we can apply complex analytics such as the modified Fourier Transform Procedure to reverse engineer the path of the
|
||||
energy, and determine the approximate distance and direction that the energy source is, relative to the sample's point in space. Modern portable devices can do
|
||||
all this purely by taking readings of local radiation.<br>
|
||||
<br>
|
||||
A canny researcher can thusly analyse radiationat pre-chosen points strategically scattered around an area, and if there are any anomalous energy
|
||||
emissions in range of those points, combined the researcher can triangulate the source.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Synthetic">Harvesting and utilising anomalous energy signatures</a></h1>
|
||||
As mentioned in the forward, my colleague from the Tyrolian Institute on Saturn's moon of Titan, in the Sol System, Doctor Raymond Ward has made great strides
|
||||
in the area of harvesting and application of the energy emitted by anomalous phenomena from around the galaxy (although I profess I have not yet seen him
|
||||
venture further from his birthplace on Earth than the comfortable distance of the Sol Cis-Oort Satellite Sphere).<br>
|
||||
<br>
|
||||
By employing a patented semi-phased alloy with unique and fascinating bluespace interaction properties, Ward's contraption is able to 'harvest' energy, store
|
||||
it and redirect it later at will (with appropriate electronic mechanisms, of course). Although he professes to see or desire no commercial or material gain
|
||||
for the application and use of said energy once it is harvested, there are no doubt myriad ways we can come to benefit from such things beyond mere research,
|
||||
such as the reconstruction of torn cartiligenous tissue that a peculiar radiation from an amphibious species on Brachis IV was found to emit.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/stasis
|
||||
name = "Cellular suspension, the new Cryogenics?"
|
||||
icon_state = "stasis"
|
||||
author = "Elvin Schmidt"
|
||||
title = "Cellular suspension, the new Cryogenics?"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Forward">Forward: A replacement for cryosleep?</a></li>
|
||||
<li><a href="#Development">The breakthrough</a></li>
|
||||
<li><a href="#Application">Applying this new principle</a></li>
|
||||
</ol>
|
||||
<br>
|
||||
<h1><a name="Forward">Forward: A replacement for cryosleep?</a></h1>
|
||||
The development of rudimentary cryofreezing in the 20th and 21st centuries was hailed as a crank science by some, but many early visionaries recognised the
|
||||
potential it had to change the way we approach so many fields, such as medicine, therapeutics and space travel. It was breakthroughs in the field in the 22nd and
|
||||
later centures that turned the procedure from science fiction to science fact, however. Since then, cryogenics has become a hallmark of modern science, and
|
||||
regarded as one of the great achievements of our era. As with all sciences however, they have their time and are superseded by newer technological miracles when
|
||||
it is over.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Development">The breakthrough</a></h1>
|
||||
It was in examining the effects of decellerated, blue-space high energy particles when transphased through bluespace that the effects where primarily noticed.
|
||||
Due to exigent properties of that dimension, transphasing those particles capable of existing in bluespace with high stability levels has the effect of bringing
|
||||
some of those effects into realspace. Examining the Hoffman emissions in particular, it was discovered that they exhibited a-entropic behaviour, and in what is
|
||||
now termed the 'Effete Hoffman Principle,' it was found that metastabilising the Hoffman radiation resulted in the effect being applied across other physical
|
||||
interactions, in particular forces and reactions.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Application">Applying this new principle</a></h1>
|
||||
When combined with an appropriate energy-effect replicate for cryogenics (slowing down biological activity, thus stabilising the organics), the effect is
|
||||
effectively identical to cryogenics, and while it consumes vastly more power and requires extremely complex equipment, it's (for all intents and purposes) superior
|
||||
to cryogenics, all that remains is to 'commercialise' the process by enabling cheaper development and mass production.<br>
|
||||
The Effete Hoffman Principle can be tweak-combined with other effects however, for different purposes. A division of PMC Research initially developed the application
|
||||
in prisons as a literal 'suspension field' where convincts are held immobile in the air, and the use quickly spread to numerous other areas.<br>
|
||||
<br>
|
||||
By examining the material resonance properties of certain strong waveforms when combined with Hoffman radiation, an effect was produced able to reverse energy
|
||||
transferral through matter, and to slow the effects of gravity. When combined with energy repulse technology, the triple effects compound themselves into a much
|
||||
stronger field, although all three componenets do slightly different things. High energy researchers assure me of the following key points:<br>
|
||||
<ol>
|
||||
<li>The energy repulsion factor provides a 'shell' capable of weak suspension.</li>
|
||||
<li>The Hoffman emissions nullify energy transferral and other kinetic activity, maintaining stability inside the field.</li>
|
||||
<li>The resonant waveform combines the effects of the above two points, and applies it magnified onto it's synched 'resonance' materials.</li>
|
||||
</ol>
|
||||
As an interesting aside, a carbon waveform was chosen for the field in prison suspension fields, due to it's resonance with organic matter.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
@@ -0,0 +1,160 @@
|
||||
#define XENOARCH_SPAWN_CHANCE 0.5
|
||||
#define XENOARCH_SPREAD_CHANCE 15
|
||||
#define ARTIFACT_SPAWN_CHANCE 20
|
||||
|
||||
proc/SetupXenoarch()
|
||||
for(var/turf/simulated/mineral/M in block(locate(1,1,1), locate(world.maxx, world.maxy, world.maxz)))
|
||||
if(!M.geologic_data)
|
||||
M.geologic_data = new/datum/geosample(M)
|
||||
|
||||
if(!prob(XENOARCH_SPAWN_CHANCE))
|
||||
continue
|
||||
|
||||
var/digsite = get_random_digsite_type()
|
||||
var/list/processed_turfs = list()
|
||||
var/list/turfs_to_process = list(M)
|
||||
for(var/turf/simulated/mineral/archeo_turf in turfs_to_process)
|
||||
|
||||
for(var/turf/simulated/mineral/T in orange(1, archeo_turf))
|
||||
if(T.finds)
|
||||
continue
|
||||
if(T in processed_turfs)
|
||||
continue
|
||||
if(prob(XENOARCH_SPREAD_CHANCE))
|
||||
turfs_to_process.Add(T)
|
||||
|
||||
processed_turfs.Add(archeo_turf)
|
||||
if(!archeo_turf.finds)
|
||||
archeo_turf.finds = list()
|
||||
if(prob(50))
|
||||
archeo_turf.finds.Add(new /datum/find(digsite, rand(5,95)))
|
||||
else if(prob(75))
|
||||
archeo_turf.finds.Add(new /datum/find(digsite, rand(5,45)))
|
||||
archeo_turf.finds.Add(new /datum/find(digsite, rand(55,95)))
|
||||
else
|
||||
archeo_turf.finds.Add(new /datum/find(digsite, rand(5,30)))
|
||||
archeo_turf.finds.Add(new /datum/find(digsite, rand(35,75)))
|
||||
archeo_turf.finds.Add(new /datum/find(digsite, rand(75,95)))
|
||||
|
||||
//sometimes a find will be close enough to the surface to show
|
||||
var/datum/find/F = archeo_turf.finds[1]
|
||||
if(F.excavation_required <= F.view_range)
|
||||
archeo_turf.archaeo_overlay = "overlay_archaeo[rand(1,3)]"
|
||||
archeo_turf.overlays += archeo_turf.archaeo_overlay
|
||||
|
||||
//dont create artifact machinery in animal or plant digsites, or if we already have one
|
||||
if(!M.artifact_find && digsite != 1 && digsite != 2 && prob(ARTIFACT_SPAWN_CHANCE))
|
||||
M.artifact_find = new()
|
||||
artifact_spawn.Add(src)
|
||||
|
||||
|
||||
//---- Noticeboard
|
||||
|
||||
/obj/structure/noticeboard/anomaly
|
||||
notices = 5
|
||||
icon_state = "nboard05"
|
||||
|
||||
/obj/structure/noticeboard/anomaly/New()
|
||||
//add some memos
|
||||
var/obj/item/weapon/paper/P = new()
|
||||
P.name = "Memo RE: proper analysis procedure"
|
||||
P.info = "<br>We keep test dummies in pens here for a reason, so standard procedure should be to activate newfound alien artifacts and place the two in close proximity. Promising items I might even approve monkey testing on."
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "Memo RE: materials gathering"
|
||||
P.info = "Corasang,<br>the hands-on approach to gathering our samples may very well be slow at times, but it's safer than allowing the blundering miners to roll willy-nilly over our dig sites in their mechs, destroying everything in the process. And don't forget the escavation tools on your way out there!<br>- R.W"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "Memo RE: ethical quandaries"
|
||||
P.info = "Darion-<br><br>I don't care what his rank is, our business is that of science and knowledge - questions of moral application do not come into this. Sure, so there are those who would employ the energy-wave particles my modified device has managed to abscond for their own personal gain, but I can hardly see the practical benefits of some of these artifacts our benefactors left behind. Ward--"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "READ ME! Before you people destroy any more samples"
|
||||
P.info = "how many times do i have to tell you people, these xeno-arch samples are del-i-cate, and should be handled so! careful application of a focussed, concentrated heat or some corrosive liquids should clear away the extraneous carbon matter, while application of an energy beam will most decidedly destroy it entirely - like someone did to the chemical dispenser! W, <b>the one who signs your paychecks</b>"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "Reminder regarding the anomalous material suits"
|
||||
P.info = "Do you people think the anomaly suits are cheap to come by? I'm about a hair trigger away from instituting a log book for the damn things. Only wear them if you're going out for a dig, and for god's sake don't go tramping around in them unless you're field testing something, R"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
//---- Bookcase
|
||||
|
||||
/obj/structure/bookcase/manuals/xenoarchaeology
|
||||
name = "Xenoarchaeology Manuals bookcase"
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/book/manual/excavation(src)
|
||||
new /obj/item/weapon/book/manual/mass_spectrometry(src)
|
||||
new /obj/item/weapon/book/manual/materials_chemistry_analysis(src)
|
||||
new /obj/item/weapon/book/manual/anomaly_testing(src)
|
||||
new /obj/item/weapon/book/manual/anomaly_spectroscopy(src)
|
||||
new /obj/item/weapon/book/manual/stasis(src)
|
||||
update_icon()
|
||||
|
||||
//---- Lockers and closets
|
||||
|
||||
/obj/structure/closet/secure_closet/xenoarchaeologist
|
||||
name = "Xenoarchaeologist Locker"
|
||||
req_access = list(access_tox_storage)
|
||||
icon_state = "secureres1"
|
||||
icon_closed = "secureres"
|
||||
icon_locked = "secureres1"
|
||||
icon_opened = "secureresopen"
|
||||
icon_broken = "secureresbroken"
|
||||
icon_off = "secureresoff"
|
||||
|
||||
New()
|
||||
..()
|
||||
sleep(2)
|
||||
new /obj/item/clothing/under/rank/scientist(src)
|
||||
new /obj/item/clothing/suit/storage/labcoat(src)
|
||||
new /obj/item/clothing/shoes/white(src)
|
||||
new /obj/item/clothing/glasses/science(src)
|
||||
new /obj/item/device/radio/headset/headset_sci(src)
|
||||
new /obj/item/weapon/storage/belt/archaeology(src)
|
||||
new /obj/item/weapon/storage/box/excavation(src)
|
||||
return
|
||||
|
||||
/obj/structure/closet/excavation
|
||||
name = "Excavation tools"
|
||||
icon_state = "toolcloset"
|
||||
icon_closed = "toolcloset"
|
||||
icon_opened = "toolclosetopen"
|
||||
|
||||
New()
|
||||
..()
|
||||
sleep(2)
|
||||
new /obj/item/weapon/storage/belt/archaeology(src)
|
||||
new /obj/item/weapon/storage/box/excavation(src)
|
||||
new /obj/item/device/flashlight/lantern(src)
|
||||
new /obj/item/device/depth_scanner(src)
|
||||
new /obj/item/device/core_sampler(src)
|
||||
new /obj/item/device/gps(src)
|
||||
new /obj/item/device/beacon_locator(src)
|
||||
new /obj/item/device/radio/beacon(src)
|
||||
new /obj/item/clothing/glasses/meson(src)
|
||||
new /obj/item/weapon/pickaxe(src)
|
||||
new /obj/item/device/measuring_tape(src)
|
||||
new /obj/item/weapon/pickaxe/hand(src)
|
||||
return
|
||||
|
||||
//---- Isolation room air alarms
|
||||
|
||||
/obj/machinery/alarm/isolation
|
||||
name = "Isolation room air control"
|
||||
req_access = list(access_research)
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
//coming soon
|
||||
//there'll probably be some stuff on the wiki at some point
|
||||
|
||||
//original code from alfie275 / lunacode, artifacts are from isaidno
|
||||
@@ -0,0 +1,196 @@
|
||||
|
||||
/obj/item/weapon/anobattery
|
||||
name = "Anomaly power battery"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "anobattery0"
|
||||
var/datum/artifact_effect/battery_effect
|
||||
var/capacity = 200
|
||||
var/stored_charge = 0
|
||||
var/effect_id = ""
|
||||
|
||||
/obj/item/weapon/anobattery/New()
|
||||
battery_effect = new()
|
||||
|
||||
/obj/item/weapon/anobattery/proc/UpdateSprite()
|
||||
var/p = (stored_charge/capacity)*100
|
||||
p = min(p, 100)
|
||||
icon_state = "anobattery[round(p,25)]"
|
||||
|
||||
/obj/item/weapon/anodevice
|
||||
name = "Anomaly power utilizer"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "anodev"
|
||||
var/cooldown = 0
|
||||
var/activated = 0
|
||||
var/timing = 0
|
||||
var/time = 50
|
||||
var/archived_time = 50
|
||||
var/obj/item/weapon/anobattery/inserted_battery
|
||||
var/turf/archived_loc
|
||||
|
||||
/obj/item/weapon/anodevice/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
|
||||
/obj/item/weapon/anodevice/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/anobattery))
|
||||
if(!inserted_battery)
|
||||
user << "\blue You insert the battery."
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
inserted_battery = I
|
||||
UpdateSprite()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/anodevice/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
|
||||
/obj/item/weapon/anodevice/interact(var/mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = "<b>Anomalous Materials Energy Utiliser</b><br>"
|
||||
if(inserted_battery)
|
||||
if(cooldown)
|
||||
dat += "Cooldown in progress, please wait.<br>"
|
||||
else if(activated)
|
||||
if(timing)
|
||||
dat += "Device active.<br>"
|
||||
else
|
||||
dat += "Device active in timed mode.<br>"
|
||||
|
||||
dat += "[inserted_battery] inserted, anomaly ID: [inserted_battery.battery_effect.artifact_id ? inserted_battery.battery_effect.artifact_id : "NA"]<BR>"
|
||||
dat += "<b>Total Power:</b> [inserted_battery.stored_charge]/[inserted_battery.capacity]<BR><BR>"
|
||||
dat += "<b>Timed activation:</b> <A href='?src=\ref[src];neg_changetime_max=-100'>--</a> <A href='?src=\ref[src];neg_changetime=-10'>-</a> [time >= 1000 ? "[time/10]" : time >= 100 ? " [time/10]" : " [time/10]" ] <A href='?src=\ref[src];changetime=10'>+</a> <A href='?src=\ref[src];changetime_max=100'>++</a><BR>"
|
||||
if(cooldown)
|
||||
dat += "<font color=red>Cooldown in progress.</font><BR>"
|
||||
dat += "<br>"
|
||||
else if(!activated)
|
||||
dat += "<A href='?src=\ref[src];startup=1'>Start</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];startup=1;starttimer=1'>Start in timed mode</a><BR>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];shutdown=1'>Shutdown emission</a><br>"
|
||||
dat += "<br>"
|
||||
dat += "<A href='?src=\ref[src];ejectbattery=1'>Eject battery</a><BR>"
|
||||
else
|
||||
dat += "Please insert battery<br>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<hr>"
|
||||
dat += "<a href='?src=\ref[src]'>Refresh</a> <a href='?src=\ref[src];close=1'>Close</a>"
|
||||
|
||||
user << browse(dat, "window=anodevice;size=400x500")
|
||||
onclose(user, "anodevice")
|
||||
|
||||
/obj/item/weapon/anodevice/process()
|
||||
if(cooldown > 0)
|
||||
cooldown -= 1
|
||||
if(cooldown <= 0)
|
||||
cooldown = 0
|
||||
src.visible_message("\blue \icon[src] [src] chimes.", "\blue \icon[src] You hear something chime.")
|
||||
else if(activated)
|
||||
if(inserted_battery && inserted_battery.battery_effect)
|
||||
//make sure the effect is active
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
|
||||
//update the effect loc
|
||||
var/turf/T = get_turf(src)
|
||||
if(T != archived_loc)
|
||||
archived_loc = T
|
||||
inserted_battery.battery_effect.UpdateMove()
|
||||
|
||||
//process the effect
|
||||
inserted_battery.battery_effect.process()
|
||||
//if someone is holding the device, do the effect on them
|
||||
if(inserted_battery.battery_effect.effect == 0 && ismob(src.loc))
|
||||
inserted_battery.battery_effect.DoEffectTouch(src.loc)
|
||||
|
||||
//handle charge
|
||||
inserted_battery.stored_charge -= 1
|
||||
if(inserted_battery.stored_charge <= 0)
|
||||
shutdown_emission()
|
||||
|
||||
//handle timed mode
|
||||
if(timing)
|
||||
time -= 1
|
||||
if(time <= 0)
|
||||
shutdown_emission()
|
||||
else
|
||||
shutdown()
|
||||
|
||||
/obj/item/weapon/anodevice/proc/shutdown_emission()
|
||||
if(activated)
|
||||
activated = 0
|
||||
timing = 0
|
||||
src.visible_message("\blue \icon[src] [src] buzzes.", "\icon[src]\blue You hear something buzz.")
|
||||
|
||||
cooldown = archived_time / 2
|
||||
|
||||
if(inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
|
||||
/obj/item/weapon/anodevice/Topic(href, href_list)
|
||||
|
||||
if(href_list["neg_changetime_max"])
|
||||
time += -100
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["neg_changetime"])
|
||||
time += -10
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["changetime"])
|
||||
time += 10
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["changetime_max"])
|
||||
time += 100
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["startup"])
|
||||
activated = 1
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
if(href_list["shutdown"])
|
||||
activated = 0
|
||||
if(href_list["starttimer"])
|
||||
timing = 1
|
||||
archived_time = time
|
||||
if(href_list["ejectbattery"])
|
||||
shutdown_emission()
|
||||
inserted_battery.loc = get_turf(src)
|
||||
inserted_battery = null
|
||||
UpdateSprite()
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=anodevice")
|
||||
usr.unset_machine(src)
|
||||
|
||||
..()
|
||||
updateDialog()
|
||||
|
||||
/obj/item/weapon/anodevice/proc/UpdateSprite()
|
||||
if(!inserted_battery)
|
||||
icon_state = "anodev"
|
||||
return
|
||||
var/p = (inserted_battery.stored_charge/inserted_battery.capacity)*100
|
||||
p = min(p, 100)
|
||||
icon_state = "anodev[round(p,25)]"
|
||||
|
||||
/obj/item/weapon/anodevice/Del()
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
//changes: rad protection up to 100 from 20/50 respectively
|
||||
/obj/item/clothing/suit/bio_suit/anomaly
|
||||
name = "Anomaly suit"
|
||||
desc = "A sealed bio suit capable of insulating against exotic alien energies"
|
||||
icon_state = "engspace_suit"
|
||||
item_state = "engspace_suit"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
|
||||
/obj/item/clothing/head/bio_hood/anomaly
|
||||
name = "Anomaly hood"
|
||||
desc = "A sealed bio hood capable of insulating against exotic alien energies."
|
||||
icon_state = "engspace_helmet"
|
||||
item_state = "engspace_helmet"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
|
||||
/obj/item/clothing/suit/space/anomaly
|
||||
name = "Excavation suit"
|
||||
desc = "A pressure resistant excavation suit partially capable of insulating against exotic alien energies."
|
||||
icon_state = "cespace_suit"
|
||||
item_state = "cespace_suit"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/anomaly
|
||||
name = "Excavation hood"
|
||||
desc = "A pressure resistant excavation hood partially capable of insulating against exotic alien energies."
|
||||
icon_state = "cespace_helmet"
|
||||
item_state = "cespace_helmet"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
/obj/machinery/bunsen_burner
|
||||
name = "bunsen burner"
|
||||
desc = "A flat, self-heating device designed for bringing chemical mixtures to boil."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "bunsen0"
|
||||
var/heating = 0 //whether the bunsen is turned on
|
||||
var/heated = 0 //whether the bunsen has been on long enough to let stuff react
|
||||
var/obj/item/weapon/reagent_containers/held_container
|
||||
var/heat_time = 50
|
||||
|
||||
/obj/machinery/bunsen_burner/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/reagent_containers))
|
||||
if(held_container)
|
||||
user << "\red You must remove the [held_container] first."
|
||||
else
|
||||
user.drop_item(src)
|
||||
held_container = W
|
||||
held_container.loc = src
|
||||
user << "\blue You put the [held_container] onto the [src]."
|
||||
var/image/I = image("icon"=W, "layer"=FLOAT_LAYER)
|
||||
underlays += I
|
||||
if(heating)
|
||||
spawn(heat_time)
|
||||
try_heating()
|
||||
else
|
||||
user << "\red You can't put the [W] onto the [src]."
|
||||
|
||||
/obj/machinery/bunsen_burner/attack_hand(mob/user as mob)
|
||||
if(held_container)
|
||||
underlays = null
|
||||
user << "\blue You remove the [held_container] from the [src]."
|
||||
held_container.loc = src.loc
|
||||
held_container.attack_hand(user)
|
||||
held_container = null
|
||||
else
|
||||
user << "\red There is nothing on the [src]."
|
||||
|
||||
/obj/machinery/bunsen_burner/proc/try_heating()
|
||||
src.visible_message("\blue \icon[src] [src] hisses.")
|
||||
if(held_container && heating)
|
||||
heated = 1
|
||||
held_container.reagents.handle_reactions()
|
||||
heated = 0
|
||||
spawn(heat_time)
|
||||
try_heating()
|
||||
|
||||
/obj/machinery/bunsen_burner/verb/toggle()
|
||||
set src in view(1)
|
||||
set name = "Toggle bunsen burner"
|
||||
set category = "IC"
|
||||
|
||||
heating = !heating
|
||||
icon_state = "bunsen[heating]"
|
||||
if(heating)
|
||||
spawn(heat_time)
|
||||
try_heating()
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
/obj/item/weapon/storage/belt/archaeology
|
||||
name = "excavation gear-belt"
|
||||
desc = "Can hold various excavation gear."
|
||||
icon_state = "gearbelt"
|
||||
item_state = "utility"
|
||||
can_hold = list(
|
||||
"/obj/item/weapon/storage/box/samplebags",
|
||||
"/obj/item/device/core_sampler",
|
||||
"/obj/item/device/beacon_locator",
|
||||
"/obj/item/device/radio/beacon",
|
||||
"/obj/item/device/gps",
|
||||
"/obj/item/device/measuring_tape",
|
||||
"/obj/item/device/flashlight",
|
||||
"/obj/item/weapon/pickaxe",
|
||||
"/obj/item/device/depth_scanner",
|
||||
"/obj/item/device/camera",
|
||||
"/obj/item/weapon/paper",
|
||||
"/obj/item/weapon/photo",
|
||||
"/obj/item/weapon/folder",
|
||||
"/obj/item/weapon/pen",
|
||||
"/obj/item/weapon/folder",
|
||||
"/obj/item/weapon/clipboard",
|
||||
"/obj/item/weapon/anodevice",
|
||||
"/obj/item/clothing/glasses",
|
||||
"/obj/item/weapon/wrench",
|
||||
"/obj/item/weapon/storage/box/excavation",
|
||||
"/obj/item/weapon/anobattery")
|
||||
@@ -0,0 +1,337 @@
|
||||
/obj/machinery/suspension_gen
|
||||
name = "suspension field generator"
|
||||
desc = "It has stubby legs bolted up against it's body for stabilising."
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "suspension2"
|
||||
density = 1
|
||||
req_access = list(access_research)
|
||||
var/obj/item/weapon/cell/cell
|
||||
var/obj/item/weapon/card/id/auth_card
|
||||
var/locked = 1
|
||||
var/open = 0
|
||||
var/screwed = 1
|
||||
var/field_type = ""
|
||||
var/power_use = 25
|
||||
var/obj/effect/suspension_field/suspension_field
|
||||
var/list/secured_mobs = list()
|
||||
|
||||
/obj/machinery/suspension_gen/New()
|
||||
src.cell = new/obj/item/weapon/cell/high(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/suspension_gen/process()
|
||||
set background = 1
|
||||
|
||||
if (suspension_field)
|
||||
cell.charge -= power_use
|
||||
|
||||
var/turf/T = get_turf(suspension_field)
|
||||
if(field_type == "carbon")
|
||||
for(var/mob/living/carbon/M in T)
|
||||
M.weakened = max(M.weakened, 3)
|
||||
cell.charge -= power_use
|
||||
if(prob(5))
|
||||
M << "\blue [pick("You feel tingly.","You feel like floating.","It is hard to speak.","You can barely move.")]"
|
||||
|
||||
if(field_type == "iron")
|
||||
for(var/mob/living/silicon/M in T)
|
||||
M.weakened = max(M.weakened, 3)
|
||||
cell.charge -= power_use
|
||||
if(prob(5))
|
||||
M << "\blue [pick("You feel tingly.","You feel like floating.","It is hard to speak.","You can barely move.")]"
|
||||
|
||||
for(var/obj/item/I in T)
|
||||
if(!suspension_field.contents.len)
|
||||
suspension_field.icon_state = "energynet"
|
||||
suspension_field.overlays += "shield2"
|
||||
I.loc = suspension_field
|
||||
|
||||
for(var/mob/living/simple_animal/M in T)
|
||||
M.weakened = max(M.weakened, 3)
|
||||
cell.charge -= power_use
|
||||
if(prob(5))
|
||||
M << "\blue [pick("You feel tingly.","You feel like floating.","It is hard to speak.","You can barely move.")]"
|
||||
|
||||
if(cell.charge <= 0)
|
||||
deactivate()
|
||||
|
||||
/obj/machinery/suspension_gen/interact(mob/user as mob)
|
||||
var/dat = "<b>Multi-phase mobile suspension field generator MK II \"Steadfast\"</b><br>"
|
||||
if(cell)
|
||||
var/colour = "red"
|
||||
if(cell.charge / cell.maxcharge > 0.66)
|
||||
colour = "green"
|
||||
else if(cell.charge / cell.maxcharge > 0.33)
|
||||
colour = "orange"
|
||||
dat += "<b>Energy cell</b>: <font color='[colour]'>[100 * cell.charge / cell.maxcharge]%</font><br>"
|
||||
else
|
||||
dat += "<b>Energy cell</b>: None<br>"
|
||||
if(auth_card)
|
||||
dat += "<A href='?src=\ref[src];ejectcard=1'>\[[auth_card]\]<a><br>"
|
||||
if(!locked)
|
||||
dat += "<b><A href='?src=\ref[src];toggle_field=1'>[suspension_field ? "Disable" : "Enable"] field</a></b><br>"
|
||||
else
|
||||
dat += "<br>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];insertcard=1'>\[------\]<a><br>"
|
||||
if(!locked)
|
||||
dat += "<b><A href='?src=\ref[src];toggle_field=1'>[suspension_field ? "Disable" : "Enable"] field</a></b><br>"
|
||||
else
|
||||
dat += "Enter your ID to begin.<br>"
|
||||
|
||||
dat += "<hr>"
|
||||
if(!locked)
|
||||
dat += "<b>Select field mode</b><br>"
|
||||
dat += "[field_type=="carbon"?"<b>":"" ]<A href='?src=\ref[src];select_field=carbon'>Diffracted carbon dioxide laser</A></b><br>"
|
||||
dat += "[field_type=="nitrogen"?"<b>":"" ]<A href='?src=\ref[src];select_field=nitrogen'>Nitrogen tracer field</A></b><br>"
|
||||
dat += "[field_type=="potassium"?"<b>":"" ]<A href='?src=\ref[src];select_field=potassium'>Potassium refrigerant cloud</A></b><br>"
|
||||
dat += "[field_type=="mercury"?"<b>":"" ]<A href='?src=\ref[src];select_field=mercury'>Mercury dispersion wave</A></b><br>"
|
||||
dat += "[field_type=="iron"?"<b>":"" ]<A href='?src=\ref[src];select_field=iron'>Iron wafer conduction field</A></b><br>"
|
||||
dat += "[field_type=="calcium"?"<b>":"" ]<A href='?src=\ref[src];select_field=calcium'>Calcium binary deoxidiser</A></b><br>"
|
||||
dat += "[field_type=="plasma"?"<b>":"" ]<A href='?src=\ref[src];select_field=chlorine'>Chlorine diffusion emissions</A></b><br>"
|
||||
dat += "[field_type=="plasma"?"<b>":"" ]<A href='?src=\ref[src];select_field=plasma'>Plasma saturated field</A></b><br>"
|
||||
else
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<hr>"
|
||||
dat += "<font color='blue'><b>Always wear safety gear and consult a field manual before operation.</b></font><br>"
|
||||
if(!locked)
|
||||
dat += "<A href='?src=\ref[src];lock=1'>Lock console</A><br>"
|
||||
else
|
||||
dat += "<br>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh console</A><br>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close console</A>"
|
||||
user << browse(dat, "window=suspension;size=500x400")
|
||||
onclose(user, "suspension")
|
||||
|
||||
/obj/machinery/suspension_gen/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["toggle_field"])
|
||||
if(!suspension_field)
|
||||
if(cell.charge > 0)
|
||||
if(anchored)
|
||||
activate()
|
||||
else
|
||||
usr << "<span class='warning'>You are unable to activate [src] until it is properly secured on the ground.</span>"
|
||||
else
|
||||
deactivate()
|
||||
if(href_list["select_field"])
|
||||
field_type = href_list["select_field"]
|
||||
else if(href_list["insertcard"])
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if (istype(I, /obj/item/weapon/card))
|
||||
usr.drop_item()
|
||||
I.loc = src
|
||||
auth_card = I
|
||||
if(attempt_unlock(I))
|
||||
usr << "<span class='info'>You insert [I], the console flashes \'<i>Access granted.</a>\'</span>"
|
||||
else
|
||||
usr << "<span class='warning'>You insert [I], the console flashes \'<i>Access denied.</a>\'</span>"
|
||||
else if(href_list["ejectcard"])
|
||||
if(auth_card)
|
||||
if(ishuman(usr))
|
||||
auth_card.loc = usr.loc
|
||||
if(!usr.get_active_hand())
|
||||
usr.put_in_hands(auth_card)
|
||||
auth_card = null
|
||||
else
|
||||
auth_card.loc = loc
|
||||
auth_card = null
|
||||
else if(href_list["lock"])
|
||||
locked = 1
|
||||
else if(href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=suspension")
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/suspension_gen/attack_hand(mob/user as mob)
|
||||
if(!open)
|
||||
interact(user)
|
||||
else if(cell)
|
||||
cell.loc = loc
|
||||
cell.add_fingerprint(user)
|
||||
cell.updateicon()
|
||||
|
||||
icon_state = "suspension0"
|
||||
cell = null
|
||||
user << "<span class='info'>You remove the power cell</span>"
|
||||
|
||||
/obj/machinery/suspension_gen/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/weapon/screwdriver))
|
||||
if(!open)
|
||||
if(screwed)
|
||||
screwed = 0
|
||||
else
|
||||
screwed = 1
|
||||
user << "<span class='info'>You [screwed ? "screw" : "unscrew"] the battery panel.</span>"
|
||||
else if (istype(W, /obj/item/weapon/crowbar))
|
||||
if(!locked)
|
||||
if(!screwed)
|
||||
if(!suspension_field)
|
||||
if(open)
|
||||
open = 0
|
||||
else
|
||||
open = 1
|
||||
user << "<span class='info'>You crowbar the battery panel [open ? "open" : "in place"].</span>"
|
||||
icon_state = "suspension[open ? (cell ? "1" : "0") : "2"]"
|
||||
else
|
||||
user << "<span class='warning'>[src]'s safety locks are engaged, shut it down first.</span>"
|
||||
else
|
||||
user << "<span class='warning'>Unscrew [src]'s battery panel first.</span>"
|
||||
else
|
||||
user << "<span class='warning'>[src]'s security locks are engaged.</span>"
|
||||
else if (istype(W, /obj/item/weapon/wrench))
|
||||
if(!suspension_field)
|
||||
if(anchored)
|
||||
anchored = 0
|
||||
else
|
||||
anchored = 1
|
||||
user << "<span class='info'>You wrench the stabilising legs [anchored ? "into place" : "up against the body"].</span>"
|
||||
if(anchored)
|
||||
desc = "It is resting securely on four stubby legs."
|
||||
else
|
||||
desc = "It has stubby legs bolted up against it's body for stabilising."
|
||||
else
|
||||
user << "<span class='warning'>You are unable to secure [src] while it is active!</span>"
|
||||
else if (istype(W, /obj/item/weapon/cell))
|
||||
if(open)
|
||||
if(cell)
|
||||
user << "<span class='warning'>There is a power cell already installed.</span>"
|
||||
else
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
cell = W
|
||||
user << "<span class='info'>You insert the power cell.</span>"
|
||||
icon_state = "suspension1"
|
||||
else if(istype(W, /obj/item/weapon/card))
|
||||
var/obj/item/weapon/card/I = W
|
||||
if(!auth_card)
|
||||
if(attempt_unlock(I))
|
||||
user << "<span class='info'>You swipe [I], the console flashes \'<i>Access granted.</i>\'</span>"
|
||||
else
|
||||
user << "<span class='warning'>You swipe [I], console flashes \'<i>Access denied.</i>\'</span>"
|
||||
else
|
||||
user << "<span class='warning'>Remove [auth_card] first.</span>"
|
||||
|
||||
/obj/machinery/suspension_gen/proc/attempt_unlock(var/obj/item/weapon/card/C)
|
||||
if(!open)
|
||||
if(istype(C, /obj/item/weapon/card/emag) && cell.charge > 0)
|
||||
//put sparks here
|
||||
if(prob(95))
|
||||
locked = 0
|
||||
else if(istype(C, /obj/item/weapon/card/id) && check_access(C))
|
||||
locked = 0
|
||||
|
||||
if(!locked)
|
||||
return 1
|
||||
|
||||
//checks for whether the machine can be activated or not should already have occurred by this point
|
||||
/obj/machinery/suspension_gen/proc/activate()
|
||||
//depending on the field type, we might pickup certain items
|
||||
var/turf/T = get_turf(get_step(src,dir))
|
||||
var/success = 0
|
||||
var/collected = 0
|
||||
switch(field_type)
|
||||
if("carbon")
|
||||
success = 1
|
||||
for(var/mob/living/carbon/C in T)
|
||||
C.weakened += 5
|
||||
C.visible_message("\blue \icon[C] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.")
|
||||
if("nitrogen")
|
||||
success = 1
|
||||
//
|
||||
if("mercury")
|
||||
success = 1
|
||||
//
|
||||
if("chlorine")
|
||||
success = 1
|
||||
//
|
||||
if("potassium")
|
||||
success = 1
|
||||
//
|
||||
if("plasma")
|
||||
success = 1
|
||||
//
|
||||
if("calcium")
|
||||
success = 1
|
||||
//
|
||||
if("iron")
|
||||
success = 1
|
||||
for(var/mob/living/silicon/R in T)
|
||||
R.weakened += 5
|
||||
R.visible_message("\blue \icon[R] [R] begins to float in the air!","You feel tingly and light, but it is difficult to move.")
|
||||
//
|
||||
//in case we have a bad field type
|
||||
if(!success)
|
||||
return
|
||||
|
||||
for(var/mob/living/simple_animal/C in T)
|
||||
C.visible_message("\blue \icon[C] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.")
|
||||
C.weakened += 5
|
||||
|
||||
suspension_field = new(T)
|
||||
suspension_field.field_type = field_type
|
||||
src.visible_message("\blue \icon[src] [src] activates with a low hum.")
|
||||
icon_state = "suspension3"
|
||||
|
||||
for(var/obj/item/I in T)
|
||||
I.loc = suspension_field
|
||||
collected++
|
||||
|
||||
if(collected)
|
||||
suspension_field.icon_state = "energynet"
|
||||
suspension_field.overlays += "shield2"
|
||||
src.visible_message("\blue \icon[suspension_field] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].")
|
||||
else
|
||||
if(istype(T,/turf/simulated/mineral) || istype(T,/turf/simulated/wall))
|
||||
suspension_field.icon_state = "shieldsparkles"
|
||||
else
|
||||
suspension_field.icon_state = "shield2"
|
||||
|
||||
/obj/machinery/suspension_gen/proc/deactivate()
|
||||
//drop anything we picked up
|
||||
var/turf/T = get_turf(suspension_field)
|
||||
|
||||
for(var/mob/M in T)
|
||||
M << "<span class='info'>You no longer feel like floating.</span>"
|
||||
M.weakened = min(M.weakened, 3)
|
||||
|
||||
src.visible_message("\blue \icon[src] [src] deactivates with a gentle shudder.")
|
||||
del(suspension_field)
|
||||
icon_state = "suspension2"
|
||||
|
||||
/obj/machinery/suspension_gen/Del()
|
||||
//safety checks: clear the field and drop anything it's holding
|
||||
deactivate()
|
||||
..()
|
||||
|
||||
/obj/machinery/suspension_gen/verb/toggle()
|
||||
set src in view(1)
|
||||
set name = "Rotate suspension gen (clockwise)"
|
||||
set category = "IC"
|
||||
|
||||
if(anchored)
|
||||
usr << "\red You cannot rotate [src], it has been firmly fixed to the floor."
|
||||
else
|
||||
dir = turn(dir, 90)
|
||||
|
||||
/obj/effect/suspension_field
|
||||
name = "energy field"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/field_type = "chlorine"
|
||||
|
||||
/obj/effect/suspension_field/Del()
|
||||
for(var/obj/I in src)
|
||||
I.loc = src.loc
|
||||
..()
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Miscellaneous xenoarchaeology tools
|
||||
|
||||
/obj/item/device/gps
|
||||
name = "relay positioning device"
|
||||
desc = "Triangulates the approximate co-ordinates using a nearby satellite network."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "locator"
|
||||
item_state = "locator"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/device/gps/attack_self(var/mob/user as mob)
|
||||
var/turf/T = get_turf(src)
|
||||
user << "\blue \icon[src] [src] flashes <i>[T.x].[rand(0,9)]:[T.y].[rand(0,9)]:[T.z].[rand(0,9)]</i>."
|
||||
|
||||
/obj/item/device/measuring_tape
|
||||
name = "measuring tape"
|
||||
desc = "A coiled metallic tape used to check dimensions and lengths."
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "measuring"
|
||||
w_class = 2
|
||||
|
||||
//todo: dig site tape
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
/obj/item/device/ano_scanner
|
||||
name = "Alden-Saraspova counter"
|
||||
desc = "Aids in triangulation of exotic particles."
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "flashgun"
|
||||
item_state = "lampgreen"
|
||||
w_class = 1.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
var/nearest_artifact_id = "unknown"
|
||||
var/nearest_artifact_distance = -1
|
||||
var/last_scan_time = 0
|
||||
var/scan_delay = 25
|
||||
|
||||
/obj/item/device/ano_scanner/New()
|
||||
..()
|
||||
spawn(0)
|
||||
scan()
|
||||
|
||||
/obj/item/device/ano_scanner/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
|
||||
/obj/item/device/ano_scanner/interact(var/mob/user as mob)
|
||||
var/message = "Background radiation levels detected."
|
||||
if(nearest_artifact_distance >= 0)
|
||||
message = "Exotic energy detected on wavelength '[nearest_artifact_id]' in a radius of [nearest_artifact_distance]m"
|
||||
user << "<span class='info'>[message]</span>"
|
||||
if(world.time - last_scan_time >= scan_delay)
|
||||
spawn(0)
|
||||
scan()
|
||||
|
||||
/obj/item/device/ano_scanner/proc/scan()
|
||||
set background = 1
|
||||
|
||||
last_scan_time = world.time
|
||||
nearest_artifact_distance = -1
|
||||
var/turf/cur_turf = get_turf(src)
|
||||
if(master_controller) //Sanity check due to runtimes ~Z
|
||||
for(var/turf/simulated/mineral/T in master_controller.artifact_spawning_turfs)
|
||||
if(T.artifact_find)
|
||||
if(T.z == cur_turf.z)
|
||||
var/cur_dist = get_dist(cur_turf, T) * 2
|
||||
if( (nearest_artifact_distance < 0 || cur_dist < nearest_artifact_distance) && cur_dist <= T.artifact_find.artifact_detect_range )
|
||||
nearest_artifact_distance = cur_dist + rand() * 2 - 1
|
||||
nearest_artifact_id = T.artifact_find.artifact_id
|
||||
else
|
||||
master_controller.artifact_spawning_turfs.Remove(T)
|
||||
cur_turf.visible_message("<span class='info'>[src] clicks.</span>")
|
||||
@@ -0,0 +1,101 @@
|
||||
//device to take core samples from mineral turfs - used for various types of analysis
|
||||
|
||||
/obj/item/weapon/storage/box/samplebags
|
||||
name = "sample bag box"
|
||||
desc = "A box claiming to contain sample bags."
|
||||
New()
|
||||
for(var/i=0, i<7, i++)
|
||||
var/obj/item/weapon/evidencebag/S = new(src)
|
||||
S.name = "sample bag"
|
||||
S.desc = "a bag for holding research samples."
|
||||
..()
|
||||
return
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/device/core_sampler
|
||||
name = "core sampler"
|
||||
desc = "Used to extract geological core samples."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "sampler0"
|
||||
item_state = "screwdriver_brown"
|
||||
w_class = 1.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
//slot_flags = SLOT_BELT
|
||||
var/sampled_turf = ""
|
||||
var/num_stored_bags = 10
|
||||
var/obj/item/weapon/evidencebag/filled_bag
|
||||
|
||||
/obj/item/device/core_sampler/examine()
|
||||
set src in orange(1)
|
||||
if (!( usr ))
|
||||
return
|
||||
if(get_dist(src, usr) < 2)
|
||||
usr << "That's \a [src]."
|
||||
usr << "\blue Used to extract geological core samples - this one is [sampled_turf ? "full" : "empty"], and has [num_stored_bags] bag[num_stored_bags != 1 ? "s" : ""] remaining."
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/core_sampler/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/evidencebag))
|
||||
if(num_stored_bags < 10)
|
||||
del(W)
|
||||
num_stored_bags += 1
|
||||
user << "\blue You insert the [W] into the core sampler."
|
||||
else
|
||||
user << "\red The core sampler can not fit any more bags!"
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/core_sampler/proc/sample_item(var/item_to_sample, var/mob/user as mob)
|
||||
var/datum/geosample/geo_data
|
||||
if(istype(item_to_sample, /turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/T = item_to_sample
|
||||
T.geologic_data.UpdateNearbyArtifactInfo(T)
|
||||
geo_data = T.geologic_data
|
||||
else if(istype(item_to_sample, /obj/item/weapon/ore))
|
||||
var/obj/item/weapon/ore/O = item_to_sample
|
||||
geo_data = O.geologic_data
|
||||
|
||||
if(geo_data)
|
||||
if(filled_bag)
|
||||
user << "\red The core sampler is full!"
|
||||
else if(num_stored_bags < 1)
|
||||
user << "\red The core sampler is out of sample bags!"
|
||||
else
|
||||
//create a new sample bag which we'll fill with rock samples
|
||||
filled_bag = new /obj/item/weapon/evidencebag(src)
|
||||
filled_bag.name = "sample bag"
|
||||
filled_bag.desc = "a bag for holding research samples."
|
||||
|
||||
icon_state = "sampler1"
|
||||
num_stored_bags--
|
||||
|
||||
//put in a rock sliver
|
||||
var/obj/item/weapon/rocksliver/R = new()
|
||||
R.geological_data = geo_data
|
||||
R.loc = filled_bag
|
||||
|
||||
//update the sample bag
|
||||
filled_bag.icon_state = "evidence"
|
||||
var/image/I = image("icon"=R, "layer"=FLOAT_LAYER)
|
||||
filled_bag.underlays += I
|
||||
filled_bag.w_class = 1
|
||||
|
||||
user << "\blue You take a core sample of the [item_to_sample]."
|
||||
else
|
||||
user << "\red You are unable to take a sample of [item_to_sample]."
|
||||
|
||||
/obj/item/device/core_sampler/attack_self()
|
||||
if(filled_bag)
|
||||
usr << "\blue You eject the full sample bag."
|
||||
var/success = 0
|
||||
if(istype(src.loc, /mob))
|
||||
var/mob/M = src.loc
|
||||
success = M.put_in_inactive_hand(filled_bag)
|
||||
if(!success)
|
||||
filled_bag.loc = get_turf(src)
|
||||
filled_bag = null
|
||||
icon_state = "sampler0"
|
||||
else
|
||||
usr << "\red The core sampler is empty."
|
||||
@@ -0,0 +1,131 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Depth scanner - scans rock turfs / boulders and tells players if there is anything interesting inside, logs all finds + coordinates + times
|
||||
|
||||
//also known as the x-ray diffractor
|
||||
/obj/item/device/depth_scanner
|
||||
name = "depth analysis scanner"
|
||||
desc = "Used to check spatial depth and density of rock outcroppings."
|
||||
icon = 'icons/obj/pda.dmi'
|
||||
icon_state = "crap"
|
||||
item_state = "analyzer"
|
||||
w_class = 1.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
var/list/positive_locations = list()
|
||||
var/datum/depth_scan/current
|
||||
|
||||
/datum/depth_scan
|
||||
var/time = ""
|
||||
var/coords = ""
|
||||
var/depth = 0
|
||||
var/clearance = 0
|
||||
var/record_index = 1
|
||||
var/dissonance_spread = 1
|
||||
var/material = "unknown"
|
||||
|
||||
/obj/item/device/depth_scanner/proc/scan_atom(var/mob/user, var/atom/A)
|
||||
user.visible_message("\blue [user] scans [A], the air around them humming gently.")
|
||||
if(istype(A,/turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/M = A
|
||||
if(M.finds.len || M.artifact_find)
|
||||
|
||||
//create a new scanlog entry
|
||||
var/datum/depth_scan/D = new()
|
||||
D.coords = "[M.x].[rand(0,9)]:[M.y].[rand(0,9)]:[10 * M.z].[rand(0,9)]"
|
||||
D.time = worldtime2text()
|
||||
D.record_index = positive_locations.len + 1
|
||||
D.material = M.mineral ? M.mineral.display_name : "Rock"
|
||||
|
||||
//find the first artifact and store it
|
||||
if(M.finds.len)
|
||||
var/datum/find/F = M.finds[1]
|
||||
D.depth = F.excavation_required * 2 //0-100% and 0-200cm
|
||||
D.clearance = F.clearance_range * 2
|
||||
D.material = get_responsive_reagent(F.find_type)
|
||||
|
||||
positive_locations.Add(D)
|
||||
|
||||
for(var/mob/L in range(src, 1))
|
||||
L << "\blue \icon[src] [src] pings."
|
||||
|
||||
else if(istype(A,/obj/structure/boulder))
|
||||
var/obj/structure/boulder/B = A
|
||||
if(B.artifact_find)
|
||||
//create a new scanlog entry
|
||||
var/datum/depth_scan/D = new()
|
||||
D.coords = "[10 * B.x].[rand(0,9)]:[10 * B.y].[rand(0,9)]:[10 * B.z].[rand(0,9)]"
|
||||
D.time = worldtime2text()
|
||||
D.record_index = positive_locations.len + 1
|
||||
|
||||
//these values are arbitrary
|
||||
D.depth = rand(75,100)
|
||||
D.clearance = rand(5,25)
|
||||
D.dissonance_spread = rand(750,2500) / 100
|
||||
|
||||
positive_locations.Add(D)
|
||||
|
||||
for(var/mob/L in range(src, 1))
|
||||
L << "\blue \icon[src] [src] pings [pick("madly","wildly","excitedly","crazily")]!."
|
||||
|
||||
/obj/item/device/depth_scanner/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
|
||||
/obj/item/device/depth_scanner/interact(var/mob/user as mob)
|
||||
var/dat = "<b>Co-ordinates with positive matches</b><br>"
|
||||
dat += "<A href='?src=\ref[src];clear=0'>== Clear all ==</a><br>"
|
||||
if(current)
|
||||
dat += "Time: [current.time]<br>"
|
||||
dat += "Coords: [current.coords]<br>"
|
||||
dat += "Anomaly depth: [current.depth] cm<br>"
|
||||
dat += "Clearance above anomaly depth: [current.clearance] cm<br>"
|
||||
dat += "Dissonance spread: [current.dissonance_spread]<br>"
|
||||
var/index = responsive_carriers.Find(current.material)
|
||||
if(index > 0 && index <= finds_as_strings.len)
|
||||
dat += "Anomaly material: [finds_as_strings[index]]<br>"
|
||||
else
|
||||
dat += "Anomaly material: Unknown<br>"
|
||||
dat += "<A href='?src=\ref[src];clear=[current.record_index]'>clear entry</a><br>"
|
||||
else
|
||||
dat += "Select an entry from the list<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<hr>"
|
||||
if(positive_locations.len)
|
||||
for(var/index=1, index<=positive_locations.len, index++)
|
||||
var/datum/depth_scan/D = positive_locations[index]
|
||||
dat += "<A href='?src=\ref[src];select=[index]'>[D.time], coords: [D.coords]</a><br>"
|
||||
else
|
||||
dat += "No entries recorded."
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</a><br>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close</a><br>"
|
||||
user << browse(dat,"window=depth_scanner;size=300x500")
|
||||
onclose(user, "depth_scanner")
|
||||
|
||||
/obj/item/device/depth_scanner/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["select"])
|
||||
var/index = text2num(href_list["select"])
|
||||
if(index && index <= positive_locations.len)
|
||||
current = positive_locations[index]
|
||||
else if(href_list["clear"])
|
||||
var/index = text2num(href_list["clear"])
|
||||
if(index)
|
||||
if(index <= positive_locations.len)
|
||||
var/datum/depth_scan/D = positive_locations[index]
|
||||
positive_locations.Remove(D)
|
||||
del(D)
|
||||
else
|
||||
//GC will hopefully pick them up before too long
|
||||
positive_locations = list()
|
||||
del(current)
|
||||
else if(href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=depth_scanner")
|
||||
|
||||
updateSelfDialog()
|
||||
@@ -0,0 +1,97 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GPS Locater - locks into a radio frequency and tracks it
|
||||
|
||||
/obj/item/device/beacon_locator
|
||||
name = "locater device"
|
||||
desc = "Used to scan and locate signals on a particular frequency according ."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinoff" //pinonfar, pinonmedium, pinonclose, pinondirect, pinonnull
|
||||
item_state = "electronic"
|
||||
var/frequency = 1459
|
||||
var/scan_ticks = 0
|
||||
var/obj/item/device/radio/target_radio
|
||||
|
||||
/obj/item/device/beacon_locator/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
|
||||
/obj/item/device/beacon_locator/Del()
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/item/device/beacon_locator/process()
|
||||
if(target_radio)
|
||||
dir = get_dir(src,target_radio)
|
||||
switch(get_dist(src,target_radio))
|
||||
if(0 to 3)
|
||||
icon_state = "pinondirect"
|
||||
if(4 to 10)
|
||||
icon_state = "pinonclose"
|
||||
if(11 to 30)
|
||||
icon_state = "pinonmedium"
|
||||
if(31 to INFINITY)
|
||||
icon_state = "pinonfar"
|
||||
else
|
||||
if(scan_ticks)
|
||||
icon_state = "pinonnull"
|
||||
scan_ticks++
|
||||
if(prob(scan_ticks * 10))
|
||||
spawn(0)
|
||||
set background = 1
|
||||
if(processing_objects.Find(src))
|
||||
//scan radios in the world to try and find one
|
||||
var/cur_dist = 999
|
||||
for(var/obj/item/device/radio/beacon/R in world)
|
||||
if(R.z == src.z && R.frequency == src.frequency)
|
||||
var/check_dist = get_dist(src,R)
|
||||
if(check_dist < cur_dist)
|
||||
cur_dist = check_dist
|
||||
target_radio = R
|
||||
|
||||
scan_ticks = 0
|
||||
var/turf/T = get_turf(src)
|
||||
if(target_radio)
|
||||
T.visible_message("\icon[src] [src] [pick("chirps","chirrups","cheeps")] happily.")
|
||||
else
|
||||
T.visible_message("\icon[src] [src] [pick("chirps","chirrups","cheeps")] sadly.")
|
||||
else
|
||||
icon_state = "pinoff"
|
||||
|
||||
/obj/item/device/beacon_locator/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
|
||||
/obj/item/device/beacon_locator/interact(var/mob/user as mob)
|
||||
var/dat = "<b>Radio frequency tracker</b><br>"
|
||||
dat += {"
|
||||
<A href='byond://?src=\ref[src];reset_tracking=1'>Reset tracker</A><BR>
|
||||
Frequency:
|
||||
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
||||
<A href='byond://?src=\ref[src];freq=-2'>-</A>
|
||||
[format_frequency(frequency)]
|
||||
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
||||
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
||||
"}
|
||||
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close</a><br>"
|
||||
user << browse(dat,"window=locater;size=300x150")
|
||||
onclose(user, "locater")
|
||||
|
||||
/obj/item/device/beacon_locator/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["reset_tracking"])
|
||||
scan_ticks = 1
|
||||
target_radio = null
|
||||
else if(href_list["freq"])
|
||||
var/new_frequency = (frequency + text2num(href_list["freq"]))
|
||||
if (frequency < 1200 || frequency > 1600)
|
||||
new_frequency = sanitize_frequency(new_frequency, 1499)
|
||||
frequency = new_frequency
|
||||
|
||||
else if(href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=locater")
|
||||
|
||||
updateSelfDialog()
|
||||
@@ -0,0 +1,132 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Excavation pickaxes - sorted in order of delicacy. Players will have to choose the right one for each part of excavation.
|
||||
|
||||
/obj/item/weapon/pickaxe/brush
|
||||
name = "brush"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "pick_brush"
|
||||
item_state = "syringe_0"
|
||||
digspeed = 20
|
||||
desc = "Thick metallic wires for clearing away dust and loose scree (1 centimetre excavation depth)."
|
||||
excavation_amount = 0.5
|
||||
drill_sound = 'sound/weapons/thudswoosh.ogg'
|
||||
drill_verb = "brushing"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/weapon/pickaxe/one_pick
|
||||
name = "1/6 pick"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "pick1"
|
||||
item_state = "syringe_0"
|
||||
digspeed = 20
|
||||
desc = "A miniature excavation tool for precise digging (2 centimetre excavation depth)."
|
||||
excavation_amount = 1
|
||||
drill_sound = 'sound/items/Screwdriver.ogg'
|
||||
drill_verb = "delicately picking"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/weapon/pickaxe/two_pick
|
||||
name = "1/3 pick"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "pick2"
|
||||
item_state = "syringe_0"
|
||||
digspeed = 20
|
||||
desc = "A miniature excavation tool for precise digging (4 centimetre excavation depth)."
|
||||
excavation_amount = 2
|
||||
drill_sound = 'sound/items/Screwdriver.ogg'
|
||||
drill_verb = "delicately picking"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/weapon/pickaxe/three_pick
|
||||
name = "1/2 pick"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "pick3"
|
||||
item_state = "syringe_0"
|
||||
digspeed = 20
|
||||
desc = "A miniature excavation tool for precise digging (6 centimetre excavation depth)."
|
||||
excavation_amount = 3
|
||||
drill_sound = 'sound/items/Screwdriver.ogg'
|
||||
drill_verb = "delicately picking"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/weapon/pickaxe/four_pick
|
||||
name = "2/3 pick"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "pick4"
|
||||
item_state = "syringe_0"
|
||||
digspeed = 20
|
||||
desc = "A miniature excavation tool for precise digging (8 centimetre excavation depth)."
|
||||
excavation_amount = 4
|
||||
drill_sound = 'sound/items/Screwdriver.ogg'
|
||||
drill_verb = "delicately picking"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/weapon/pickaxe/five_pick
|
||||
name = "5/6 pick"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "pick5"
|
||||
item_state = "syringe_0"
|
||||
digspeed = 20
|
||||
desc = "A miniature excavation tool for precise digging (10 centimetre excavation depth)."
|
||||
excavation_amount = 5
|
||||
drill_sound = 'sound/items/Screwdriver.ogg'
|
||||
drill_verb = "delicately picking"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/weapon/pickaxe/six_pick
|
||||
name = "1/1 pick"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "pick6"
|
||||
item_state = "syringe_0"
|
||||
digspeed = 20
|
||||
desc = "A miniature excavation tool for precise digging (12 centimetre excavation depth)."
|
||||
excavation_amount = 6
|
||||
drill_sound = 'sound/items/Screwdriver.ogg'
|
||||
drill_verb = "delicately picking"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/weapon/pickaxe/hand
|
||||
name = "hand pickaxe"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "pick_hand"
|
||||
item_state = "syringe_0"
|
||||
digspeed = 30
|
||||
desc = "A smaller, more precise version of the pickaxe (30 centimetre excavation depth)."
|
||||
excavation_amount = 15
|
||||
drill_sound = 'sound/items/Crowbar.ogg'
|
||||
drill_verb = "clearing"
|
||||
w_class = 3
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Pack for holding pickaxes
|
||||
|
||||
/obj/item/weapon/storage/box/excavation
|
||||
name = "excavation pick set"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "excavation"
|
||||
desc = "A set of picks for excavation."
|
||||
item_state = "syringe_kit"
|
||||
foldable = /obj/item/stack/sheet/cardboard //BubbleWrap
|
||||
storage_slots = 7
|
||||
w_class = 2
|
||||
can_hold = list("/obj/item/weapon/pickaxe/brush",\
|
||||
"/obj/item/weapon/pickaxe/one_pick",\
|
||||
"/obj/item/weapon/pickaxe/two_pick",\
|
||||
"/obj/item/weapon/pickaxe/three_pick",\
|
||||
"/obj/item/weapon/pickaxe/four_pick",\
|
||||
"/obj/item/weapon/pickaxe/five_pick",\
|
||||
"/obj/item/weapon/pickaxe/six_pick")
|
||||
max_combined_w_class = 17
|
||||
max_w_class = 4
|
||||
use_to_pickup = 1 // for picking up broken bulbs, not that most people will try
|
||||
|
||||
/obj/item/weapon/storage/box/excavation/New()
|
||||
..()
|
||||
new /obj/item/weapon/pickaxe/brush(src)
|
||||
new /obj/item/weapon/pickaxe/one_pick(src)
|
||||
new /obj/item/weapon/pickaxe/two_pick(src)
|
||||
new /obj/item/weapon/pickaxe/three_pick(src)
|
||||
new /obj/item/weapon/pickaxe/four_pick(src)
|
||||
new /obj/item/weapon/pickaxe/five_pick(src)
|
||||
new /obj/item/weapon/pickaxe/six_pick(src)
|
||||
Reference in New Issue
Block a user