mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-21 20:11:04 +01:00
Merge tgstation13 r4570 into bs12_with_tgport
Conflicts: baystation12.dme code/defines/obj.dm code/defines/procs/helpers.dm code/defines/turf.dm code/game/gamemodes/changeling/modularchangling.dm code/game/gamemodes/cult/cult_structures.dm code/game/gamemodes/events.dm code/game/machinery/telecomms/machine_interactions.dm code/game/master_controller.dm code/game/objects/items/blueprints.dm code/game/objects/items/devices/uplinks.dm code/game/objects/items/item.dm code/game/objects/items/weapons/gift_wrappaper.dm code/game/objects/items/weapons/wires.dm code/game/objects/weapons.dm code/game/turfs/turf.dm code/modules/clothing/head/hardhat.dm code/modules/mining/mine_items.dm code/modules/mining/mine_turfs.dm code/modules/mob/living/silicon/robot/life.dm code/modules/mob/mob_defines.dm code/modules/mob/new_player/login.dm code/modules/paperwork/pen.dm code/modules/paperwork/stamps.dm code/unused/toilets.dm html/changelog.html icons/effects/alert.dmi Signed-off-by: Cael_Aislinn <cael_aislinn@yahoo.com.au>
This commit is contained in:
Executable
+1136
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,712 @@
|
||||
/obj/item/weapon/cartridge
|
||||
name = "generic cartridge"
|
||||
desc = "A data cartridge for portable microcomputers."
|
||||
icon = 'icons/obj/pda.dmi'
|
||||
icon_state = "cart"
|
||||
item_state = "electronic"
|
||||
w_class = 1
|
||||
|
||||
var/obj/item/radio/integrated/radio = null
|
||||
var/access_security = 0
|
||||
var/access_engine = 0
|
||||
var/access_medical = 0
|
||||
var/access_manifest = 0
|
||||
var/access_clown = 0
|
||||
var/access_mime = 0
|
||||
var/access_janitor = 0
|
||||
// var/access_flora = 0
|
||||
var/access_reagent_scanner = 0
|
||||
var/access_remote_door = 0 //Control some blast doors remotely!!
|
||||
var/remote_door_id = ""
|
||||
var/access_status_display = 0
|
||||
var/access_quartermaster = 0
|
||||
var/access_hydroponics = 0
|
||||
var/mode = null
|
||||
var/menu
|
||||
var/datum/data/record/active1 = null //General
|
||||
var/datum/data/record/active2 = null //Medical
|
||||
var/datum/data/record/active3 = null //Security
|
||||
var/obj/machinery/power/monitor/powmonitor = null // Power Monitor
|
||||
var/list/powermonitors = list()
|
||||
var/message1 // used for status_displays
|
||||
var/message2
|
||||
var/list/stored_data = list()
|
||||
|
||||
engineering
|
||||
name = "Power-ON Cartridge"
|
||||
icon_state = "cart-e"
|
||||
access_engine = 1
|
||||
|
||||
medical
|
||||
name = "Med-U Cartridge"
|
||||
icon_state = "cart-m"
|
||||
access_medical = 1
|
||||
|
||||
chemistry
|
||||
name = "ChemWhiz Cartridge"
|
||||
icon_state = "cart-chem"
|
||||
access_reagent_scanner = 1
|
||||
|
||||
security
|
||||
name = "R.O.B.U.S.T. Cartridge"
|
||||
icon_state = "cart-s"
|
||||
access_security = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
radio = new /obj/item/radio/integrated/beepsky(src)
|
||||
|
||||
detective
|
||||
name = "D.E.T.E.C.T. Cartridge"
|
||||
icon_state = "cart-s"
|
||||
access_security = 1
|
||||
access_medical = 1
|
||||
access_manifest = 1
|
||||
|
||||
|
||||
janitor
|
||||
name = "CustodiPRO Cartridge"
|
||||
desc = "The ultimate in clean-room design."
|
||||
icon_state = "cart-j"
|
||||
access_janitor = 1
|
||||
|
||||
lawyer
|
||||
name = "P.R.O.V.E. Cartridge"
|
||||
icon_state = "cart-s"
|
||||
access_security = 1
|
||||
|
||||
clown
|
||||
name = "Honkworks 5.0"
|
||||
icon_state = "cart-clown"
|
||||
access_clown = 1
|
||||
var/honk_charges = 5
|
||||
|
||||
mime
|
||||
name = "Gestur-O 1000"
|
||||
icon_state = "cart-mi"
|
||||
access_mime = 1
|
||||
var/mime_charges = 5
|
||||
/*
|
||||
botanist
|
||||
name = "Green Thumb v4.20"
|
||||
icon_state = "cart-b"
|
||||
access_flora = 1
|
||||
*/
|
||||
|
||||
signal
|
||||
name = "generic signaler cartridge"
|
||||
desc = "A data cartridge with an integrated radio signaler module."
|
||||
|
||||
toxins
|
||||
name = "Signal Ace 2"
|
||||
desc = "Complete with integrated radio signaler!"
|
||||
icon_state = "cart-tox"
|
||||
// access_reagent_scanner = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
radio = new /obj/item/radio/integrated/signal(src)
|
||||
|
||||
|
||||
|
||||
quartermaster
|
||||
name = "Space Parts & Space Vendors Cartridge"
|
||||
desc = "Perfect for the Quartermaster on the go!"
|
||||
icon_state = "cart-q"
|
||||
access_quartermaster = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
radio = new /obj/item/radio/integrated/mule(src)
|
||||
|
||||
head
|
||||
name = "Easy-Record DELUXE"
|
||||
icon_state = "cart-h"
|
||||
access_manifest = 1
|
||||
access_status_display = 1
|
||||
|
||||
hop
|
||||
name = "HumanResources9001"
|
||||
icon_state = "cart-h"
|
||||
access_manifest = 1
|
||||
access_status_display = 1
|
||||
access_quartermaster = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
radio = new /obj/item/radio/integrated/mule(src)
|
||||
|
||||
hos
|
||||
name = "R.O.B.U.S.T. DELUXE"
|
||||
icon_state = "cart-hos"
|
||||
access_manifest = 1
|
||||
access_status_display = 1
|
||||
access_security = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
radio = new /obj/item/radio/integrated/beepsky(src)
|
||||
|
||||
ce
|
||||
name = "Power-On DELUXE"
|
||||
icon_state = "cart-ce"
|
||||
access_manifest = 1
|
||||
access_status_display = 1
|
||||
access_engine = 1
|
||||
|
||||
cmo
|
||||
name = "Med-U DELUXE"
|
||||
icon_state = "cart-cmo"
|
||||
access_manifest = 1
|
||||
access_status_display = 1
|
||||
access_reagent_scanner = 1
|
||||
access_medical = 1
|
||||
|
||||
rd
|
||||
name = "Signal Ace DELUXE"
|
||||
icon_state = "cart-rd"
|
||||
access_manifest = 1
|
||||
access_status_display = 1
|
||||
// access_reagent_scanner = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
radio = new /obj/item/radio/integrated/signal(src)
|
||||
|
||||
captain
|
||||
name = "Value-PAK Cartridge"
|
||||
desc = "Now with 200% more value!"
|
||||
icon_state = "cart-c"
|
||||
access_manifest = 1
|
||||
access_engine = 1
|
||||
access_security = 1
|
||||
access_medical = 1
|
||||
access_reagent_scanner = 1
|
||||
access_status_display = 1
|
||||
|
||||
syndicate
|
||||
name = "Detomatix Cartridge"
|
||||
icon_state = "cart"
|
||||
access_remote_door = 1
|
||||
remote_door_id = "syndicate" //Make sure this matches the syndicate shuttle's shield/door id!!
|
||||
var/shock_charges = 4
|
||||
|
||||
proc/unlock()
|
||||
if (!istype(loc, /obj/item/device/pda))
|
||||
return
|
||||
|
||||
generate_menu()
|
||||
print_to_host(menu)
|
||||
return
|
||||
|
||||
proc/print_to_host(var/text)
|
||||
if (!istype(loc, /obj/item/device/pda))
|
||||
return
|
||||
loc:cart = text
|
||||
|
||||
for (var/mob/M in viewers(1, loc.loc))
|
||||
if (M.client && M.machine == loc)
|
||||
loc:attack_self(M)
|
||||
|
||||
return
|
||||
|
||||
proc/post_status(var/command, var/data1, var/data2)
|
||||
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435)
|
||||
|
||||
if(!frequency) return
|
||||
|
||||
var/datum/signal/status_signal = new
|
||||
status_signal.source = src
|
||||
status_signal.transmission_method = 1
|
||||
status_signal.data["command"] = command
|
||||
|
||||
switch(command)
|
||||
if("message")
|
||||
status_signal.data["msg1"] = data1
|
||||
status_signal.data["msg2"] = data2
|
||||
if("alert")
|
||||
status_signal.data["picture_state"] = data1
|
||||
|
||||
frequency.post_signal(src, status_signal)
|
||||
|
||||
proc/generate_menu()
|
||||
switch(mode)
|
||||
if(40) //signaller
|
||||
menu = "<h4><img src=pda_signaler.png> Remote Signaling System</h4>"
|
||||
|
||||
menu += {"
|
||||
<a href='byond://?src=\ref[src];choice=Send Signal'>Send Signal</A><BR>
|
||||
Frequency:
|
||||
<a href='byond://?src=\ref[src];choice=Signal Frequency;sfreq=-10'>-</a>
|
||||
<a href='byond://?src=\ref[src];choice=Signal Frequency;sfreq=-2'>-</a>
|
||||
[format_frequency(radio:frequency)]
|
||||
<a href='byond://?src=\ref[src];choice=Signal Frequency;sfreq=2'>+</a>
|
||||
<a href='byond://?src=\ref[src];choice=Signal Frequency;sfreq=10'>+</a><br>
|
||||
<br>
|
||||
Code:
|
||||
<a href='byond://?src=\ref[src];choice=Signal Code;scode=-5'>-</a>
|
||||
<a href='byond://?src=\ref[src];choice=Signal Code;scode=-1'>-</a>
|
||||
[radio:code]
|
||||
<a href='byond://?src=\ref[src];choice=Signal Code;scode=1'>+</a>
|
||||
<a href='byond://?src=\ref[src];choice=Signal Code;scode=5'>+</a><br>"}
|
||||
if (41) //crew manifest
|
||||
|
||||
menu = "<h4><img src=pda_notes.png> Crew Manifest</h4>"
|
||||
menu += "Entries cannot be modified from this terminal.<br><br>"
|
||||
if(!isnull(data_core.general))
|
||||
for (var/datum/data/record/t in sortRecord(data_core.general))
|
||||
menu += "[t.fields["name"]] - [t.fields["rank"]]<br>"
|
||||
menu += "<br>"
|
||||
|
||||
|
||||
if (42) //status displays
|
||||
menu = "<h4><img src=pda_status.png> Station Status Display Interlink</h4>"
|
||||
|
||||
menu += "\[ <A HREF='?src=\ref[src];choice=Status;statdisp=blank'>Clear</A> \]<BR>"
|
||||
menu += "\[ <A HREF='?src=\ref[src];choice=Status;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
|
||||
menu += "\[ <A HREF='?src=\ref[src];choice=Status;statdisp=message'>Message</A> \]"
|
||||
menu += "<ul><li> Line 1: <A HREF='?src=\ref[src];choice=Status;statdisp=setmsg1'>[ message1 ? message1 : "(none)"]</A>"
|
||||
menu += "<li> Line 2: <A HREF='?src=\ref[src];choice=Status;statdisp=setmsg2'>[ message2 ? message2 : "(none)"]</A></ul><br>"
|
||||
menu += "\[ Alert: <A HREF='?src=\ref[src];choice=Status;statdisp=alert;alert=default'>None</A> |"
|
||||
menu += " <A HREF='?src=\ref[src];choice=Status;statdisp=alert;alert=redalert'>Red Alert</A> |"
|
||||
menu += " <A HREF='?src=\ref[src];choice=Status;statdisp=alert;alert=lockdown'>Lockdown</A> |"
|
||||
menu += " <A HREF='?src=\ref[src];choice=Status;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR>"
|
||||
|
||||
if (43) //Muskets' and Rockdtben's power monitor :D
|
||||
menu = "<h4><img src=pda_power.png> Power Monitors - Please select one</h4><BR>"
|
||||
powmonitor = null
|
||||
powermonitors = null
|
||||
powermonitors = list()
|
||||
var/powercount = 0
|
||||
|
||||
|
||||
|
||||
for(var/obj/machinery/power/monitor/pMon in world)
|
||||
if(!(pMon.stat & (NOPOWER|BROKEN)) )
|
||||
powercount++
|
||||
powermonitors += pMon
|
||||
|
||||
|
||||
if(!powercount)
|
||||
menu += "\red No connection<BR>"
|
||||
else
|
||||
|
||||
menu += "<FONT SIZE=-1>"
|
||||
var/count = 0
|
||||
for(var/obj/machinery/power/monitor/pMon in powermonitors)
|
||||
count++
|
||||
menu += "<a href='byond://?src=\ref[src];choice=Power Select;target=[count]'> [pMon] </a><BR>"
|
||||
|
||||
menu += "</FONT>"
|
||||
|
||||
if (433) //Muskets' and Rockdtben's power monitor :D
|
||||
menu = "<h4><img src=pda_power.png> Power Monitor </h4><BR>"
|
||||
if(!powmonitor)
|
||||
menu += "\red No connection<BR>"
|
||||
else
|
||||
var/list/L = list()
|
||||
for(var/obj/machinery/power/terminal/term in powmonitor.powernet.nodes)
|
||||
if(istype(term.master, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/A = term.master
|
||||
L += A
|
||||
|
||||
menu += "<PRE>Total power: [powmonitor.powernet.avail] W<BR>Total load: [num2text(powmonitor.powernet.viewload,10)] W<BR>"
|
||||
|
||||
menu += "<FONT SIZE=-1>"
|
||||
|
||||
if(L.len > 0)
|
||||
menu += "Area Eqp./Lgt./Env. Load Cell<HR>"
|
||||
|
||||
var/list/S = list(" Off","AOff"," On", " AOn")
|
||||
var/list/chg = list("N","C","F")
|
||||
|
||||
for(var/obj/machinery/power/apc/A in L)
|
||||
menu += copytext(add_tspace(A.area.name, 30), 1, 30)
|
||||
menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(A.lastused_total, 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]<BR>"
|
||||
|
||||
menu += "</FONT></PRE>"
|
||||
|
||||
if (44) //medical records //This thing only displays a single screen so it's hard to really get the sub-menu stuff working.
|
||||
menu = "<h4><img src=pda_medical.png> Medical Record List</h4>"
|
||||
if(!isnull(data_core.general))
|
||||
for (var/datum/data/record/R in sortRecord(data_core.general))
|
||||
menu += "<a href='byond://?src=\ref[src];choice=Medical Records;target=\ref[R]'>[R.fields["id"]]: [R.fields["name"]]<br>"
|
||||
menu += "<br>"
|
||||
if(441)
|
||||
menu = "<h4><img src=pda_medical.png> Medical Record</h4>"
|
||||
|
||||
if (istype(active1, /datum/data/record) && (active1 in data_core.general))
|
||||
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
|
||||
menu += "Sex: [active1.fields["sex"]]<br>"
|
||||
menu += "Age: [active1.fields["age"]]<br>"
|
||||
menu += "Rank: [active1.fields["rank"]]<br>"
|
||||
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
|
||||
menu += "Physical Status: [active1.fields["p_stat"]]<br>"
|
||||
menu += "Mental Status: [active1.fields["m_stat"]]<br>"
|
||||
else
|
||||
menu += "<b>Record Lost!</b><br>"
|
||||
|
||||
menu += "<br>"
|
||||
|
||||
menu += "<h4><img src=pda_medical.png> Medical Data</h4>"
|
||||
if (istype(active2, /datum/data/record) && (active2 in data_core.medical))
|
||||
menu += "Blood Type: [active2.fields["b_type"]]<br><br>"
|
||||
|
||||
menu += "Minor Disabilities: [active2.fields["mi_dis"]]<br>"
|
||||
menu += "Details: [active2.fields["mi_dis_d"]]<br><br>"
|
||||
|
||||
menu += "Major Disabilities: [active2.fields["ma_dis"]]<br>"
|
||||
menu += "Details: [active2.fields["ma_dis_d"]]<br><br>"
|
||||
|
||||
menu += "Allergies: [active2.fields["alg"]]<br>"
|
||||
menu += "Details: [active2.fields["alg_d"]]<br><br>"
|
||||
|
||||
menu += "Current Diseases: [active2.fields["cdi"]]<br>"
|
||||
menu += "Details: [active2.fields["cdi_d"]]<br><br>"
|
||||
|
||||
menu += "Important Notes: [active2.fields["notes"]]<br>"
|
||||
else
|
||||
menu += "<b>Record Lost!</b><br>"
|
||||
|
||||
menu += "<br>"
|
||||
if (45) //security records
|
||||
menu = "<h4><img src=pda_cuffs.png> Security Record List</h4>"
|
||||
if(!isnull(data_core.general))
|
||||
for (var/datum/data/record/R in sortRecord(data_core.general))
|
||||
menu += "<a href='byond://?src=\ref[src];choice=Security Records;target=\ref[R]'>[R.fields["id"]]: [R.fields["name"]]<br>"
|
||||
|
||||
menu += "<br>"
|
||||
if(451)
|
||||
menu = "<h4><img src=pda_cuffs.png> Security Record</h4>"
|
||||
|
||||
if (istype(active1, /datum/data/record) && (active1 in data_core.general))
|
||||
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
|
||||
menu += "Sex: [active1.fields["sex"]]<br>"
|
||||
menu += "Age: [active1.fields["age"]]<br>"
|
||||
menu += "Rank: [active1.fields["rank"]]<br>"
|
||||
menu += "Fingerprint: [active1.fields["fingerprint"]]<br>"
|
||||
menu += "Physical Status: [active1.fields["p_stat"]]<br>"
|
||||
menu += "Mental Status: [active1.fields["m_stat"]]<br>"
|
||||
else
|
||||
menu += "<b>Record Lost!</b><br>"
|
||||
|
||||
menu += "<br>"
|
||||
|
||||
menu += "<h4><img src=pda_cuffs.png> Security Data</h4>"
|
||||
if (istype(active3, /datum/data/record) && (active3 in data_core.security))
|
||||
menu += "Criminal Status: [active3.fields["criminal"]]<br>"
|
||||
|
||||
menu += "Minor Crimes: [active3.fields["mi_crim"]]<br>"
|
||||
menu += "Details: [active3.fields["mi_crim"]]<br><br>"
|
||||
|
||||
menu += "Major Crimes: [active3.fields["ma_crim"]]<br>"
|
||||
menu += "Details: [active3.fields["ma_crim_d"]]<br><br>"
|
||||
|
||||
menu += "Important Notes:<br>"
|
||||
menu += "[active3.fields["notes"]]"
|
||||
else
|
||||
menu += "<b>Record Lost!</b><br>"
|
||||
|
||||
menu += "<br>"
|
||||
if (46) //beepsky control
|
||||
var/obj/item/radio/integrated/beepsky/SC = radio
|
||||
if(!SC)
|
||||
menu = "Interlink Error - Please reinsert cartridge."
|
||||
return
|
||||
|
||||
menu = "<h4><img src=pda_cuffs.png> Securitron Interlink</h4>"
|
||||
|
||||
if(!SC.active)
|
||||
// list of bots
|
||||
if(!SC.botlist || (SC.botlist && SC.botlist.len==0))
|
||||
menu += "No bots found.<BR>"
|
||||
|
||||
else
|
||||
for(var/obj/machinery/bot/secbot/B in SC.botlist)
|
||||
menu += "<A href='byond://?src=\ref[SC];op=control;bot=\ref[B]'>[B] at [B.loc.loc]</A><BR>"
|
||||
|
||||
menu += "<BR><A href='byond://?src=\ref[SC];op=scanbots'><img src=pda_scanner.png> Scan for active bots</A><BR>"
|
||||
|
||||
else // bot selected, control it
|
||||
|
||||
menu += "<B>[SC.active]</B><BR> Status: (<A href='byond://?src=\ref[SC];op=control;bot=\ref[SC.active]'><img src=pda_refresh.png><i>refresh</i></A>)<BR>"
|
||||
|
||||
if(!SC.botstatus)
|
||||
menu += "Waiting for response...<BR>"
|
||||
else
|
||||
|
||||
menu += "Location: [SC.botstatus["loca"] ]<BR>"
|
||||
menu += "Mode: "
|
||||
|
||||
switch(SC.botstatus["mode"])
|
||||
if(0)
|
||||
menu += "Ready"
|
||||
if(1)
|
||||
menu += "Apprehending target"
|
||||
if(2,3)
|
||||
menu += "Arresting target"
|
||||
if(4)
|
||||
menu += "Starting patrol"
|
||||
if(5)
|
||||
menu += "On patrol"
|
||||
if(6)
|
||||
menu += "Responding to summons"
|
||||
|
||||
menu += "<BR>\[<A href='byond://?src=\ref[SC];op=stop'>Stop Patrol</A>\] "
|
||||
menu += "\[<A href='byond://?src=\ref[SC];op=go'>Start Patrol</A>\] "
|
||||
menu += "\[<A href='byond://?src=\ref[SC];op=summon'>Summon Bot</A>\]<BR>"
|
||||
menu += "<HR><A href='byond://?src=\ref[SC];op=botlist'><img src=pda_back.png>Return to bot list</A>"
|
||||
|
||||
if (47) //quartermaster order records
|
||||
menu = "<h4><img src=pda_crate.png> Supply Record Interlink</h4>"
|
||||
|
||||
menu += "<BR><B>Supply shuttle</B><BR>"
|
||||
menu += "Location: [supply_shuttle.moving ? "Moving to station ([supply_shuttle.eta] Mins.)":supply_shuttle.at_station ? "Station":"Dock"]<BR>"
|
||||
menu += "Current approved orders: <BR><ol>"
|
||||
for(var/S in supply_shuttle.shoppinglist)
|
||||
var/datum/supply_order/SO = S
|
||||
menu += "<li>#[SO.ordernum] - [SO.object.name] approved by [SO.orderedby] [SO.comment ? "([SO.comment])":""]</li>"
|
||||
menu += "</ol>"
|
||||
|
||||
menu += "Current requests: <BR><ol>"
|
||||
for(var/S in supply_shuttle.requestlist)
|
||||
var/datum/supply_order/SO = S
|
||||
menu += "<li>#[SO.ordernum] - [SO.object.name] requested by [SO.orderedby]</li>"
|
||||
menu += "</ol><font size=\"-3\">Upgrade NOW to Space Parts & Space Vendors PLUS for full remote order control and inventory management."
|
||||
|
||||
if (48) //mulebot control
|
||||
var/obj/item/radio/integrated/mule/QC = radio
|
||||
if(!QC)
|
||||
menu = "Interlink Error - Please reinsert cartridge."
|
||||
return
|
||||
|
||||
menu = "<h4><img src=pda_mule.png> M.U.L.E. bot Interlink V0.8</h4>"
|
||||
|
||||
if(!QC.active)
|
||||
// list of bots
|
||||
if(!QC.botlist || (QC.botlist && QC.botlist.len==0))
|
||||
menu += "No bots found.<BR>"
|
||||
|
||||
else
|
||||
for(var/obj/machinery/bot/mulebot/B in QC.botlist)
|
||||
menu += "<A href='byond://?src=\ref[QC];op=control;bot=\ref[B]'>[B] at [B.loc.loc]</A><BR>"
|
||||
|
||||
menu += "<BR><A href='byond://?src=\ref[QC];op=scanbots'><img src=pda_scanner.png> Scan for active bots</A><BR>"
|
||||
|
||||
else // bot selected, control it
|
||||
|
||||
menu += "<B>[QC.active]</B><BR> Status: (<A href='byond://?src=\ref[QC];op=control;bot=\ref[QC.active]'><img src=pda_refresh.png><i>refresh</i></A>)<BR>"
|
||||
|
||||
if(!QC.botstatus)
|
||||
menu += "Waiting for response...<BR>"
|
||||
else
|
||||
|
||||
menu += "Location: [QC.botstatus["loca"] ]<BR>"
|
||||
menu += "Mode: "
|
||||
|
||||
switch(QC.botstatus["mode"])
|
||||
if(0)
|
||||
menu += "Ready"
|
||||
if(1)
|
||||
menu += "Loading/Unloading"
|
||||
if(2)
|
||||
menu += "Navigating to Delivery Location"
|
||||
if(3)
|
||||
menu += "Navigating to Home"
|
||||
if(4)
|
||||
menu += "Waiting for clear path"
|
||||
if(5,6)
|
||||
menu += "Calculating navigation path"
|
||||
if(7)
|
||||
menu += "Unable to locate destination"
|
||||
var/obj/structure/closet/crate/C = QC.botstatus["load"]
|
||||
menu += "<BR>Current Load: [ !C ? "<i>none</i>" : "[C.name] (<A href='byond://?src=\ref[QC];op=unload'><i>unload</i></A>)" ]<BR>"
|
||||
menu += "Destination: [!QC.botstatus["dest"] ? "<i>none</i>" : QC.botstatus["dest"] ] (<A href='byond://?src=\ref[QC];op=setdest'><i>set</i></A>)<BR>"
|
||||
menu += "Power: [QC.botstatus["powr"]]%<BR>"
|
||||
menu += "Home: [!QC.botstatus["home"] ? "<i>none</i>" : QC.botstatus["home"] ]<BR>"
|
||||
menu += "Auto Return Home: [QC.botstatus["retn"] ? "<B>On</B> <A href='byond://?src=\ref[QC];op=retoff'>Off</A>" : "(<A href='byond://?src=\ref[QC];op=reton'><i>On</i></A>) <B>Off</B>"]<BR>"
|
||||
menu += "Auto Pickup Crate: [QC.botstatus["pick"] ? "<B>On</B> <A href='byond://?src=\ref[QC];op=pickoff'>Off</A>" : "(<A href='byond://?src=\ref[QC];op=pickon'><i>On</i></A>) <B>Off</B>"]<BR><BR>"
|
||||
|
||||
menu += "\[<A href='byond://?src=\ref[QC];op=stop'>Stop</A>\] "
|
||||
menu += "\[<A href='byond://?src=\ref[QC];op=go'>Proceed</A>\] "
|
||||
menu += "\[<A href='byond://?src=\ref[QC];op=home'>Return Home</A>\]<BR>"
|
||||
menu += "<HR><A href='byond://?src=\ref[QC];op=botlist'><img src=pda_back.png>Return to bot list</A>"
|
||||
|
||||
if (49) //janitorial locator
|
||||
menu = "<h4><img src=pda_bucket.png> Persistent Custodial Object Locator</h4>"
|
||||
|
||||
var/turf/cl = get_turf(src)
|
||||
if (cl)
|
||||
menu += "Current Orbital Location: <b>\[[cl.x],[cl.y]\]</b>"
|
||||
|
||||
menu += "<h4>Located Mops:</h4>"
|
||||
|
||||
var/ldat
|
||||
for (var/obj/item/weapon/mop/M in world)
|
||||
var/turf/ml = get_turf(M)
|
||||
|
||||
if(ml)
|
||||
if (ml.z != cl.z)
|
||||
continue
|
||||
var/direction = get_dir(src, M)
|
||||
ldat += "Mop - <b>\[[ml.x],[ml.y] ([uppertext(dir2text(direction))])\]</b> - [M.reagents.total_volume ? "Wet" : "Dry"]<br>"
|
||||
|
||||
if (!ldat)
|
||||
menu += "None"
|
||||
else
|
||||
menu += "[ldat]"
|
||||
|
||||
menu += "<h4>Located Mop Buckets:</h4>"
|
||||
|
||||
ldat = null
|
||||
for (var/obj/structure/mopbucket/B in world)
|
||||
var/turf/bl = get_turf(B)
|
||||
|
||||
if(bl)
|
||||
if (bl.z != cl.z)
|
||||
continue
|
||||
var/direction = get_dir(src, B)
|
||||
ldat += "Bucket - <b>\[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\]</b> - Water level: [B.reagents.total_volume]/100<br>"
|
||||
|
||||
if (!ldat)
|
||||
menu += "None"
|
||||
else
|
||||
menu += "[ldat]"
|
||||
|
||||
menu += "<h4>Located Cleanbots:</h4>"
|
||||
|
||||
ldat = null
|
||||
for (var/obj/machinery/bot/cleanbot/B in world)
|
||||
var/turf/bl = get_turf(B)
|
||||
|
||||
if(bl)
|
||||
if (bl.z != cl.z)
|
||||
continue
|
||||
var/direction = get_dir(src, B)
|
||||
ldat += "Cleanbot - <b>\[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\]</b> - [B.on ? "Online" : "Offline"]<br>"
|
||||
|
||||
if (!ldat)
|
||||
menu += "None"
|
||||
else
|
||||
menu += "[ldat]"
|
||||
|
||||
else
|
||||
menu += "ERROR: Unable to determine current location."
|
||||
menu += "<br><br><A href='byond://?src=\ref[src];choice=49'>Refresh GPS Locator</a>"
|
||||
|
||||
proc/add_data(atom/A as mob|obj|turf|area)
|
||||
//I love hashtables.
|
||||
var/list/data_entry = stored_data["\ref [A]"]
|
||||
if(islist(data_entry)) //Yay, it was already stored!
|
||||
//Merge the fingerprints.
|
||||
var/list/data_prints = data_entry[1]
|
||||
for(var/print in A.fingerprints)
|
||||
var/merged_print = data_prints[print]
|
||||
if(!merged_print)
|
||||
data_prints[print] = A.fingerprints[print]
|
||||
else
|
||||
data_prints[print] = stringmerge(data_prints[print],A.fingerprints[print])
|
||||
|
||||
//Now the fibers
|
||||
var/list/fibers = data_entry[2]
|
||||
if(!fibers)
|
||||
fibers = list()
|
||||
if(A.suit_fibers && A.suit_fibers.len)
|
||||
for(var/j = 1, j <= A.suit_fibers.len, j++) //Fibers~~~
|
||||
if(!fibers.Find(A.suit_fibers[j])) //It isn't! Add!
|
||||
fibers += A.suit_fibers[j]
|
||||
var/list/blood = data_entry[3]
|
||||
if(!blood)
|
||||
blood = list()
|
||||
if(A.blood_DNA && A.blood_DNA.len)
|
||||
for(var/main_blood in A.blood_DNA)
|
||||
if(!blood[main_blood])
|
||||
blood[main_blood] = A.blood_DNA[blood]
|
||||
return 1
|
||||
var/list/sum_list[4] //Pack it back up!
|
||||
sum_list[1] = A.fingerprints
|
||||
sum_list[2] = A.suit_fibers
|
||||
sum_list[3] = A.blood_DNA
|
||||
sum_list[4] = "\The [A] in \the [get_area(A)]"
|
||||
stored_data["\ref [A]"] = sum_list
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/cartridge/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
if (!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
|
||||
usr.machine = null
|
||||
usr << browse(null, "window=pda")
|
||||
return
|
||||
|
||||
switch(href_list["choice"])
|
||||
if("Medical Records")
|
||||
var/datum/data/record/R = locate(href_list["target"])
|
||||
var/datum/data/record/M = locate(href_list["target"])
|
||||
loc:mode = 441
|
||||
mode = 441
|
||||
if (R in data_core.general)
|
||||
for (var/datum/data/record/E in data_core.medical)
|
||||
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
|
||||
M = E
|
||||
break
|
||||
active1 = R
|
||||
active2 = M
|
||||
|
||||
if("Security Records")
|
||||
var/datum/data/record/R = locate(href_list["target"])
|
||||
var/datum/data/record/S = locate(href_list["target"])
|
||||
loc:mode = 451
|
||||
mode = 451
|
||||
if (R in data_core.general)
|
||||
for (var/datum/data/record/E in data_core.security)
|
||||
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
|
||||
S = E
|
||||
break
|
||||
active1 = R
|
||||
active3 = S
|
||||
|
||||
if("Send Signal")
|
||||
spawn( 0 )
|
||||
radio:send_signal("ACTIVATE")
|
||||
return
|
||||
|
||||
if("Signal Frequency")
|
||||
var/new_frequency = sanitize_frequency(radio:frequency + text2num(href_list["sfreq"]))
|
||||
radio:set_frequency(new_frequency)
|
||||
|
||||
if("Signal Code")
|
||||
radio:code += text2num(href_list["scode"])
|
||||
radio:code = round(radio:code)
|
||||
radio:code = min(100, radio:code)
|
||||
radio:code = max(1, radio:code)
|
||||
|
||||
if("Status")
|
||||
switch(href_list["statdisp"])
|
||||
if("message")
|
||||
post_status("message", message1, message2)
|
||||
if("alert")
|
||||
post_status("alert", href_list["alert"])
|
||||
if("setmsg1")
|
||||
message1 = input("Line 1", "Enter Message Text", message1) as text|null
|
||||
updateSelfDialog()
|
||||
if("setmsg2")
|
||||
message2 = input("Line 2", "Enter Message Text", message2) as text|null
|
||||
updateSelfDialog()
|
||||
else
|
||||
post_status(href_list["statdisp"])
|
||||
if("Power Select")
|
||||
var/pnum = text2num(href_list["target"])
|
||||
powmonitor = powermonitors[pnum]
|
||||
loc:mode = 433
|
||||
mode = 433
|
||||
|
||||
generate_menu()
|
||||
print_to_host(menu)
|
||||
@@ -0,0 +1,16 @@
|
||||
var/list/chatrooms = list()
|
||||
|
||||
/datum/chatroom
|
||||
var/name = "Generic Chatroom"
|
||||
var/list/logged_in = list()
|
||||
var/list/logs = list() // chat logs
|
||||
var/list/banned = list() // banned users
|
||||
var/list/whitelist = list() // whitelisted users
|
||||
var/list/muted = list()
|
||||
var/topic = "" // topic message for the chatroom
|
||||
var/password = "" // blank for no password.
|
||||
var/operator = "" // name of the operator
|
||||
|
||||
/datum/chatroom/proc/attempt_connect(var/obj/item/device/pda/device, var/obj/password)
|
||||
if(!device)
|
||||
return
|
||||
@@ -0,0 +1,259 @@
|
||||
/obj/item/radio/integrated
|
||||
name = "PDA radio module"
|
||||
desc = "An electronic radio system of nanotrasen origin."
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "power_mod"
|
||||
var/obj/item/device/pda/hostpda = null
|
||||
|
||||
var/on = 0 //Are we currently active??
|
||||
var/menu_message = ""
|
||||
|
||||
New()
|
||||
..()
|
||||
if (istype(loc.loc, /obj/item/device/pda))
|
||||
hostpda = loc.loc
|
||||
|
||||
proc/post_signal(var/freq, var/key, var/value, var/key2, var/value2, var/key3, var/value3, s_filter)
|
||||
|
||||
//world << "Post: [freq]: [key]=[value], [key2]=[value2]"
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq)
|
||||
|
||||
if(!frequency) return
|
||||
|
||||
var/datum/signal/signal = new()
|
||||
signal.source = src
|
||||
signal.transmission_method = 1
|
||||
signal.data[key] = value
|
||||
if(key2)
|
||||
signal.data[key2] = value2
|
||||
if(key3)
|
||||
signal.data[key3] = value3
|
||||
|
||||
frequency.post_signal(src, signal, filter = s_filter)
|
||||
|
||||
proc/print_to_host(var/text)
|
||||
if (isnull(src.hostpda))
|
||||
return
|
||||
src.hostpda.cart = text
|
||||
|
||||
for (var/mob/M in viewers(1, src.hostpda.loc))
|
||||
if (M.client && M.machine == src.hostpda)
|
||||
src.hostpda.cartridge.unlock()
|
||||
|
||||
return
|
||||
|
||||
proc/generate_menu()
|
||||
|
||||
/obj/item/radio/integrated/beepsky
|
||||
var/list/botlist = null // list of bots
|
||||
var/obj/machinery/bot/secbot/active // the active bot; if null, show bot list
|
||||
var/list/botstatus // the status signal sent by the bot
|
||||
|
||||
var/control_freq = 1447
|
||||
|
||||
// create a new QM cartridge, and register to receive bot control & beacon message
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(src, control_freq, filter = RADIO_SECBOT)
|
||||
|
||||
// receive radio signals
|
||||
// can detect bot status signals
|
||||
// create/populate list as they are recvd
|
||||
|
||||
receive_signal(datum/signal/signal)
|
||||
// var/obj/item/device/pda/P = src.loc
|
||||
|
||||
/*
|
||||
world << "recvd:[P] : [signal.source]"
|
||||
for(var/d in signal.data)
|
||||
world << "- [d] = [signal.data[d]]"
|
||||
*/
|
||||
if (signal.data["type"] == "secbot")
|
||||
if(!botlist)
|
||||
botlist = new()
|
||||
|
||||
if(!(signal.source in botlist))
|
||||
botlist += signal.source
|
||||
|
||||
if(active == signal.source)
|
||||
var/list/b = signal.data
|
||||
botstatus = b.Copy()
|
||||
|
||||
// if (istype(P)) P.updateSelfDialog()
|
||||
|
||||
Topic(href, href_list)
|
||||
..()
|
||||
var/obj/item/device/pda/PDA = src.hostpda
|
||||
|
||||
switch(href_list["op"])
|
||||
|
||||
if("control")
|
||||
active = locate(href_list["bot"])
|
||||
post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_SECBOT)
|
||||
|
||||
if("scanbots") // find all bots
|
||||
botlist = null
|
||||
post_signal(control_freq, "command", "bot_status", s_filter = RADIO_SECBOT)
|
||||
|
||||
if("botlist")
|
||||
active = null
|
||||
|
||||
if("stop", "go")
|
||||
post_signal(control_freq, "command", href_list["op"], "active", active, s_filter = RADIO_SECBOT)
|
||||
post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_SECBOT)
|
||||
|
||||
if("summon")
|
||||
post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(PDA) , s_filter = RADIO_SECBOT)
|
||||
post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_SECBOT)
|
||||
PDA.cartridge.unlock()
|
||||
|
||||
/obj/item/radio/integrated/mule
|
||||
var/list/botlist = null // list of bots
|
||||
var/obj/machinery/bot/mulebot/active // the active bot; if null, show bot list
|
||||
var/list/botstatus // the status signal sent by the bot
|
||||
var/list/beacons
|
||||
|
||||
var/beacon_freq = 1400
|
||||
var/control_freq = 1447
|
||||
|
||||
// create a new QM cartridge, and register to receive bot control & beacon message
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(src, control_freq, filter = RADIO_MULEBOT)
|
||||
radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS)
|
||||
spawn(10)
|
||||
post_signal(beacon_freq, "findbeacon", "delivery", s_filter = RADIO_NAVBEACONS)
|
||||
|
||||
// receive radio signals
|
||||
// can detect bot status signals
|
||||
// and beacon locations
|
||||
// create/populate lists as they are recvd
|
||||
|
||||
receive_signal(datum/signal/signal)
|
||||
// var/obj/item/device/pda/P = src.loc
|
||||
|
||||
/*
|
||||
world << "recvd:[P] : [signal.source]"
|
||||
for(var/d in signal.data)
|
||||
world << "- [d] = [signal.data[d]]"
|
||||
*/
|
||||
if(signal.data["type"] == "mulebot")
|
||||
if(!botlist)
|
||||
botlist = new()
|
||||
|
||||
if(!(signal.source in botlist))
|
||||
botlist += signal.source
|
||||
|
||||
if(active == signal.source)
|
||||
var/list/b = signal.data
|
||||
botstatus = b.Copy()
|
||||
|
||||
else if(signal.data["beacon"])
|
||||
if(!beacons)
|
||||
beacons = new()
|
||||
|
||||
beacons[signal.data["beacon"] ] = signal.source
|
||||
|
||||
|
||||
// if(istype(P)) P.updateSelfDialog()
|
||||
|
||||
Topic(href, href_list)
|
||||
..()
|
||||
var/obj/item/device/pda/PDA = src.hostpda
|
||||
var/cmd = "command"
|
||||
if(active) cmd = "command [active.suffix]"
|
||||
|
||||
switch(href_list["op"])
|
||||
|
||||
if("control")
|
||||
active = locate(href_list["bot"])
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("scanbots") // find all bots
|
||||
botlist = null
|
||||
post_signal(control_freq, "command", "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("botlist")
|
||||
active = null
|
||||
|
||||
|
||||
if("unload")
|
||||
post_signal(control_freq, cmd, "unload", s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
if("setdest")
|
||||
if(beacons)
|
||||
var/dest = input("Select Bot Destination", "Mulebot [active.suffix] Interlink", active.destination) as null|anything in beacons
|
||||
if(dest)
|
||||
post_signal(control_freq, cmd, "target", "destination", dest, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("retoff")
|
||||
post_signal(control_freq, cmd, "autoret", "value", 0, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
if("reton")
|
||||
post_signal(control_freq, cmd, "autoret", "value", 1, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("pickoff")
|
||||
post_signal(control_freq, cmd, "autopick", "value", 0, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
if("pickon")
|
||||
post_signal(control_freq, cmd, "autopick", "value", 1, s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("stop", "go", "home")
|
||||
post_signal(control_freq, cmd, href_list["op"], s_filter = RADIO_MULEBOT)
|
||||
post_signal(control_freq, cmd, "bot_status", s_filter = RADIO_MULEBOT)
|
||||
PDA.cartridge.unlock()
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Radio Cartridge, essentially a signaler.
|
||||
*/
|
||||
|
||||
|
||||
/obj/item/radio/integrated/signal
|
||||
var/frequency = 1457
|
||||
var/code = 30.0
|
||||
var/last_transmission
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
New()
|
||||
..()
|
||||
if(radio_controller)
|
||||
initialize()
|
||||
|
||||
initialize()
|
||||
if (src.frequency < 1441 || src.frequency > 1489)
|
||||
src.frequency = sanitize_frequency(src.frequency)
|
||||
|
||||
set_frequency(frequency)
|
||||
|
||||
proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = radio_controller.add_object(src, frequency)
|
||||
|
||||
proc/send_signal(message="ACTIVATE")
|
||||
|
||||
if(last_transmission && world.time < (last_transmission + 5))
|
||||
return
|
||||
last_transmission = world.time
|
||||
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
var/turf/T = get_turf(src)
|
||||
lastsignalers.Add("[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(frequency)]/[code]")
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.source = src
|
||||
signal.encryption = code
|
||||
signal.data["message"] = message
|
||||
|
||||
radio_connection.post_signal(src, signal)
|
||||
|
||||
return
|
||||
@@ -0,0 +1,128 @@
|
||||
/obj/item/device/aicard
|
||||
name = "inteliCard"
|
||||
icon = 'icons/obj/pda.dmi'
|
||||
icon_state = "aicard" // aicard-full
|
||||
item_state = "electronic"
|
||||
w_class = 2.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
var/flush = null
|
||||
origin_tech = "programming=4;materials=4"
|
||||
|
||||
|
||||
attack(mob/living/silicon/ai/M as mob, mob/user as mob)
|
||||
if(!istype(M, /mob/living/silicon/ai))//If target is not an AI.
|
||||
return ..()
|
||||
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been carded with [src.name] by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to card [M.name] ([M.ckey])</font>")
|
||||
|
||||
log_attack("<font color='red'>[user.name] ([user.ckey]) used the [src.name] to card [M.name] ([M.ckey])</font>")
|
||||
|
||||
|
||||
transfer_ai("AICORE", "AICARD", M, user)
|
||||
return
|
||||
|
||||
attack(mob/living/silicon/decoy/M as mob, mob/user as mob)
|
||||
if (!istype (M, /mob/living/silicon/decoy))
|
||||
return ..()
|
||||
else
|
||||
M.death()
|
||||
user << "<b>ERROR ERROR ERROR</b>"
|
||||
|
||||
attack_self(mob/user)
|
||||
if (!in_range(src, user))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<TT><B>Intelicard</B><BR>"
|
||||
var/laws
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
dat += "Stored AI: [A.name]<br>System integrity: [(A.health+100)/2]%<br>"
|
||||
|
||||
for (var/index = 1, index <= A.laws.ion.len, index++)
|
||||
var/law = A.laws.ion[index]
|
||||
if (length(law) > 0)
|
||||
var/num = ionnum()
|
||||
laws += "[num]. [law]"
|
||||
|
||||
if (A.laws.zeroth)
|
||||
laws += "0: [A.laws.zeroth]<BR>"
|
||||
|
||||
var/number = 1
|
||||
for (var/index = 1, index <= A.laws.inherent.len, index++)
|
||||
var/law = A.laws.inherent[index]
|
||||
if (length(law) > 0)
|
||||
laws += "[number]: [law]<BR>"
|
||||
number++
|
||||
|
||||
for (var/index = 1, index <= A.laws.supplied.len, index++)
|
||||
var/law = A.laws.supplied[index]
|
||||
if (length(law) > 0)
|
||||
laws += "[number]: [law]<BR>"
|
||||
number++
|
||||
|
||||
dat += "Laws:<br>[laws]<br>"
|
||||
|
||||
if (A.stat == 2)
|
||||
dat += "<b>AI nonfunctional</b>"
|
||||
else
|
||||
if (!src.flush)
|
||||
dat += {"<A href='byond://?src=\ref[src];choice=Wipe'>Wipe AI</A>"}
|
||||
else
|
||||
dat += "<b>Wipe in progress</b>"
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Wireless'>[A.control_disabled ? "Enable" : "Disable"] Wireless Activity</a>"}
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
|
||||
user << browse(dat, "window=aicard")
|
||||
onclose(user, "aicard")
|
||||
return
|
||||
|
||||
Topic(href, href_list)
|
||||
var/mob/U = usr
|
||||
if (!in_range(src, U)||U.machine!=src)//If they are not in range of 1 or less or their machine is not the card (ie, clicked on something else).
|
||||
U << browse(null, "window=aicard")
|
||||
U.machine = null
|
||||
return
|
||||
|
||||
add_fingerprint(U)
|
||||
U.machine = src
|
||||
|
||||
switch(href_list["choice"])//Now we switch based on choice.
|
||||
if ("Close")
|
||||
U << browse(null, "window=aicard")
|
||||
U.machine = null
|
||||
return
|
||||
|
||||
if ("Wipe")
|
||||
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
if(isnull(src)||!in_range(src, U)||U.machine!=src)
|
||||
U << browse(null, "window=aicard")
|
||||
U.machine = null
|
||||
return
|
||||
else
|
||||
flush = 1
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.suiciding = 1
|
||||
A << "Your core files are being wiped!"
|
||||
while (A.stat != 2)
|
||||
A.adjustOxyLoss(2)
|
||||
A.updatehealth()
|
||||
sleep(10)
|
||||
flush = 0
|
||||
|
||||
if ("Wireless")
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.control_disabled = !A.control_disabled
|
||||
A << "The intelicard's wireless port has been [A.control_disabled ? "disabled" : "enabled"]!"
|
||||
if (A.control_disabled)
|
||||
overlays -= image('icons/obj/pda.dmi', "aicard-on")
|
||||
else
|
||||
overlays += image('icons/obj/pda.dmi', "aicard-on")
|
||||
attack_self(U)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/obj/item/device/chameleon
|
||||
name = "chameleon-projector"
|
||||
icon_state = "shield0"
|
||||
flags = FPRINT | TABLEPASS| CONDUCT | USEDELAY
|
||||
slot_flags = SLOT_BELT
|
||||
item_state = "electronic"
|
||||
throwforce = 5.0
|
||||
throw_speed = 1
|
||||
throw_range = 5
|
||||
w_class = 2.0
|
||||
origin_tech = "syndicate=4;magnets=4"
|
||||
var/can_use = 1
|
||||
var/obj/effect/dummy/chameleon/active_dummy = null
|
||||
var/saved_item = "/obj/item/weapon/cigbutt"
|
||||
|
||||
dropped()
|
||||
disrupt()
|
||||
|
||||
attack_self()
|
||||
toggle()
|
||||
|
||||
afterattack(atom/target, mob/user , flag)
|
||||
if(istype(target,/obj/item))
|
||||
playsound(src, 'sound/weapons/flash.ogg', 100, 1, 1)
|
||||
user << "\blue Scanned [target]."
|
||||
saved_item = target.type
|
||||
|
||||
proc/toggle()
|
||||
if(!can_use || !saved_item) return
|
||||
if(active_dummy)
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
for(var/atom/movable/A in active_dummy)
|
||||
A.loc = active_dummy.loc
|
||||
if(ismob(A))
|
||||
if(A:client)
|
||||
A:client:eye = A
|
||||
del(active_dummy)
|
||||
active_dummy = null
|
||||
usr << "\blue You deactivate the [src]."
|
||||
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
spawn(8) del(T)
|
||||
else
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
var/obj/O = new saved_item(src)
|
||||
if(!O) return
|
||||
var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(usr.loc)
|
||||
C.name = O.name
|
||||
C.desc = O.desc
|
||||
C.icon = O.icon
|
||||
C.icon_state = O.icon_state
|
||||
C.dir = O.dir
|
||||
usr.loc = C
|
||||
C.master = src
|
||||
src.active_dummy = C
|
||||
del(O)
|
||||
usr << "\blue You activate the [src]."
|
||||
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
spawn(8) del(T)
|
||||
|
||||
proc/disrupt()
|
||||
if(active_dummy)
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
spark_system.start()
|
||||
for(var/atom/movable/A in active_dummy)
|
||||
A.loc = active_dummy.loc
|
||||
if(ismob(A))
|
||||
if(A:client)
|
||||
A:client:eye = A
|
||||
del(active_dummy)
|
||||
active_dummy = null
|
||||
can_use = 0
|
||||
spawn(100) can_use = 1
|
||||
|
||||
|
||||
/obj/effect/dummy/chameleon
|
||||
name = ""
|
||||
desc = ""
|
||||
density = 0
|
||||
anchored = 1
|
||||
var/can_move = 1
|
||||
var/obj/item/device/chameleon/master = null
|
||||
attackby()
|
||||
for(var/mob/M in src)
|
||||
M << "\red Your chameleon-projector deactivates."
|
||||
master.disrupt()
|
||||
attack_hand()
|
||||
for(var/mob/M in src)
|
||||
M << "\red Your chameleon-projector deactivates."
|
||||
master.disrupt()
|
||||
ex_act()
|
||||
for(var/mob/M in src)
|
||||
M << "\red Your chameleon-projector deactivates."
|
||||
master.disrupt()
|
||||
bullet_act()
|
||||
for(var/mob/M in src)
|
||||
M << "\red Your chameleon-projector deactivates."
|
||||
..()
|
||||
master.disrupt()
|
||||
relaymove(var/mob/user, direction)
|
||||
if(istype(loc, /turf/space)) return //No magical space movement!
|
||||
|
||||
if(can_move)
|
||||
can_move = 0
|
||||
switch(usr.bodytemperature)
|
||||
if(300 to INFINITY)
|
||||
spawn(10) can_move = 1
|
||||
if(295 to 300)
|
||||
spawn(13) can_move = 1
|
||||
if(280 to 295)
|
||||
spawn(16) can_move = 1
|
||||
if(260 to 280)
|
||||
spawn(20) can_move = 1
|
||||
else
|
||||
spawn(25) can_move = 1
|
||||
step(src,direction)
|
||||
return
|
||||
@@ -0,0 +1,214 @@
|
||||
/obj/item/device/flash
|
||||
name = "flash"
|
||||
desc = "Used for blinding and being an asshole."
|
||||
icon_state = "flash"
|
||||
item_state = "flashbang" //looks exactly like a flash (and nothing like a flashbang)
|
||||
throwforce = 5
|
||||
w_class = 1.0
|
||||
throw_speed = 4
|
||||
throw_range = 10
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
origin_tech = "magnets=2;combat=1"
|
||||
|
||||
var/times_used = 0 //Number of times it's been used.
|
||||
var/broken = 0 //Is the flash burnt out?
|
||||
var/last_used = 0 //last world.time it was used.
|
||||
|
||||
/obj/item/device/flash/proc/clown_check(var/mob/user)
|
||||
if(user && (CLUMSY in user.mutations) && prob(50))
|
||||
user << "\red \The [src] slips out of your hand."
|
||||
user.drop_item()
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/device/flash/proc/flash_recharge()
|
||||
//capacitor recharges over time
|
||||
for(var/i=0, i<3, i++)
|
||||
if(last_used+600 > world.time)
|
||||
break
|
||||
last_used += 600
|
||||
times_used -= 2
|
||||
last_used = world.time
|
||||
times_used = max(0,round(times_used)) //sanity
|
||||
|
||||
|
||||
/obj/item/device/flash/attack(mob/living/M as mob, mob/user as mob)
|
||||
if(!user || !M) return //sanity
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to flash [M.name] ([M.ckey])</font>")
|
||||
|
||||
log_attack("<font color='red'>[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey])</font>")
|
||||
|
||||
|
||||
if(!clown_check(user)) return
|
||||
if(broken)
|
||||
user << "<span class='warning'>\The [src] is broken.</span>"
|
||||
return
|
||||
|
||||
flash_recharge()
|
||||
|
||||
//spamming the flash before it's fully charged (60seconds) increases the chance of it breaking
|
||||
//It will never break on the first use.
|
||||
switch(times_used)
|
||||
if(0 to 5)
|
||||
last_used = world.time
|
||||
if(prob(times_used)) //if you use it 5 times in a minute it has a 10% chance to break!
|
||||
broken = 1
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
icon_state = "flashburnt"
|
||||
return
|
||||
times_used++
|
||||
else //can only use it 5 times a minute
|
||||
user << "<span class='warning'>*click* *click*</span>"
|
||||
return
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
var/flashfail = 0
|
||||
|
||||
if(iscarbon(M))
|
||||
var/safety = M:eyecheck()
|
||||
if(safety <= 0)
|
||||
M.Weaken(10)
|
||||
flick("e_flash", M.flash)
|
||||
|
||||
if(ishuman(M) && ishuman(user) && M.stat!=DEAD)
|
||||
if(user.mind && user.mind in ticker.mode.head_revolutionaries)
|
||||
var/revsafe = 0
|
||||
for(var/obj/item/weapon/implant/loyalty/L in M)
|
||||
if(L && L.implanted)
|
||||
revsafe = 1
|
||||
break
|
||||
M.mind_initialize() //give them a mind datum if they don't have one.
|
||||
if(M.mind.has_been_rev)
|
||||
revsafe = 2
|
||||
if(!revsafe)
|
||||
M.mind.has_been_rev = 1
|
||||
ticker.mode.add_revolutionary(M.mind)
|
||||
else if(revsafe == 1)
|
||||
user << "<span class='warning'>Something seems to be blocking the flash!</span>"
|
||||
else
|
||||
user << "<span class='warning'>This mind seems resistant to the flash!</span>"
|
||||
user << "<span class='warning'>This mind is so vacant that it is not susceptible to influence!</span>"
|
||||
else
|
||||
flashfail = 1
|
||||
|
||||
else if(issilicon(M))
|
||||
M.Weaken(rand(5,10))
|
||||
else
|
||||
flashfail = 1
|
||||
|
||||
if(isrobot(user))
|
||||
spawn(0)
|
||||
var/atom/movable/overlay/animation = new(user.loc)
|
||||
animation.layer = user.layer + 1
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = user
|
||||
flick("blspell", animation)
|
||||
sleep(5)
|
||||
del(animation)
|
||||
|
||||
if(!flashfail)
|
||||
flick("flash2", src)
|
||||
if(!issilicon(M))
|
||||
|
||||
user.visible_message("<span class='disarm'>[user] blinds [M] with the flash!</span>")
|
||||
else
|
||||
|
||||
user.visible_message("<span class='notice'>[user] overloads [M]'s sensors with the flash!</span>")
|
||||
else
|
||||
|
||||
user.visible_message("<span class='notice'>[user] fails to blind [M] with the flash!</span>")
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
|
||||
if(!user || !clown_check(user)) return
|
||||
if(broken)
|
||||
user.show_message("<span class='warning'>The [src.name] is broken</span>", 2)
|
||||
return
|
||||
|
||||
flash_recharge()
|
||||
|
||||
//spamming the flash before it's fully charged (60seconds) increases the chance of it breaking
|
||||
//It will never break on the first use.
|
||||
switch(times_used)
|
||||
if(0 to 5)
|
||||
if(prob(2*times_used)) //if you use it 5 times in a minute it has a 10% chance to break!
|
||||
broken = 1
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
icon_state = "flashburnt"
|
||||
return
|
||||
times_used++
|
||||
else //can only use it 5 times a minute
|
||||
user.show_message("<span class='warning'>*click* *click*</span>", 2)
|
||||
return
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
flick("flash2", src)
|
||||
if(user && isrobot(user))
|
||||
spawn(0)
|
||||
var/atom/movable/overlay/animation = new(user.loc)
|
||||
animation.layer = user.layer + 1
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = user
|
||||
flick("blspell", animation)
|
||||
sleep(5)
|
||||
del(animation)
|
||||
|
||||
for(var/mob/living/carbon/M in oviewers(3, null))
|
||||
if(prob(50))
|
||||
if (locate(/obj/item/weapon/cloaking_device, M))
|
||||
for(var/obj/item/weapon/cloaking_device/S in M)
|
||||
S.active = 0
|
||||
S.icon_state = "shield0"
|
||||
var/safety = M:eyecheck()
|
||||
if(!safety)
|
||||
if(!M.blinded)
|
||||
flick("flash", M.flash)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/device/flash/emp_act(severity)
|
||||
if(broken) return
|
||||
flash_recharge()
|
||||
switch(times_used)
|
||||
if(0 to 5)
|
||||
if(prob(2*times_used))
|
||||
broken = 1
|
||||
icon_state = "flashburnt"
|
||||
return
|
||||
times_used++
|
||||
if(istype(loc, /mob/living/carbon))
|
||||
var/mob/living/carbon/M = loc
|
||||
var/safety = M.eyecheck()
|
||||
if(safety <= 0)
|
||||
M.Weaken(10)
|
||||
flick("e_flash", M.flash)
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message("<span class='disarm'>[M] is blinded by the flash!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/device/flash/synthetic
|
||||
name = "synthetic flash"
|
||||
desc = "When a problem arises, SCIENCE is the solution."
|
||||
icon_state = "sflash"
|
||||
origin_tech = "magnets=2;combat=1"
|
||||
var/construction_cost = list("metal"=750,"glass"=750)
|
||||
var/construction_time=100
|
||||
|
||||
/obj/item/device/flash/synthetic/attack(mob/living/M as mob, mob/user as mob)
|
||||
..()
|
||||
if(!broken)
|
||||
broken = 1
|
||||
user << "\red The bulb has burnt out!"
|
||||
icon_state = "flashburnt"
|
||||
|
||||
/obj/item/device/flash/synthetic/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
|
||||
..()
|
||||
if(!broken)
|
||||
broken = 1
|
||||
user << "\red The bulb has burnt out!"
|
||||
icon_state = "flashburnt"
|
||||
@@ -0,0 +1,167 @@
|
||||
/obj/item/device/flashlight
|
||||
name = "flashlight"
|
||||
desc = "A hand-held emergency light."
|
||||
icon_state = "flight0"
|
||||
w_class = 2
|
||||
item_state = "flight"
|
||||
flags = FPRINT | TABLEPASS | CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
m_amt = 50
|
||||
g_amt = 20
|
||||
icon_action_button = "action_flashlight"
|
||||
var/on = 0
|
||||
var/brightness_on = 4 //luminosity when on
|
||||
var/icon_on = "flight1"
|
||||
var/icon_off = "flight0"
|
||||
|
||||
/obj/item/device/flashlight/initialize()
|
||||
..()
|
||||
if (on)
|
||||
icon_state = icon_on
|
||||
src.SetLuminosity(brightness_on)
|
||||
else
|
||||
icon_state = icon_off
|
||||
src.SetLuminosity(0)
|
||||
|
||||
/obj/item/device/flashlight/proc/update_brightness(var/mob/user = null)
|
||||
if(on)
|
||||
icon_state = icon_on
|
||||
if(src.loc == user)
|
||||
user.SetLuminosity(user.luminosity + brightness_on)
|
||||
else if(isturf(loc))
|
||||
SetLuminosity(brightness_on)
|
||||
else
|
||||
icon_state = icon_off
|
||||
if(src.loc == user)
|
||||
user.SetLuminosity(user.luminosity - brightness_on)
|
||||
else if(isturf(loc))
|
||||
SetLuminosity(0)
|
||||
|
||||
/obj/item/device/flashlight/attack_self(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities.
|
||||
return
|
||||
on = !on
|
||||
update_brightness(user)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/flashlight/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
if(src.on && user.zone_sel.selecting == "eyes")
|
||||
|
||||
if (((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))//too dumb to use flashlight properly
|
||||
return ..()//just hit them in the head
|
||||
|
||||
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")//don't have dexterity
|
||||
usr.show_message("\red You don't have the dexterity to do this!",1)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = M//mob has protective eyewear
|
||||
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
|
||||
user << text("\blue You're going to need to remove that [] first.", ((H.head && H.head.flags & HEADCOVERSEYES) ? "helmet" : ((H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) ? "mask": "glasses")))
|
||||
return
|
||||
|
||||
for(var/mob/O in viewers(M, null))//echo message
|
||||
if ((O.client && !(O.blinded )))
|
||||
O.show_message("\blue [(O==user?"You direct":"[user] directs")] [src] to [(M==user? "your":"[M]")] eyes", 1)
|
||||
|
||||
if(istype(M, /mob/living/carbon/human) || istype(M, /mob/living/carbon/monkey))//robots and aliens are unaffected
|
||||
if(M.stat == DEAD || M.sdisabilities & BLIND)//mob is dead or fully blind
|
||||
if(M!=user)
|
||||
user.show_message("\red [M] pupils does not react to the light!",1)
|
||||
else if(XRAY in M.mutations)//mob has X-RAY vision
|
||||
if(M!=user)
|
||||
user.show_message("\red [M] pupils give an eerie glow!",1)
|
||||
else //nothing wrong
|
||||
if(!M.blinded)
|
||||
flick("flash", M.flash)//flash the affected mob
|
||||
if(M!=user)
|
||||
user.show_message("\blue [M] pupils narrow",1)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/device/flashlight/pickup(mob/user)
|
||||
if(on)
|
||||
user.SetLuminosity(user.luminosity + brightness_on)
|
||||
SetLuminosity(0)
|
||||
|
||||
|
||||
/obj/item/device/flashlight/dropped(mob/user)
|
||||
if(on)
|
||||
user.SetLuminosity(user.luminosity - brightness_on)
|
||||
SetLuminosity(brightness_on)
|
||||
|
||||
|
||||
/obj/item/device/flashlight/pen
|
||||
name = "penlight"
|
||||
desc = "A pen-sized light. It shines as well as a flashlight."
|
||||
icon_state = "plight0"
|
||||
flags = FPRINT | TABLEPASS | CONDUCT
|
||||
item_state = ""
|
||||
icon_on = "plight1"
|
||||
icon_off = "plight0"
|
||||
brightness_on = 3
|
||||
|
||||
|
||||
|
||||
/obj/item/device/flashlight/pen/paralysis/attack(mob/M as mob, mob/user as mob)
|
||||
if(!ismob(M))
|
||||
return
|
||||
user << "\red You stab [M] with the pen."
|
||||
M << "\red You feel a tiny prick!"
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been stabbed with [src.name] by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to stab [M.name] ([M.ckey])</font>")
|
||||
|
||||
log_attack("<font color='red'>[user.name] ([user.ckey]) Used the [src.name] to stab [M.name] ([M.ckey])</font>")
|
||||
|
||||
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/device/flashlight/pen/paralysis/New()
|
||||
var/datum/reagents/R = new/datum/reagents(15)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("zombiepowder", 15)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/device/flashlight/pen/paralysis/attack(mob/M as mob, mob/user as mob)
|
||||
if (!( istype(M, /mob) ))
|
||||
return
|
||||
..()
|
||||
if (reagents.total_volume)
|
||||
if(M.reagents) reagents.trans_to(M, 15)
|
||||
return
|
||||
|
||||
// the desk lamps are a bit special
|
||||
/obj/item/device/flashlight/lamp
|
||||
name = "desk lamp"
|
||||
desc = "A desk lamp"
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "lamp0"
|
||||
brightness_on = 5
|
||||
icon_on = "lamp1"
|
||||
icon_off = "lamp0"
|
||||
w_class = 4
|
||||
flags = FPRINT | TABLEPASS | CONDUCT
|
||||
m_amt = 0
|
||||
g_amt = 0
|
||||
on = 1
|
||||
|
||||
// green-shaded desk lamp
|
||||
/obj/item/device/flashlight/lamp/green
|
||||
icon_state = "green0"
|
||||
icon_on = "green1"
|
||||
icon_off = "green0"
|
||||
desc = "A green-shaded desk lamp"
|
||||
|
||||
/obj/item/device/flashlight/lamp/verb/toggle_light()
|
||||
set name = "Toggle light"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(!usr.stat)
|
||||
attack_self(usr)
|
||||
@@ -0,0 +1,210 @@
|
||||
|
||||
// Light Replacer (LR)
|
||||
//
|
||||
// ABOUT THE DEVICE
|
||||
//
|
||||
// This is a device supposedly to be used by Janitors and Janitor Cyborgs which will
|
||||
// allow them to easily replace lights. This was mostly designed for Janitor Cyborgs since
|
||||
// they don't have hands or a way to replace lightbulbs.
|
||||
//
|
||||
// HOW IT WORKS
|
||||
//
|
||||
// You attack a light fixture with it, if the light fixture is broken it will replace the
|
||||
// light fixture with a working light; the broken light is then placed on the floor for the
|
||||
// user to then pickup with a trash bag. If it's empty then it will just place a light in the fixture.
|
||||
//
|
||||
// HOW TO REFILL THE DEVICE
|
||||
//
|
||||
// It will need to be manually refilled with lights.
|
||||
// If it's part of a robot module, it will charge when the Robot is inside a Recharge Station.
|
||||
//
|
||||
// EMAGGED FEATURES
|
||||
//
|
||||
// NOTICE: The Cyborg cannot use the emagged Light Replacer and the light's explosion was nerfed. It cannot create holes in the station anymore.
|
||||
//
|
||||
// I'm not sure everyone will react the emag's features so please say what your opinions are of it.
|
||||
//
|
||||
// When emagged it will rig every light it replaces, which will explode when the light is on.
|
||||
// This is VERY noticable, even the device's name changes when you emag it so if anyone
|
||||
// examines you when you're holding it in your hand, you will be discovered.
|
||||
// It will also be very obvious who is setting all these lights off, since only Janitor Borgs and Janitors have easy
|
||||
// access to them, and only one of them can emag their device.
|
||||
//
|
||||
// The explosion cannot insta-kill anyone with 30% or more health.
|
||||
|
||||
#define LIGHT_OK 0
|
||||
#define LIGHT_EMPTY 1
|
||||
#define LIGHT_BROKEN 2
|
||||
#define LIGHT_BURNED 3
|
||||
|
||||
|
||||
/obj/item/device/lightreplacer
|
||||
|
||||
name = "light replacer"
|
||||
desc = "A device to automatically replace lights. Refill with working lightbulbs."
|
||||
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "lightreplacer0"
|
||||
item_state = "electronic"
|
||||
|
||||
flags = FPRINT | CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "magnets=3;materials=2"
|
||||
|
||||
var/max_uses = 20
|
||||
var/uses = 0
|
||||
var/inuse = 0
|
||||
var/emagged = 0
|
||||
var/failmsg = ""
|
||||
// How much to increase per each glass?
|
||||
var/increment = 5
|
||||
// How much to take from the glass?
|
||||
var/decrement = 1
|
||||
var/charge = 1
|
||||
|
||||
/obj/item/device/lightreplacer/New()
|
||||
uses = max_uses / 2
|
||||
failmsg = "The [name]'s refill light blinks red."
|
||||
..()
|
||||
|
||||
/obj/item/device/lightreplacer/examine()
|
||||
set src in view(2)
|
||||
..()
|
||||
usr << "It has [uses] lights remaining."
|
||||
|
||||
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/weapon/card/emag) && emagged == 0)
|
||||
Emag()
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = W
|
||||
if(G.amount - decrement >= 0 && uses < max_uses)
|
||||
var/remaining = max(G.amount - decrement, 0)
|
||||
if(!remaining && !(G.amount - decrement) == 0)
|
||||
user << "There isn't enough glass."
|
||||
return
|
||||
G.amount = remaining
|
||||
if(!G.amount)
|
||||
user.drop_item()
|
||||
del(G)
|
||||
AddUses(increment)
|
||||
user << "You insert a piece of glass into the [src.name]. You have [uses] lights remaining."
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/light))
|
||||
var/obj/item/weapon/light/L = W
|
||||
if(L.status == 0) // LIGHT OKAY
|
||||
if(uses < max_uses)
|
||||
AddUses(1)
|
||||
user << "You insert the [L.name] into the [src.name]. You have [uses] lights remaining."
|
||||
user.drop_item()
|
||||
del(L)
|
||||
return
|
||||
else
|
||||
user << "You need a working light."
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/lightreplacer/attack_self(mob/user)
|
||||
/* // This would probably be a bit OP. If you want it though, uncomment the code.
|
||||
if(isrobot(user))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(R.emagged)
|
||||
src.Emag()
|
||||
usr << "You shortcircuit the [src]."
|
||||
return
|
||||
*/
|
||||
usr << "It has [uses] lights remaining."
|
||||
|
||||
/obj/item/device/lightreplacer/update_icon()
|
||||
icon_state = "lightreplacer[emagged]"
|
||||
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Use(var/mob/user)
|
||||
|
||||
if(inuse) return
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
var/pass = 0
|
||||
inuse = 1
|
||||
if(do_after(user, 30))
|
||||
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
AddUses(-1)
|
||||
pass = 1
|
||||
inuse = 0
|
||||
return pass
|
||||
|
||||
// Negative numbers will subtract
|
||||
/obj/item/device/lightreplacer/proc/AddUses(var/amount = 1)
|
||||
uses = min(max(uses + amount, 0), max_uses)
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Charge(var/mob/user)
|
||||
charge += 1
|
||||
if(charge > 7)
|
||||
AddUses(1)
|
||||
charge = 1
|
||||
|
||||
/obj/item/device/lightreplacer/proc/ReplaceLight(var/obj/machinery/light/target, var/mob/living/U)
|
||||
|
||||
if(target.status != LIGHT_OK)
|
||||
if(CanUse(U))
|
||||
if(!Use(U)) return
|
||||
U << "<span class='notice'>You replace the [target.fitting] with the [src].</span>"
|
||||
|
||||
if(target.status != LIGHT_EMPTY)
|
||||
|
||||
var/obj/item/weapon/light/L1 = new target.light_type(target.loc)
|
||||
L1.status = target.status
|
||||
L1.rigged = target.rigged
|
||||
L1.brightness = target.brightness
|
||||
L1.switchcount = target.switchcount
|
||||
target.switchcount = 0
|
||||
L1.update()
|
||||
|
||||
target.status = LIGHT_EMPTY
|
||||
target.update()
|
||||
|
||||
var/obj/item/weapon/light/L2 = new target.light_type()
|
||||
|
||||
target.status = L2.status
|
||||
target.switchcount = L2.switchcount
|
||||
target.rigged = emagged
|
||||
target.brightness = L2.brightness
|
||||
target.on = target.has_power()
|
||||
target.update()
|
||||
del(L2)
|
||||
|
||||
if(target.on && target.rigged)
|
||||
target.explode()
|
||||
return
|
||||
|
||||
else
|
||||
U << failmsg
|
||||
return
|
||||
else
|
||||
U << "There is a working [target.fitting] already inserted."
|
||||
return
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Emag()
|
||||
emagged = !emagged
|
||||
playsound(src.loc, "sparks", 100, 1)
|
||||
if(emagged)
|
||||
name = "Shortcircuited [initial(name)]"
|
||||
else
|
||||
name = initial(name)
|
||||
update_icon()
|
||||
|
||||
//Can you use it?
|
||||
|
||||
/obj/item/device/lightreplacer/proc/CanUse(var/mob/living/user)
|
||||
src.add_fingerprint(user)
|
||||
//Not sure what else to check for. Maybe if clumsy?
|
||||
if(uses > 0)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
#undef LIGHT_OK
|
||||
#undef LIGHT_EMPTY
|
||||
#undef LIGHT_BROKEN
|
||||
#undef LIGHT_BURNED
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Multitool -- A multitool is used for hacking electronic devices.
|
||||
* TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
|
||||
*
|
||||
*/
|
||||
/obj/item/device/multitool
|
||||
name = "multitool"
|
||||
icon_state = "multitool"
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
force = 5.0
|
||||
w_class = 2.0
|
||||
throwforce = 5.0
|
||||
throw_range = 15
|
||||
throw_speed = 3
|
||||
desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
|
||||
m_amt = 50
|
||||
g_amt = 20
|
||||
origin_tech = "magnets=1"
|
||||
@@ -0,0 +1,136 @@
|
||||
/obj/item/device/paicard
|
||||
name = "personal AI device"
|
||||
icon = 'icons/obj/pda.dmi'
|
||||
icon_state = "pai"
|
||||
item_state = "electronic"
|
||||
w_class = 2.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "programming=2"
|
||||
var/obj/item/device/radio/radio
|
||||
var/looking_for_personality = 0
|
||||
var/mob/living/silicon/pai/pai
|
||||
|
||||
/obj/item/device/paicard/New()
|
||||
..()
|
||||
overlays += "pai-off"
|
||||
|
||||
/obj/item/device/paicard/Del()
|
||||
//Will stop people throwing friend pAIs into the singularity so they can respawn
|
||||
if(!isnull(pai))
|
||||
pai.death(0)
|
||||
..()
|
||||
|
||||
/obj/item/device/paicard/attack_self(mob/user)
|
||||
if (!in_range(src, user))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<TT><B>Personal AI Device</B><BR>"
|
||||
if(pai && (!pai.master_dna || !pai.master))
|
||||
dat += "<a href='byond://?src=\ref[src];setdna=1'>Imprint Master DNA</a><br>"
|
||||
if(pai)
|
||||
dat += "Installed Personality: [pai.name]<br>"
|
||||
dat += "Prime directive: <br>[pai.pai_law0]<br>"
|
||||
dat += "Additional directives: <br>[pai.pai_laws]<br>"
|
||||
dat += "<a href='byond://?src=\ref[src];setlaws=1'>Configure Directives</a><br>"
|
||||
dat += "<br>"
|
||||
dat += "<h3>Device Settings</h3><br>"
|
||||
if(radio)
|
||||
dat += "<b>Radio Uplink</b><br>"
|
||||
dat += "Transmit: <A href='byond://?src=\ref[src];wires=4'>[(radio.wires & 4) ? "Enabled" : "Disabled"]</A><br>"
|
||||
dat += "Receive: <A href='byond://?src=\ref[src];wires=2'>[(radio.wires & 2) ? "Enabled" : "Disabled"]</A><br>"
|
||||
dat += "Signal Pulser: <A href='byond://?src=\ref[src];wires=1'>[(radio.wires & 1) ? "Enabled" : "Disabled"]</A><br>"
|
||||
else
|
||||
dat += "<b>Radio Uplink</b><br>"
|
||||
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
|
||||
dat += "<A href='byond://?src=\ref[src];wipe=1'>\[Wipe current pAI personality\]</a><br>"
|
||||
else
|
||||
if(looking_for_personality)
|
||||
dat += "Searching for a personality..."
|
||||
dat += "<A href='byond://?src=\ref[src];request=1'>\[View available personalities\]</a><br>"
|
||||
else
|
||||
dat += "No personality is installed.<br>"
|
||||
dat += "<A href='byond://?src=\ref[src];request=1'>\[Request personal AI personality\]</a><br>"
|
||||
dat += "Each time this button is pressed, a request will be sent out to any available personalities. Check back often and alot time for personalities to respond. This process could take anywhere from 15 seconds to several minutes, depending on the available personalities' timeliness."
|
||||
user << browse(dat, "window=paicard")
|
||||
onclose(user, "paicard")
|
||||
return
|
||||
|
||||
/obj/item/device/paicard/Topic(href, href_list)
|
||||
|
||||
if(href_list["setdna"])
|
||||
if(pai.master_dna)
|
||||
return
|
||||
var/mob/M = usr
|
||||
if(!istype(M, /mob/living/carbon))
|
||||
usr << "<font color=blue>You don't have any DNA, or your DNA is incompatible with this device.</font>"
|
||||
else
|
||||
var/datum/dna/dna = usr.dna
|
||||
pai.master = M.real_name
|
||||
pai.master_dna = dna.unique_enzymes
|
||||
pai << "<font color = red><h3>You have been bound to a new master.</h3></font>"
|
||||
if(href_list["request"])
|
||||
src.looking_for_personality = 1
|
||||
paiController.findPAI(src, usr)
|
||||
if(href_list["wipe"])
|
||||
var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
for(var/mob/M in src)
|
||||
M << "<font color = #ff0000><h2>You feel yourself slipping away from reality.</h2></font>"
|
||||
M << "<font color = #ff4d4d><h3>Byte by byte you lose your sense of self.</h3></font>"
|
||||
M << "<font color = #ff8787><h4>Your mental faculties leave you.</h4></font>"
|
||||
M << "<font color = #ffc4c4><h5>oblivion... </h5></font>"
|
||||
M.death(0)
|
||||
removePersonality()
|
||||
if(href_list["wires"])
|
||||
var/t1 = text2num(href_list["wires"])
|
||||
if (radio.wires & t1)
|
||||
radio.wires &= ~t1
|
||||
else
|
||||
radio.wires |= t1
|
||||
if(href_list["setlaws"])
|
||||
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) as message),1,MAX_MESSAGE_LEN)
|
||||
if(newlaws)
|
||||
pai.pai_laws = newlaws
|
||||
pai << "Your supplemental directives have been updated. Your new directives are:"
|
||||
pai << "Prime Directive : <br>[pai.pai_law0]"
|
||||
pai << "Supplemental Directives: <br>[pai.pai_laws]"
|
||||
attack_self(usr)
|
||||
|
||||
// WIRE_SIGNAL = 1
|
||||
// WIRE_RECEIVE = 2
|
||||
// WIRE_TRANSMIT = 4
|
||||
|
||||
/obj/item/device/paicard/proc/setPersonality(mob/living/silicon/pai/personality)
|
||||
src.pai = personality
|
||||
src.overlays += "pai-happy"
|
||||
|
||||
/obj/item/device/paicard/proc/removePersonality()
|
||||
src.pai = null
|
||||
src.overlays = null
|
||||
src.overlays += "pai-off"
|
||||
|
||||
/obj/item/device/paicard/proc/setEmotion(var/emotion)
|
||||
if(pai)
|
||||
src.overlays = null
|
||||
switch(emotion)
|
||||
if(1) src.overlays += "pai-happy"
|
||||
if(2) src.overlays += "pai-cat"
|
||||
if(3) src.overlays += "pai-extremely-happy"
|
||||
if(4) src.overlays += "pai-face"
|
||||
if(5) src.overlays += "pai-laugh"
|
||||
if(6) src.overlays += "pai-off"
|
||||
if(7) src.overlays += "pai-sad"
|
||||
if(8) src.overlays += "pai-angry"
|
||||
if(9) src.overlays += "pai-what"
|
||||
|
||||
/obj/item/device/paicard/proc/alertUpdate()
|
||||
var/turf/T = get_turf_or_move(src.loc)
|
||||
for (var/mob/M in viewers(T))
|
||||
M.show_message("\blue [src] flashes a message across its screen, \"Additional personalities available for download.\"", 3, "\blue [src] bleeps electronically.", 2)
|
||||
|
||||
/obj/item/device/paicard/emp_act(severity)
|
||||
for(var/mob/M in src)
|
||||
M.emp_act(severity)
|
||||
..()
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
// Powersink - used to drain station power
|
||||
|
||||
/obj/item/device/powersink
|
||||
desc = "A nulling power sink which drains energy from electrical systems."
|
||||
name = "power sink"
|
||||
icon_state = "powersink0"
|
||||
item_state = "electronic"
|
||||
w_class = 4.0
|
||||
flags = FPRINT | TABLEPASS | CONDUCT
|
||||
throwforce = 5
|
||||
throw_speed = 1
|
||||
throw_range = 2
|
||||
m_amt = 750
|
||||
w_amt = 750
|
||||
origin_tech = "powerstorage=3;syndicate=5"
|
||||
var/drain_rate = 600000 // amount of power to drain per tick
|
||||
var/power_drained = 0 // has drained this much power
|
||||
var/max_power = 1e8 // maximum power that can be drained before exploding
|
||||
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
|
||||
|
||||
|
||||
var/obj/structure/cable/attached // the attached cable
|
||||
|
||||
attackby(var/obj/item/I, var/mob/user)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(mode == 0)
|
||||
var/turf/T = loc
|
||||
if(isturf(T) && !T.intact)
|
||||
attached = locate() in T
|
||||
if(!attached)
|
||||
user << "No exposed cable here to attach to."
|
||||
return
|
||||
else
|
||||
anchored = 1
|
||||
mode = 1
|
||||
user << "You attach the device to the cable."
|
||||
for(var/mob/M in viewers(user))
|
||||
if(M == user) continue
|
||||
M << "[user] attaches the power sink to the cable."
|
||||
return
|
||||
else
|
||||
user << "Device must be placed over an exposed cable to attach to it."
|
||||
return
|
||||
else
|
||||
if (mode == 2)
|
||||
processing_objects.Remove(src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite
|
||||
anchored = 0
|
||||
mode = 0
|
||||
user << "You detach the device from the cable."
|
||||
for(var/mob/M in viewers(user))
|
||||
if(M == user) continue
|
||||
M << "[user] detaches the power sink from the cable."
|
||||
SetLuminosity(0)
|
||||
icon_state = "powersink0"
|
||||
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
|
||||
attack_paw()
|
||||
return
|
||||
|
||||
attack_ai()
|
||||
return
|
||||
|
||||
attack_hand(var/mob/user)
|
||||
switch(mode)
|
||||
if(0)
|
||||
..()
|
||||
|
||||
if(1)
|
||||
user << "You activate the device!"
|
||||
for(var/mob/M in viewers(user))
|
||||
if(M == user) continue
|
||||
M << "[user] activates the power sink!"
|
||||
mode = 2
|
||||
icon_state = "powersink1"
|
||||
processing_objects.Add(src)
|
||||
|
||||
if(2) //This switch option wasn't originally included. It exists now. --NeoFite
|
||||
user << "You deactivate the device!"
|
||||
for(var/mob/M in viewers(user))
|
||||
if(M == user) continue
|
||||
M << "[user] deactivates the power sink!"
|
||||
mode = 1
|
||||
SetLuminosity(0)
|
||||
icon_state = "powersink0"
|
||||
processing_objects.Remove(src)
|
||||
|
||||
process()
|
||||
if(attached)
|
||||
var/datum/powernet/PN = attached.get_powernet()
|
||||
if(PN)
|
||||
SetLuminosity(12)
|
||||
|
||||
// found a powernet, so drain up to max power from it
|
||||
|
||||
var/drained = min ( drain_rate, PN.avail )
|
||||
PN.newload += drained
|
||||
power_drained += drained
|
||||
|
||||
// if tried to drain more than available on powernet
|
||||
// now look for APCs and drain their cells
|
||||
if(drained < drain_rate)
|
||||
for(var/obj/machinery/power/terminal/T in PN.nodes)
|
||||
if(istype(T.master, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/A = T.master
|
||||
if(A.operating && A.cell)
|
||||
A.cell.charge = max(0, A.cell.charge - 50)
|
||||
power_drained += 50
|
||||
|
||||
|
||||
if(power_drained > max_power * 0.95)
|
||||
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
|
||||
if(power_drained >= max_power)
|
||||
processing_objects.Remove(src)
|
||||
explosion(src.loc, 3,6,9,12)
|
||||
del(src)
|
||||
@@ -0,0 +1,49 @@
|
||||
/obj/item/device/radio/beacon
|
||||
name = "Tracking Beacon"
|
||||
desc = "A beacon used by a teleporter."
|
||||
icon_state = "beacon"
|
||||
item_state = "signaler"
|
||||
var/code = "electronic"
|
||||
origin_tech = "bluespace=1"
|
||||
|
||||
/obj/item/device/radio/beacon/hear_talk()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/radio/beacon/send_hear()
|
||||
return null
|
||||
|
||||
|
||||
/obj/item/device/radio/beacon/verb/alter_signal(t as text)
|
||||
set name = "Alter Beacon's Signal"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if ((usr.canmove && !( usr.restrained() )))
|
||||
src.code = t
|
||||
if (!( src.code ))
|
||||
src.code = "beacon"
|
||||
src.add_fingerprint(usr)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/radio/beacon/bacon //Probably a better way of doing this, I'm lazy.
|
||||
proc/digest_delay()
|
||||
spawn(600)
|
||||
del(src)
|
||||
|
||||
|
||||
// SINGULO BEACON SPAWNER
|
||||
|
||||
/obj/item/device/radio/beacon/syndicate
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Activate to have a singularity beacon teleported to your location</i>."
|
||||
origin_tech = "bluespace=1;syndicate=7"
|
||||
|
||||
/obj/item/device/radio/beacon/syndicate/attack_self(mob/user as mob)
|
||||
if(user)
|
||||
user << "\blue Locked In"
|
||||
new /obj/machinery/singularity_beacon/syndicate( user.loc )
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
del(src)
|
||||
return
|
||||
@@ -0,0 +1,164 @@
|
||||
/obj/item/device/radio/electropack
|
||||
name = "Electropack"
|
||||
desc = "Dance my monkeys! DANCE!!!"
|
||||
icon_state = "electropack0"
|
||||
var/code = 2
|
||||
var/e_pads = 0.0
|
||||
g_amt = 2500
|
||||
m_amt = 10000
|
||||
frequency = 1449
|
||||
w_class = 5.0
|
||||
flags = FPRINT | CONDUCT | TABLEPASS
|
||||
slot_flags = SLOT_BACK
|
||||
item_state = "electropack"
|
||||
|
||||
/obj/item/device/radio/electropack/examine()
|
||||
set src in view()
|
||||
|
||||
..()
|
||||
if ((in_range(src, usr) || src.loc == usr))
|
||||
if (src.e_pads)
|
||||
usr << "\blue The electric pads are exposed!"
|
||||
return
|
||||
|
||||
/obj/item/device/radio/electropack/attack_paw(mob/user as mob)
|
||||
|
||||
return src.attack_hand(user)
|
||||
return
|
||||
|
||||
/obj/item/device/radio/electropack/attack_hand(mob/user as mob)
|
||||
|
||||
if (src == user.back)
|
||||
user << "\blue You need help taking this off!"
|
||||
return
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/device/radio/electropack/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
|
||||
if (istype(W, /obj/item/weapon/screwdriver))
|
||||
src.e_pads = !( src.e_pads )
|
||||
if (src.e_pads)
|
||||
user.show_message("\blue The electric pads have been exposed!")
|
||||
else
|
||||
user.show_message("\blue The electric pads have been reinserted!")
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
else
|
||||
if (istype(W, /obj/item/clothing/head/helmet))
|
||||
var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user )
|
||||
A.icon = 'icons/obj/assemblies.dmi'
|
||||
|
||||
user.drop_from_inventory(W)
|
||||
W.loc = A
|
||||
W.master = A
|
||||
A.part1 = W
|
||||
|
||||
user.drop_from_inventory(src)
|
||||
src.loc = A
|
||||
src.master = A
|
||||
A.part2 = src
|
||||
|
||||
user.put_in_hands(A)
|
||||
A.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/device/radio/electropack/Topic(href, href_list)
|
||||
//..()
|
||||
if (usr.stat || usr.restrained())
|
||||
return
|
||||
if (((istype(usr, /mob/living/carbon/human) && ((!( ticker ) || (ticker && ticker.mode != "monkey")) && usr.contents.Find(src))) || (usr.contents.Find(src.master) || (in_range(src, usr) && istype(src.loc, /turf)))))
|
||||
usr.machine = src
|
||||
if (href_list["freq"])
|
||||
var/new_frequency = sanitize_frequency(frequency + text2num(href_list["freq"]))
|
||||
set_frequency(new_frequency)
|
||||
else
|
||||
if (href_list["code"])
|
||||
src.code += text2num(href_list["code"])
|
||||
src.code = round(src.code)
|
||||
src.code = min(100, src.code)
|
||||
src.code = max(1, src.code)
|
||||
else
|
||||
if (href_list["power"])
|
||||
src.on = !( src.on )
|
||||
src.icon_state = text("electropack[]", src.on)
|
||||
if (!( src.master ))
|
||||
if (istype(src.loc, /mob))
|
||||
attack_self(src.loc)
|
||||
else
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if (M.client)
|
||||
src.attack_self(M)
|
||||
//Foreach goto(308)
|
||||
else
|
||||
if (istype(src.master.loc, /mob))
|
||||
src.attack_self(src.master.loc)
|
||||
else
|
||||
for(var/mob/M in viewers(1, src.master))
|
||||
if (M.client)
|
||||
src.attack_self(M)
|
||||
//Foreach goto(384)
|
||||
else
|
||||
usr << browse(null, "window=radio")
|
||||
return
|
||||
return
|
||||
/*
|
||||
/obj/item/device/radio/electropack/accept_rad(obj/item/device/radio/signaler/R as obj, message)
|
||||
|
||||
if ((istype(R, /obj/item/device/radio/signaler) && R.frequency == src.frequency && R.code == src.code))
|
||||
return 1
|
||||
else
|
||||
return null
|
||||
return*/
|
||||
|
||||
/obj/item/device/radio/electropack/receive_signal(datum/signal/signal)
|
||||
if(!signal || (signal.encryption != code))
|
||||
return
|
||||
|
||||
if ((ismob(src.loc) && src.on))
|
||||
|
||||
var/mob/M = src.loc
|
||||
var/turf/T = M.loc
|
||||
if ((istype(T, /turf)))
|
||||
if (!M.moved_recently && M.last_move)
|
||||
M.moved_recently = 1
|
||||
step(M, M.last_move)
|
||||
sleep 50
|
||||
if(M)
|
||||
M.moved_recently = 0
|
||||
M.show_message("\red <B>You feel a sharp shock!</B>")
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, M)
|
||||
s.start()
|
||||
|
||||
M.Weaken(10)
|
||||
|
||||
if ((src.master && src.wires & 1))
|
||||
src.master.receive_signal()
|
||||
return
|
||||
|
||||
/obj/item/device/radio/electropack/attack_self(mob/user as mob, flag1)
|
||||
|
||||
if (!( istype(user, /mob/living/carbon/human) ))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = {"<TT>
|
||||
<A href='?src=\ref[src];power=1'>Turn [src.on ? "Off" : "On"]</A><BR>
|
||||
<B>Frequency/Code</B> for electropack:<BR>
|
||||
Frequency:
|
||||
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
||||
<A href='byond://?src=\ref[src];freq=-2'>-</A> [format_frequency(src.frequency)]
|
||||
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
||||
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
||||
|
||||
Code:
|
||||
<A href='byond://?src=\ref[src];code=-5'>-</A>
|
||||
<A href='byond://?src=\ref[src];code=-1'>-</A> [src.code]
|
||||
<A href='byond://?src=\ref[src];code=1'>+</A>
|
||||
<A href='byond://?src=\ref[src];code=5'>+</A><BR>
|
||||
</TT>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
@@ -0,0 +1,128 @@
|
||||
|
||||
/obj/item/device/encryptionkey/
|
||||
name = "Standard Encrpytion Key"
|
||||
desc = "An encyption key for a radio headset. Has no special codes in it. WHY DOES IT EXIST? ASK NANOTRASEN."
|
||||
icon = 'icons/obj/radio.dmi'
|
||||
icon_state = "cypherkey"
|
||||
item_state = ""
|
||||
var/translate_binary = 0
|
||||
var/translate_hive = 0
|
||||
var/syndie = 0
|
||||
var/list/channels = list()
|
||||
|
||||
|
||||
/obj/item/device/encryptionkey/New()
|
||||
|
||||
/obj/item/device/encryptionkey/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
/obj/item/device/encryptionkey/syndicate
|
||||
icon_state = "cypherkey"
|
||||
channels = list("Syndicate" = 1)
|
||||
origin_tech = "syndicate=3"
|
||||
syndie = 1//Signifies that it de-crypts Syndicate transmissions
|
||||
|
||||
/obj/item/device/encryptionkey/binary
|
||||
icon_state = "cypherkey"
|
||||
translate_binary = 1
|
||||
origin_tech = "syndicate=3"
|
||||
|
||||
/obj/item/device/encryptionkey/headset_sec
|
||||
name = "Security Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "sec_cypherkey"
|
||||
channels = list("Security" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/headset_eng
|
||||
name = "Engineering Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "eng_cypherkey"
|
||||
channels = list("Engineering" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/headset_rob
|
||||
name = "Robotics Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "rob_cypherkey"
|
||||
channels = list("Engineering" = 1, "Science" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/headset_med
|
||||
name = "Medical Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "med_cypherkey"
|
||||
channels = list("Medical" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/headset_sci
|
||||
name = "Science Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "sci_cypherkey"
|
||||
channels = list("Science" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/headset_medsci
|
||||
name = "Medical Research Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "medsci_cypherkey"
|
||||
channels = list("Medical" = 1, "Science" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/headset_com
|
||||
name = "Command Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "com_cypherkey"
|
||||
channels = list("Command" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/captain
|
||||
name = "Captain's Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "cap_cypherkey"
|
||||
channels = list("Command" = 1, "Science" = 0, "Medical" = 0, "Security" = 1, "Engineering" = 0, "Mining" = 0, "Cargo" = 0)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/rd
|
||||
name = "Research Director's Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "rd_cypherkey"
|
||||
channels = list("Science" = 1, "Command" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/hos
|
||||
name = "Head of Security's Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "hos_cypherkey"
|
||||
channels = list("Security" = 1, "Command" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/ce
|
||||
name = "Chief Engineer's Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "ce_cypherkey"
|
||||
channels = list("Engineering" = 1, "Command" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/cmo
|
||||
name = "Chief Medical Officer's Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "cmo_cypherkey"
|
||||
channels = list("Medical" = 1, "Command" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/hop
|
||||
name = "Head of Personnel's Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "hop_cypherkey"
|
||||
channels = list("Command" = 1, "Security" = 0, "Cargo" = 1, "Mining" = 0)
|
||||
|
||||
/obj/item/device/encryptionkey/headset_mine
|
||||
name = "Mining Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "mine_cypherkey"
|
||||
channels = list("Mining" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/qm
|
||||
name = "Quartermaster's Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "qm_cypherkey"
|
||||
channels = list("Cargo" = 1, "Mining" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/headset_cargo
|
||||
name = "Cargo Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
icon_state = "cargo_cypherkey"
|
||||
channels = list("Cargo" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/ert
|
||||
name = "NanoTrasen ERT Radio Encryption Key"
|
||||
desc = "An encyption key for a radio headset. Contains cypherkeys."
|
||||
channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Mining" = 1, "Cargo" = 1,)
|
||||
@@ -0,0 +1,264 @@
|
||||
/obj/item/device/radio/headset
|
||||
name = "radio headset"
|
||||
desc = "An updated, modular intercom that fits over the head. Takes encryption keys"
|
||||
icon_state = "headset"
|
||||
item_state = "headset"
|
||||
g_amt = 0
|
||||
m_amt = 75
|
||||
subspace_transmission = 1
|
||||
canhear_range = 1 // can't hear headsets from very far away
|
||||
|
||||
slot_flags = SLOT_EARS
|
||||
var/translate_binary = 0
|
||||
var/translate_hive = 0
|
||||
var/obj/item/device/encryptionkey/keyslot1 = null
|
||||
var/obj/item/device/encryptionkey/keyslot2 = null
|
||||
maxf = 1489
|
||||
|
||||
/obj/item/device/radio/headset/New()
|
||||
..()
|
||||
keyslot1 = new /obj/item/device/encryptionkey/
|
||||
recalculateChannels()
|
||||
|
||||
/obj/item/device/radio/headset/syndicate
|
||||
origin_tech = "syndicate=3"
|
||||
/obj/item/device/radio/headset/syndicate/New()
|
||||
..()
|
||||
del(keyslot1)
|
||||
keyslot1 = new /obj/item/device/encryptionkey/syndicate
|
||||
syndie = 1
|
||||
recalculateChannels()
|
||||
|
||||
/obj/item/device/radio/headset/binary
|
||||
origin_tech = "syndicate=3"
|
||||
/obj/item/device/radio/headset/binary/New()
|
||||
..()
|
||||
del(keyslot1)
|
||||
keyslot1 = new /obj/item/device/encryptionkey/binary
|
||||
recalculateChannels()
|
||||
|
||||
/obj/item/device/radio/headset/headset_sec
|
||||
name = "security radio headset"
|
||||
desc = "This is used by your elite security force. To access the security channel, use :s."
|
||||
icon_state = "sec_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_sec
|
||||
|
||||
/obj/item/device/radio/headset/headset_eng
|
||||
name = "engineering radio headset"
|
||||
desc = "When the engineers wish to chat like girls. To access the engineering channel, use :e. "
|
||||
icon_state = "eng_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_eng
|
||||
|
||||
/obj/item/device/radio/headset/headset_rob
|
||||
name = "robotics radio headset"
|
||||
desc = "Made specifically for the roboticists who cannot decide between departments. To access the engineering channel, use :e. For research, use :n."
|
||||
icon_state = "rob_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_rob
|
||||
|
||||
/obj/item/device/radio/headset/headset_med
|
||||
name = "medical radio headset"
|
||||
desc = "A headset for the trained staff of the medbay. To access the medical channel, use :m."
|
||||
icon_state = "med_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_med
|
||||
|
||||
/obj/item/device/radio/headset/headset_sci
|
||||
name = "science radio headset"
|
||||
desc = "A sciency headset. Like usual. To access the science channel, use :n."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_sci
|
||||
|
||||
/obj/item/device/radio/headset/headset_medsci
|
||||
name = "medical research radio headset"
|
||||
desc = "A headset that is a result of the mating between medical and science. To access the medical channel, use :m. For science, use :n."
|
||||
icon_state = "med_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_medsci
|
||||
|
||||
/obj/item/device/radio/headset/headset_com
|
||||
name = "command radio headset"
|
||||
desc = "A headset with a commanding channel. To access the command channel, use :c."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_com
|
||||
|
||||
/obj/item/device/radio/headset/heads/captain
|
||||
name = "captain's headset"
|
||||
desc = "The headset of the boss. Channels are as follows: :c - command, :s - security, :e - engineering, :d - mining, :q - cargo, :m - medical, :n - science."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/heads/captain
|
||||
|
||||
/obj/item/device/radio/headset/heads/rd
|
||||
name = "Research Director's headset"
|
||||
desc = "Headset of the researching God. To access the science channel, use :n. For command, use :c."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/heads/rd
|
||||
|
||||
/obj/item/device/radio/headset/heads/hos
|
||||
name = "head of security's headset"
|
||||
desc = "The headset of the man who protects your worthless lifes. To access the security channel, use :s. For command, use :c."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/heads/hos
|
||||
|
||||
/obj/item/device/radio/headset/heads/ce
|
||||
name = "chief engineer's headset"
|
||||
desc = "The headset of the guy who is in charge of morons. To access the engineering channel, use :e. For command, use :c."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/heads/ce
|
||||
|
||||
/obj/item/device/radio/headset/heads/cmo
|
||||
name = "chief medical officer's headset"
|
||||
desc = "The headset of the highly trained medical chief. To access the medical channel, use :m. For command, use :c."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/heads/cmo
|
||||
|
||||
/obj/item/device/radio/headset/heads/hop
|
||||
name = "head of personnel's headset"
|
||||
desc = "The headset of the guy who will one day be captain. Channels are as follows: :c - command, :s - security, :q - cargo, :d - mining."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/heads/hop
|
||||
|
||||
/obj/item/device/radio/headset/headset_mine
|
||||
name = "mining radio headset"
|
||||
desc = "Headset used by miners. How useless. To access the mining channel, use :d."
|
||||
icon_state = "mine_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_mine
|
||||
|
||||
/obj/item/device/radio/headset/heads/qm
|
||||
name = "quartermaster's headset"
|
||||
desc = "The headset of the man who control your toiletpaper supply. To access the cargo channel, use :q. For mining, use :d."
|
||||
icon_state = "cargo_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/heads/qm
|
||||
|
||||
/obj/item/device/radio/headset/headset_cargo
|
||||
name = "cargo radio headset"
|
||||
desc = "Headset used by the QM's slaves. To access the cargo channel, use :q."
|
||||
icon_state = "cargo_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_cargo
|
||||
|
||||
/obj/item/device/radio/headset/ert
|
||||
name = "CentCom Response Team headset"
|
||||
desc = "The headset of the boss's boss. Channels are as follows: :h - Response Team :c - command, :s - security, :e - engineering, :d - mining, :q - cargo, :m - medical, :n - science."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
freerange = 1
|
||||
keyslot2 = new /obj/item/device/encryptionkey/ert
|
||||
|
||||
/obj/item/device/radio/headset/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
// ..()
|
||||
user.machine = src
|
||||
if (!( istype(W, /obj/item/weapon/screwdriver) || (istype(W, /obj/item/device/encryptionkey/ ))))
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
if(keyslot1 || keyslot2)
|
||||
|
||||
|
||||
for(var/ch_name in channels)
|
||||
radio_controller.remove_object(src, radiochannels[ch_name])
|
||||
secure_radio_connections[ch_name] = null
|
||||
|
||||
|
||||
if(keyslot1)
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
keyslot1.loc = T
|
||||
keyslot1 = null
|
||||
|
||||
|
||||
|
||||
if(keyslot2)
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
keyslot2.loc = T
|
||||
keyslot2 = null
|
||||
|
||||
recalculateChannels()
|
||||
user << "You pop out the encryption keys in the headset!"
|
||||
|
||||
else
|
||||
user << "This headset doesn't have any encryption keys! How useless..."
|
||||
|
||||
if(istype(W, /obj/item/device/encryptionkey/))
|
||||
if(keyslot1 && keyslot2)
|
||||
user << "The headset can't hold another key!"
|
||||
return
|
||||
|
||||
if(!keyslot1)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
keyslot1 = W
|
||||
|
||||
else
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
keyslot2 = W
|
||||
|
||||
|
||||
recalculateChannels()
|
||||
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/radio/headset/proc/recalculateChannels()
|
||||
src.channels = list()
|
||||
src.translate_binary = 0
|
||||
src.translate_hive = 0
|
||||
src.syndie = 0
|
||||
|
||||
if(keyslot1)
|
||||
for(var/ch_name in keyslot1.channels)
|
||||
if(ch_name in src.channels)
|
||||
continue
|
||||
src.channels += ch_name
|
||||
src.channels[ch_name] = keyslot1.channels[ch_name]
|
||||
|
||||
if(keyslot1.translate_binary)
|
||||
src.translate_binary = 1
|
||||
|
||||
if(keyslot1.translate_hive)
|
||||
src.translate_hive = 1
|
||||
|
||||
if(keyslot1.syndie)
|
||||
src.syndie = 1
|
||||
|
||||
if(keyslot2)
|
||||
for(var/ch_name in keyslot2.channels)
|
||||
if(ch_name in src.channels)
|
||||
continue
|
||||
src.channels += ch_name
|
||||
src.channels[ch_name] = keyslot2.channels[ch_name]
|
||||
|
||||
if(keyslot2.translate_binary)
|
||||
src.translate_binary = 1
|
||||
|
||||
if(keyslot2.translate_hive)
|
||||
src.translate_hive = 1
|
||||
|
||||
if(keyslot2.syndie)
|
||||
src.syndie = 1
|
||||
|
||||
|
||||
for (var/ch_name in channels)
|
||||
if(!radio_controller)
|
||||
sleep(30) // Waiting for the radio_controller to be created.
|
||||
if(!radio_controller)
|
||||
src.name = "broken radio headset"
|
||||
return
|
||||
|
||||
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
|
||||
|
||||
return
|
||||
@@ -0,0 +1,73 @@
|
||||
/obj/item/device/radio/intercom
|
||||
name = "station intercom"
|
||||
desc = "Talk through this."
|
||||
icon_state = "intercom"
|
||||
anchored = 1
|
||||
w_class = 4.0
|
||||
canhear_range = 4
|
||||
var/number = 0
|
||||
var/anyai = 1
|
||||
var/mob/living/silicon/ai/ai = list()
|
||||
|
||||
/obj/item/device/radio/intercom/New()
|
||||
spawn(5)
|
||||
checkpower()
|
||||
..()
|
||||
|
||||
/obj/item/device/radio/intercom/attack_ai(mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
spawn (0)
|
||||
attack_self(user)
|
||||
|
||||
/obj/item/device/radio/intercom/attack_paw(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
|
||||
/obj/item/device/radio/intercom/attack_hand(mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
spawn (0)
|
||||
attack_self(user)
|
||||
|
||||
/obj/item/device/radio/intercom/receive_range(freq, level)
|
||||
if (!on)
|
||||
return 0
|
||||
if (!(src.wires & WIRE_RECEIVE))
|
||||
return 0
|
||||
if(level != 0)
|
||||
var/turf/position = get_turf(src)
|
||||
if(isnull(position) || position.z != level)
|
||||
return 0
|
||||
if (!src.listening)
|
||||
return 0
|
||||
if(freq == SYND_FREQ)
|
||||
if(!(src.syndie))
|
||||
return 0//Prevents broadcast of messages over devices lacking the encryption
|
||||
|
||||
return canhear_range
|
||||
|
||||
|
||||
/obj/item/device/radio/intercom/hear_talk(mob/M as mob, msg)
|
||||
if(!src.anyai && !(M in src.ai))
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/radio/intercom/proc/checkpower()
|
||||
|
||||
// Simple loop, checks for power. Strictly for intercoms
|
||||
while(src)
|
||||
|
||||
if(!src.loc)
|
||||
on = 0
|
||||
else
|
||||
var/area/A = src.loc.loc
|
||||
if(!A || !isarea(A) || !A.master)
|
||||
on = 0
|
||||
else
|
||||
on = A.master.powered(EQUIP) // set "on" to the power status
|
||||
|
||||
if(!on)
|
||||
icon_state = "intercom-p"
|
||||
else
|
||||
icon_state = "intercom"
|
||||
|
||||
sleep(30)
|
||||
@@ -0,0 +1,779 @@
|
||||
var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
||||
// 0 = old radios
|
||||
// 1 = new radios (subspace technology)
|
||||
|
||||
|
||||
/obj/item/device/radio
|
||||
icon = 'icons/obj/radio.dmi'
|
||||
name = "station bounced radio"
|
||||
suffix = "\[3\]"
|
||||
icon_state = "walkietalkie"
|
||||
item_state = "walkietalkie"
|
||||
var/on = 1 // 0 for off
|
||||
var/last_transmission
|
||||
var/frequency = 1459 //common chat
|
||||
var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies
|
||||
var/canhear_range = 3 // the range which mobs can hear this radio from
|
||||
var/obj/item/device/radio/patch_link = null
|
||||
var/wires = WIRE_SIGNAL | WIRE_RECEIVE | WIRE_TRANSMIT
|
||||
var/b_stat = 0
|
||||
var/broadcasting = 0
|
||||
var/listening = 1
|
||||
var/freerange = 0 // 0 - Sanitize frequencies, 1 - Full range
|
||||
var/list/channels = list() //see communications.dm for full list. First channes is a "default" for :h
|
||||
var/subspace_transmission = 0
|
||||
var/syndie = 0//Holder to see if it's a syndicate encrpyed radio
|
||||
var/maxf = 1499
|
||||
// "Example" = FREQ_LISTENING|FREQ_BROADCASTING
|
||||
flags = FPRINT | CONDUCT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
throw_speed = 2
|
||||
throw_range = 9
|
||||
w_class = 2
|
||||
g_amt = 25
|
||||
m_amt = 75
|
||||
var/const/WIRE_SIGNAL = 1 //sends a signal, like to set off a bomb or electrocute someone
|
||||
var/const/WIRE_RECEIVE = 2
|
||||
var/const/WIRE_TRANSMIT = 4
|
||||
var/const/TRANSMISSION_DELAY = 5 // only 2/second/radio
|
||||
var/const/FREQ_LISTENING = 1
|
||||
//FREQ_BROADCASTING = 2
|
||||
|
||||
/obj/item/device/radio
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/list/datum/radio_frequency/secure_radio_connections = new
|
||||
|
||||
proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
|
||||
|
||||
/obj/item/device/radio/New()
|
||||
..()
|
||||
if(radio_controller)
|
||||
initialize()
|
||||
|
||||
|
||||
/obj/item/device/radio/initialize()
|
||||
|
||||
if(freerange)
|
||||
if(frequency < 1200 || frequency > 1600)
|
||||
frequency = sanitize_frequency(frequency, maxf)
|
||||
// The max freq is higher than a regular headset to decrease the chance of people listening in, if you use the higher channels.
|
||||
else if (frequency < 1441 || frequency > maxf)
|
||||
//world.log << "[src] ([type]) has a frequency of [frequency], sanitizing."
|
||||
frequency = sanitize_frequency(frequency, maxf)
|
||||
|
||||
set_frequency(frequency)
|
||||
|
||||
for (var/ch_name in channels)
|
||||
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
|
||||
|
||||
|
||||
/obj/item/device/radio/attack_self(mob/user as mob)
|
||||
user.machine = src
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/radio/proc/interact(mob/user as mob)
|
||||
if(!on)
|
||||
return
|
||||
|
||||
if(active_uplink_check(user))
|
||||
return
|
||||
|
||||
var/dat = "<html><head><title>[src]</title></head><body><TT>"
|
||||
|
||||
if(!istype(src, /obj/item/device/radio/headset)) //Headsets dont get a mic button
|
||||
dat += "Microphone: [broadcasting ? "<A href='byond://?src=\ref[src];talk=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];talk=1'>Disengaged</A>"]<BR>"
|
||||
|
||||
dat += {"
|
||||
Speaker: [listening ? "<A href='byond://?src=\ref[src];listen=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];listen=1'>Disengaged</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>
|
||||
"}
|
||||
|
||||
for (var/ch_name in channels)
|
||||
dat+=text_sec_channel(ch_name, channels[ch_name])
|
||||
dat+={"[text_wires()]</TT></body></html>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
|
||||
/obj/item/device/radio/proc/text_wires()
|
||||
if (!b_stat)
|
||||
return ""
|
||||
return {"
|
||||
<hr>
|
||||
Green Wire: <A href='byond://?src=\ref[src];wires=4'>[(wires & 4) ? "Cut" : "Mend"] Wire</A><BR>
|
||||
Red Wire: <A href='byond://?src=\ref[src];wires=2'>[(wires & 2) ? "Cut" : "Mend"] Wire</A><BR>
|
||||
Blue Wire: <A href='byond://?src=\ref[src];wires=1'>[(wires & 1) ? "Cut" : "Mend"] Wire</A><BR>
|
||||
"}
|
||||
|
||||
|
||||
/obj/item/device/radio/proc/text_sec_channel(var/chan_name, var/chan_stat)
|
||||
var/list = !!(chan_stat&FREQ_LISTENING)!=0
|
||||
return {"
|
||||
<B>[chan_name]</B><br>
|
||||
Speaker: <A href='byond://?src=\ref[src];ch_name=[chan_name];listen=[!list]'>[list ? "Engaged" : "Disengaged"]</A><BR>
|
||||
"}
|
||||
|
||||
/obj/item/device/radio/Topic(href, href_list)
|
||||
//..()
|
||||
if (usr.stat || !on)
|
||||
return
|
||||
|
||||
if (!(issilicon(usr) || (usr.contents.Find(src) || ( in_range(src, usr) && istype(loc, /turf) ))))
|
||||
usr << browse(null, "window=radio")
|
||||
return
|
||||
usr.machine = src
|
||||
if (href_list["track"])
|
||||
var/mob/target = locate(href_list["track"])
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
||||
if(A && target)
|
||||
A.ai_actual_track(target)
|
||||
return
|
||||
|
||||
else if (href_list["faketrack"])
|
||||
var/mob/target = locate(href_list["track"])
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
||||
if(A && target)
|
||||
|
||||
A:cameraFollow = target
|
||||
A << text("Now tracking [] on camera.", target.name)
|
||||
if (usr.machine == null)
|
||||
usr.machine = usr
|
||||
|
||||
while (usr:cameraFollow == target)
|
||||
usr << "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb)."
|
||||
sleep(40)
|
||||
continue
|
||||
|
||||
return
|
||||
|
||||
else if (href_list["freq"])
|
||||
var/new_frequency = (frequency + text2num(href_list["freq"]))
|
||||
if (!freerange || (frequency < 1200 || frequency > 1600))
|
||||
new_frequency = sanitize_frequency(new_frequency, maxf)
|
||||
set_frequency(new_frequency)
|
||||
if(hidden_uplink)
|
||||
if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency))
|
||||
usr << browse(null, "window=radio")
|
||||
return
|
||||
|
||||
else if (href_list["talk"])
|
||||
broadcasting = text2num(href_list["talk"])
|
||||
else if (href_list["listen"])
|
||||
var/chan_name = href_list["ch_name"]
|
||||
if (!chan_name)
|
||||
listening = text2num(href_list["listen"])
|
||||
else
|
||||
if (channels[chan_name] & FREQ_LISTENING)
|
||||
channels[chan_name] &= ~FREQ_LISTENING
|
||||
else
|
||||
channels[chan_name] |= FREQ_LISTENING
|
||||
else if (href_list["wires"])
|
||||
var/t1 = text2num(href_list["wires"])
|
||||
if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
|
||||
return
|
||||
if (wires & t1)
|
||||
wires &= ~t1
|
||||
else
|
||||
wires |= t1
|
||||
if (!( master ))
|
||||
if (istype(loc, /mob))
|
||||
interact(loc)
|
||||
else
|
||||
updateDialog()
|
||||
else
|
||||
if (istype(master.loc, /mob))
|
||||
interact(master.loc)
|
||||
else
|
||||
updateDialog()
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/item/device/radio/talk_into(mob/M as mob, message, channel)
|
||||
|
||||
if(!on) return // the device has to be on
|
||||
// Fix for permacell radios, but kinda eh about actually fixing them.
|
||||
|
||||
// Uncommenting this. To the above comment:
|
||||
// The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom
|
||||
if(!(src.wires & WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
|
||||
return
|
||||
|
||||
|
||||
if(GLOBAL_RADIO_TYPE == 1) // NEW RADIO SYSTEMS: By Doohl
|
||||
|
||||
/* Quick introduction:
|
||||
This new radio system uses a very robust FTL signaling technology unoriginally
|
||||
dubbed "subspace" which is somewhat similar to 'blue-space' but can't
|
||||
actually transmit large mass. Headsets are the only radio devices capable
|
||||
of sending subspace transmissions to the Communications Satellite.
|
||||
|
||||
A headset sends a signal to a subspace listener/reciever elsewhere in space,
|
||||
the signal gets processed and logged, and an audible transmission gets sent
|
||||
to each individual headset.
|
||||
*/
|
||||
|
||||
//#### Grab the connection datum ####//
|
||||
var/datum/radio_frequency/connection = null
|
||||
if(channel && channels && channels.len > 0)
|
||||
if (channel == "department")
|
||||
//world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\""
|
||||
channel = channels[1]
|
||||
connection = secure_radio_connections[channel]
|
||||
else
|
||||
connection = radio_connection
|
||||
channel = null
|
||||
if (!istype(connection))
|
||||
return
|
||||
if (!connection)
|
||||
return
|
||||
|
||||
var/turf/position = get_turf(src)
|
||||
|
||||
//#### Tagging the signal with all appropriate identity values ####//
|
||||
|
||||
// ||-- The mob's name identity --||
|
||||
var/displayname = M.name // grab the display name (name you get when you hover over someone's icon)
|
||||
var/real_name = M.real_name // mob's real name
|
||||
var/mobkey = "none" // player key associated with mob
|
||||
var/voicemask = 0 // the speaker is wearing a voice mask
|
||||
if(M.client)
|
||||
mobkey = M.key // assign the mob's key
|
||||
|
||||
|
||||
var/jobname // the mob's "job"
|
||||
|
||||
// --- Human: use their actual job ---
|
||||
if (ishuman(M))
|
||||
jobname = M:get_assignment()
|
||||
|
||||
// --- Carbon Nonhuman ---
|
||||
else if (iscarbon(M)) // Nonhuman carbon mob
|
||||
jobname = "No id"
|
||||
|
||||
// --- AI ---
|
||||
else if (isAI(M))
|
||||
jobname = "AI"
|
||||
|
||||
// --- Cyborg ---
|
||||
else if (isrobot(M))
|
||||
jobname = "Cyborg"
|
||||
|
||||
// --- Personal AI (pAI) ---
|
||||
else if (istype(M, /mob/living/silicon/pai))
|
||||
jobname = "Personal AI"
|
||||
|
||||
// --- Unidentifiable mob ---
|
||||
else
|
||||
jobname = "Unknown"
|
||||
|
||||
|
||||
// --- Modifications to the mob's identity ---
|
||||
|
||||
// The mob is disguising their identity:
|
||||
if (istype(M.wear_mask, /obj/item/clothing/mask/gas/voice))
|
||||
if(M.wear_mask:vchange)
|
||||
displayname = M.wear_mask:voice
|
||||
jobname = "Unknown"
|
||||
voicemask = 1
|
||||
|
||||
|
||||
|
||||
/* ###### Radio headsets can only broadcast through subspace ###### */
|
||||
|
||||
if(subspace_transmission)
|
||||
// First, we want to generate a new radio signal
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 2 // 2 would be a subspace transmission.
|
||||
// transmission_method could probably be enumerated through #define. Would be neater.
|
||||
|
||||
// --- Finally, tag the actual signal with the appropriate values ---
|
||||
signal.data = list(
|
||||
// Identity-associated tags:
|
||||
"mob" = M, // store a reference to the mob
|
||||
"mobtype" = M.type, // the mob's type
|
||||
"realname" = real_name, // the mob's real name
|
||||
"name" = displayname, // the mob's display name
|
||||
"job" = jobname, // the mob's job
|
||||
"key" = mobkey, // the mob's key
|
||||
"vmessage" = M.voice_message, // the message to display if the voice wasn't understood
|
||||
"vname" = M.voice_name, // the name to display if the voice wasn't understood
|
||||
"vmask" = voicemask, // 1 if the mob is using a voice gas mask
|
||||
|
||||
// We store things that would otherwise be kept in the actual mob
|
||||
// so that they can be logged even AFTER the mob is deleted or something
|
||||
|
||||
// Other tags:
|
||||
"compression" = rand(45,50), // compressed radio signal
|
||||
"message" = message, // the actual sent message
|
||||
"connection" = connection, // the radio connection to use
|
||||
"radio" = src, // stores the radio used for transmission
|
||||
"slow" = 0, // how much to sleep() before broadcasting - simulates net lag
|
||||
"traffic" = 0, // dictates the total traffic sum that the signal went through
|
||||
"type" = 0, // determines what type of radio input it is: normal broadcast
|
||||
"server" = null, // the last server to log this signal
|
||||
"reject" = 0, // if nonzero, the signal will not be accepted by any broadcasting machinery
|
||||
"level" = position.z // The source's z level
|
||||
)
|
||||
signal.frequency = connection.frequency // Quick frequency set
|
||||
|
||||
//#### Sending the signal to all subspace receivers ####//
|
||||
|
||||
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
|
||||
R.receive_signal(signal)
|
||||
|
||||
// Allinone can act as receivers.
|
||||
for(var/obj/machinery/telecomms/allinone/R in telecomms_list)
|
||||
R.receive_signal(signal)
|
||||
|
||||
// Receiving code can be located in Telecommunications.dm
|
||||
return
|
||||
|
||||
|
||||
/* ###### Intercoms and station-bounced radios ###### */
|
||||
|
||||
var/filter_type = 2
|
||||
|
||||
/* --- Intercoms can only broadcast to other intercoms, but bounced radios can broadcast to bounced radios and intercoms --- */
|
||||
if(istype(src, /obj/item/device/radio/intercom))
|
||||
filter_type = 1
|
||||
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 2
|
||||
|
||||
|
||||
/* --- Try to send a normal subspace broadcast first */
|
||||
|
||||
signal.data = list(
|
||||
|
||||
"mob" = M, // store a reference to the mob
|
||||
"mobtype" = M.type, // the mob's type
|
||||
"realname" = real_name, // the mob's real name
|
||||
"name" = displayname, // the mob's display name
|
||||
"job" = jobname, // the mob's job
|
||||
"key" = mobkey, // the mob's key
|
||||
"vmessage" = M.voice_message, // the message to display if the voice wasn't understood
|
||||
"vname" = M.voice_name, // the name to display if the voice wasn't understood
|
||||
"vmask" = voicemask, // 1 if the mob is using a voice gas mas
|
||||
|
||||
"compression" = 0, // uncompressed radio signal
|
||||
"message" = message, // the actual sent message
|
||||
"connection" = connection, // the radio connection to use
|
||||
"radio" = src, // stores the radio used for transmission
|
||||
"slow" = 0,
|
||||
"traffic" = 0,
|
||||
"type" = 0,
|
||||
"server" = null,
|
||||
"reject" = 0,
|
||||
"level" = position.z
|
||||
)
|
||||
signal.frequency = connection.frequency // Quick frequency set
|
||||
|
||||
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
|
||||
R.receive_signal(signal)
|
||||
|
||||
|
||||
sleep(rand(10,25)) // wait a little...
|
||||
|
||||
if(signal.data["done"])
|
||||
// we're done here.
|
||||
return
|
||||
|
||||
// Oh my god; the comms are down or something because the signal hasn't been broadcasted yet.
|
||||
// Send a mundane broadcast with limited targets:
|
||||
|
||||
//THIS IS TEMPORARY.
|
||||
if(!connection) return //~Carn
|
||||
|
||||
Broadcast_Message(connection, M, voicemask, M.voice_message,
|
||||
src, message, displayname, jobname, real_name, M.voice_name,
|
||||
filter_type, signal.data["compression"], position.z)
|
||||
|
||||
|
||||
|
||||
else // OLD RADIO SYSTEMS: By Goons?
|
||||
|
||||
var/datum/radio_frequency/connection = null
|
||||
if(channel && channels && channels.len > 0)
|
||||
if (channel == "department")
|
||||
//world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\""
|
||||
channel = channels[1]
|
||||
connection = secure_radio_connections[channel]
|
||||
else
|
||||
connection = radio_connection
|
||||
channel = null
|
||||
if (!istype(connection))
|
||||
return
|
||||
var/display_freq = connection.frequency
|
||||
|
||||
//world << "DEBUG: used channel=\"[channel]\" frequency= \"[display_freq]\" connection.devices.len = [connection.devices.len]"
|
||||
|
||||
var/eqjobname
|
||||
|
||||
if (ishuman(M))
|
||||
eqjobname = M:get_assignment()
|
||||
else if (iscarbon(M))
|
||||
eqjobname = "No id" //only humans can wear ID
|
||||
else if (isAI(M))
|
||||
eqjobname = "AI"
|
||||
else if (isrobot(M))
|
||||
eqjobname = "Cyborg"//Androids don't really describe these too well, in my opinion.
|
||||
else if (istype(M, /mob/living/silicon/pai))
|
||||
eqjobname = "Personal AI"
|
||||
else
|
||||
eqjobname = "Unknown"
|
||||
|
||||
if (!(wires & WIRE_TRANSMIT))
|
||||
return
|
||||
|
||||
var/list/receive = list()
|
||||
|
||||
//for (var/obj/item/device/radio/R in radio_connection.devices)
|
||||
for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"]) // Modified for security headset code -- TLE
|
||||
//if(R.accept_rad(src, message))
|
||||
receive |= R.send_hear(display_freq, 0)
|
||||
|
||||
//world << "DEBUG: receive.len=[receive.len]"
|
||||
var/list/heard_masked = list() // masked name or no real name
|
||||
var/list/heard_normal = list() // normal message
|
||||
var/list/heard_voice = list() // voice message
|
||||
var/list/heard_garbled = list() // garbled message
|
||||
|
||||
for (var/mob/R in receive)
|
||||
if (R.client && R.client.STFU_radio) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios.
|
||||
continue
|
||||
if (R.say_understands(M))
|
||||
if (!ishuman(M) || istype(M.wear_mask, /obj/item/clothing/mask/gas/voice))
|
||||
heard_masked += R
|
||||
else
|
||||
heard_normal += R
|
||||
else
|
||||
if (M.voice_message)
|
||||
heard_voice += R
|
||||
else
|
||||
heard_garbled += R
|
||||
|
||||
if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled))
|
||||
var/part_a = "<span class='radio'><span class='name'>"
|
||||
//var/part_b = "</span><b> \icon[src]\[[format_frequency(frequency)]\]</b> <span class='message'>"
|
||||
var/freq_text
|
||||
switch(display_freq)
|
||||
if(SYND_FREQ)
|
||||
freq_text = "#unkn"
|
||||
if(COMM_FREQ)
|
||||
freq_text = "Command"
|
||||
if(1351)
|
||||
freq_text = "Science"
|
||||
if(1355)
|
||||
freq_text = "Medical"
|
||||
if(1357)
|
||||
freq_text = "Engineering"
|
||||
if(1359)
|
||||
freq_text = "Security"
|
||||
if(1349)
|
||||
freq_text = "Mining"
|
||||
if(1347)
|
||||
freq_text = "Cargo"
|
||||
//There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO
|
||||
|
||||
if(!freq_text)
|
||||
freq_text = format_frequency(display_freq)
|
||||
|
||||
var/part_b = "</span><b> \icon[src]\[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
|
||||
var/part_c = "</span></span>"
|
||||
|
||||
if (display_freq==SYND_FREQ)
|
||||
part_a = "<span class='syndradio'><span class='name'>"
|
||||
else if (display_freq==COMM_FREQ)
|
||||
part_a = "<span class='comradio'><span class='name'>"
|
||||
else if (display_freq in DEPT_FREQS)
|
||||
part_a = "<span class='deptradio'><span class='name'>"
|
||||
|
||||
var/quotedmsg = M.say_quote(message)
|
||||
|
||||
//This following recording is intended for research and feedback in the use of department radio channels.
|
||||
|
||||
var/part_blackbox_b = "</span><b> \[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
|
||||
var/blackbox_msg = "[part_a][M.name][part_blackbox_b][quotedmsg][part_c]"
|
||||
//var/blackbox_admin_msg = "[part_a][M.name] (Real name: [M.real_name])[part_blackbox_b][quotedmsg][part_c]"
|
||||
if(istype(blackbox))
|
||||
//BR.messages_admin += blackbox_admin_msg
|
||||
switch(display_freq)
|
||||
if(1459)
|
||||
blackbox.msg_common += blackbox_msg
|
||||
if(1351)
|
||||
blackbox.msg_science += blackbox_msg
|
||||
if(1353)
|
||||
blackbox.msg_command += blackbox_msg
|
||||
if(1355)
|
||||
blackbox.msg_medical += blackbox_msg
|
||||
if(1357)
|
||||
blackbox.msg_engineering += blackbox_msg
|
||||
if(1359)
|
||||
blackbox.msg_security += blackbox_msg
|
||||
if(1441)
|
||||
blackbox.msg_deathsquad += blackbox_msg
|
||||
if(1213)
|
||||
blackbox.msg_syndicate += blackbox_msg
|
||||
if(1349)
|
||||
blackbox.msg_mining += blackbox_msg
|
||||
if(1347)
|
||||
blackbox.msg_cargo += blackbox_msg
|
||||
else
|
||||
blackbox.messages += blackbox_msg
|
||||
|
||||
//End of research and feedback code.
|
||||
|
||||
if (length(heard_masked))
|
||||
var/N = M.name
|
||||
var/J = eqjobname
|
||||
if (istype(M.wear_mask, /obj/item/clothing/mask/gas/voice)&&M.wear_mask:vchange)
|
||||
//To properly have the ninja show up on radio. Could also be useful for similar items.
|
||||
//Would not be necessary but the mob could be wearing a mask that is not a voice changer.
|
||||
N = M.wear_mask:voice
|
||||
J = "Unknown"
|
||||
var/rendered = "[part_a][N][part_b][quotedmsg][part_c]"
|
||||
for (var/mob/R in heard_masked)
|
||||
if(istype(R, /mob/living/silicon/ai))
|
||||
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[N] ([J]) </a>[part_b][quotedmsg][part_c]", 2)
|
||||
else
|
||||
R.show_message(rendered, 2)
|
||||
|
||||
if (length(heard_normal))
|
||||
var/rendered = "[part_a][M.real_name][part_b][quotedmsg][part_c]"
|
||||
|
||||
for (var/mob/R in heard_normal)
|
||||
if(istype(R, /mob/living/silicon/ai))
|
||||
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.real_name] ([eqjobname]) </a>[part_b][quotedmsg][part_c]", 2)
|
||||
else
|
||||
R.show_message(rendered, 2)
|
||||
|
||||
if (length(heard_voice))
|
||||
var/rendered = "[part_a][M.voice_name][part_b][M.voice_message][part_c]"
|
||||
|
||||
for (var/mob/R in heard_voice)
|
||||
if(istype(R, /mob/living/silicon/ai))
|
||||
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name] ([eqjobname]) </a>[part_b][M.voice_message][part_c]", 2)
|
||||
else
|
||||
R.show_message(rendered, 2)
|
||||
|
||||
if (length(heard_garbled))
|
||||
quotedmsg = M.say_quote(stars(message))
|
||||
var/rendered = "[part_a][M.voice_name][part_b][quotedmsg][part_c]"
|
||||
|
||||
for (var/mob/R in heard_voice)
|
||||
if(istype(R, /mob/living/silicon/ai))
|
||||
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name]</a>[part_b][quotedmsg][part_c]", 2)
|
||||
else
|
||||
R.show_message(rendered, 2)
|
||||
|
||||
/obj/item/device/radio/hear_talk(mob/M as mob, msg)
|
||||
|
||||
if (broadcasting)
|
||||
talk_into(M, msg)
|
||||
/*
|
||||
/obj/item/device/radio/proc/accept_rad(obj/item/device/radio/R as obj, message)
|
||||
|
||||
if ((R.frequency == frequency && message))
|
||||
return 1
|
||||
else if
|
||||
|
||||
else
|
||||
return null
|
||||
return
|
||||
*/
|
||||
|
||||
|
||||
/obj/item/device/radio/proc/receive_range(freq, level)
|
||||
// check if this radio can receive on the given frequency, and if so,
|
||||
// what the range is in which mobs will hear the radio
|
||||
// returns: 0 if can't receive, range otherwise
|
||||
|
||||
if (!(wires & WIRE_RECEIVE))
|
||||
return 0
|
||||
if(!listening)
|
||||
return 0
|
||||
if(level != 0)
|
||||
var/turf/position = get_turf(src)
|
||||
if(isnull(position) || position.z != level)
|
||||
return 0
|
||||
if(freq == SYND_FREQ)
|
||||
if(!(src.syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys
|
||||
return 0
|
||||
if (!on)
|
||||
return 0
|
||||
if (!freq) //recieved on main frequency
|
||||
if (!listening)
|
||||
return 0
|
||||
else
|
||||
var/accept = (freq==frequency && listening)
|
||||
if (!accept)
|
||||
for (var/ch_name in channels)
|
||||
var/datum/radio_frequency/RF = secure_radio_connections[ch_name]
|
||||
if (RF.frequency==freq && (channels[ch_name]&FREQ_LISTENING))
|
||||
accept = 1
|
||||
break
|
||||
if (!accept)
|
||||
return 0
|
||||
|
||||
return canhear_range
|
||||
|
||||
/obj/item/device/radio/proc/send_hear(freq, level)
|
||||
|
||||
var/range = receive_range(freq, level)
|
||||
if(range > 0)
|
||||
return get_mobs_in_view(canhear_range, src)
|
||||
|
||||
|
||||
/obj/item/device/radio/examine()
|
||||
set src in view()
|
||||
|
||||
..()
|
||||
if ((in_range(src, usr) || loc == usr))
|
||||
if (b_stat)
|
||||
usr.show_message("\blue \the [src] can be attached and modified!")
|
||||
else
|
||||
usr.show_message("\blue \the [src] can not be modified or attached!")
|
||||
return
|
||||
|
||||
/obj/item/device/radio/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
user.machine = src
|
||||
if (!( istype(W, /obj/item/weapon/screwdriver) ))
|
||||
return
|
||||
b_stat = !( b_stat )
|
||||
if(!istype(src, /obj/item/device/radio/beacon))
|
||||
if (b_stat)
|
||||
user.show_message("\blue The radio can now be attached and modified!")
|
||||
else
|
||||
user.show_message("\blue The radio can no longer be modified or attached!")
|
||||
updateDialog()
|
||||
//Foreach goto(83)
|
||||
add_fingerprint(user)
|
||||
return
|
||||
else return
|
||||
|
||||
/obj/item/device/radio/emp_act(severity)
|
||||
broadcasting = 0
|
||||
listening = 0
|
||||
for (var/ch_name in channels)
|
||||
channels[ch_name] = 0
|
||||
..()
|
||||
|
||||
///////////////////////////////
|
||||
//////////Borg Radios//////////
|
||||
///////////////////////////////
|
||||
//Giving borgs their own radio to have some more room to work with -Sieve
|
||||
|
||||
/obj/item/device/radio/borg
|
||||
var/obj/item/device/encryptionkey/keyslot = null//Borg radios can handle a single encryption key
|
||||
|
||||
/obj/item/device/radio/borg/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
// ..()
|
||||
user.machine = src
|
||||
if (!( istype(W, /obj/item/weapon/screwdriver) || (istype(W, /obj/item/device/encryptionkey/ ))))
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/screwdriver))
|
||||
if(keyslot)
|
||||
|
||||
|
||||
for(var/ch_name in channels)
|
||||
radio_controller.remove_object(src, radiochannels[ch_name])
|
||||
secure_radio_connections[ch_name] = null
|
||||
|
||||
|
||||
if(keyslot)
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
keyslot.loc = T
|
||||
keyslot = null
|
||||
|
||||
recalculateChannels()
|
||||
user << "You pop out the encryption key in the radio!"
|
||||
|
||||
else
|
||||
user << "This radio doesn't have any encryption keys!"
|
||||
|
||||
if(istype(W, /obj/item/device/encryptionkey/))
|
||||
if(keyslot)
|
||||
user << "The radio can't hold another key!"
|
||||
return
|
||||
|
||||
if(!keyslot)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
keyslot = W
|
||||
|
||||
recalculateChannels()
|
||||
|
||||
return
|
||||
|
||||
/obj/item/device/radio/borg/proc/recalculateChannels()
|
||||
src.channels = list()
|
||||
src.syndie = 0
|
||||
|
||||
if(keyslot)
|
||||
for(var/ch_name in keyslot.channels)
|
||||
if(ch_name in src.channels)
|
||||
continue
|
||||
src.channels += ch_name
|
||||
src.channels[ch_name] = keyslot.channels[ch_name]
|
||||
|
||||
if(keyslot.syndie)
|
||||
src.syndie = 1
|
||||
|
||||
|
||||
for (var/ch_name in channels)
|
||||
if(!radio_controller)
|
||||
sleep(30) // Waiting for the radio_controller to be created.
|
||||
if(!radio_controller)
|
||||
src.name = "broken radio"
|
||||
return
|
||||
|
||||
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/device/radio/borg/Topic(href, href_list)
|
||||
if(usr.stat || !on)
|
||||
return
|
||||
if (href_list["mode"])
|
||||
subspace_transmission = !subspace_transmission
|
||||
if(!subspace_transmission)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled
|
||||
channels = list()
|
||||
else
|
||||
recalculateChannels()
|
||||
usr << "Subspace Transmission is [(subspace_transmission) ? "enabled" : "disabled"]"
|
||||
..()
|
||||
|
||||
/obj/item/device/radio/borg/interact(mob/user as mob)
|
||||
if(!on)
|
||||
return
|
||||
|
||||
var/dat = "<html><head><title>[src]</title></head><body><TT>"
|
||||
dat += {"
|
||||
Speaker: [listening ? "<A href='byond://?src=\ref[src];listen=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];listen=1'>Disengaged</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>
|
||||
<A href='byond://?src=\ref[src];mode=1'>Toggle Broadcast Mode</A><BR>
|
||||
"}
|
||||
|
||||
if(subspace_transmission)//Don't even bother if subspace isn't turned on
|
||||
for (var/ch_name in channels)
|
||||
dat+=text_sec_channel(ch_name, channels[ch_name])
|
||||
dat+={"[text_wires()]</TT></body></html>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
@@ -0,0 +1,267 @@
|
||||
|
||||
/*
|
||||
CONTAINS:
|
||||
T-RAY
|
||||
DETECTIVE SCANNER
|
||||
HEALTH ANALYZER
|
||||
GAS ANALYZER
|
||||
PLANT ANALYZER
|
||||
MASS SPECTROMETER
|
||||
|
||||
*/
|
||||
/obj/item/device/t_scanner
|
||||
name = "T-ray scanner"
|
||||
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
|
||||
icon_state = "t-ray0"
|
||||
var/on = 0
|
||||
flags = FPRINT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = 2
|
||||
item_state = "electronic"
|
||||
m_amt = 150
|
||||
origin_tech = "magnets=1;engineering=1"
|
||||
|
||||
/obj/item/device/t_scanner/attack_self(mob/user)
|
||||
|
||||
on = !on
|
||||
icon_state = "t-ray[on]"
|
||||
|
||||
if(on)
|
||||
processing_objects.Add(src)
|
||||
|
||||
|
||||
/obj/item/device/t_scanner/process()
|
||||
if(!on)
|
||||
processing_objects.Remove(src)
|
||||
return null
|
||||
|
||||
for(var/turf/T in range(1, src.loc) )
|
||||
|
||||
if(!T.intact)
|
||||
continue
|
||||
|
||||
for(var/obj/O in T.contents)
|
||||
|
||||
if(O.level != 1)
|
||||
continue
|
||||
|
||||
if(O.invisibility == 101)
|
||||
O.invisibility = 0
|
||||
spawn(10)
|
||||
if(O)
|
||||
var/turf/U = O.loc
|
||||
if(U.intact)
|
||||
O.invisibility = 101
|
||||
|
||||
var/mob/living/M = locate() in T
|
||||
if(M && M.invisibility == 2)
|
||||
M.invisibility = 0
|
||||
spawn(2)
|
||||
if(M)
|
||||
M.invisibility = INVISIBILITY_LEVEL_TWO
|
||||
|
||||
|
||||
/obj/item/device/healthanalyzer
|
||||
name = "Health Analyzer"
|
||||
icon_state = "health"
|
||||
item_state = "analyzer"
|
||||
desc = "A hand-held body scanner able to distinguish vital signs of the subject."
|
||||
flags = FPRINT | TABLEPASS | CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 3
|
||||
w_class = 1.0
|
||||
throw_speed = 5
|
||||
throw_range = 10
|
||||
m_amt = 200
|
||||
origin_tech = "magnets=1;biotech=1"
|
||||
var/mode = 1;
|
||||
|
||||
/obj/item/device/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
if (( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
|
||||
user << text("\red You try to analyze the floor's vitals!")
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1)
|
||||
user.show_message(text("\blue Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
|
||||
user.show_message(text("\blue \t Damage Specifics: [0]-[0]-[0]-[0]"), 1)
|
||||
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
|
||||
user.show_message("\blue Body Temperature: ???", 1)
|
||||
return
|
||||
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
return
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message(text("\red [] has analyzed []'s vitals!", user, M), 1)
|
||||
//Foreach goto(67)
|
||||
var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss())))
|
||||
if(M.status_flags & FAKEDEATH)
|
||||
user.show_message(text("\blue Analyzing Results for []:\n\t Overall Status: []", M, "dead"), 1)
|
||||
user.show_message(text("\blue \t Damage Specifics: []-[]-[]-[]", fake_oxy < 50 ? "\red [fake_oxy]" : fake_oxy , M.getToxLoss() > 50 ? "\red [M.getToxLoss()]" : M.getToxLoss(), M.getFireLoss() > 50 ? "\red[M.getFireLoss()]" : M.getFireLoss(), M.getBruteLoss() > 50 ? "\red[M.getBruteLoss()]" : M.getBruteLoss()), 1)
|
||||
else
|
||||
user.show_message(text("\blue Analyzing Results for []:\n\t Overall Status: []", M, (M.stat > 1 ? "dead" : text("[]% healthy", M.health - M.halloss))), 1)
|
||||
user.show_message(text("\blue \t Damage Specifics: []-[]-[]-[]", M.getOxyLoss() > 50 ? "\red [M.getOxyLoss()]" : M.getOxyLoss(), M.getToxLoss() > 50 ? "\red [M.getToxLoss()]" : M.getToxLoss(), M.getFireLoss() > 50 ? "\red[M.getFireLoss()]" : M.getFireLoss(), M.getBruteLoss() > 50 ? "\red[M.getBruteLoss()]" : M.getBruteLoss()), 1)
|
||||
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
|
||||
user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
|
||||
if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
|
||||
user.show_message("\blue Time of Death: [M.tod]")
|
||||
if(istype(M, /mob/living/carbon/human) && mode == 1)
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/list/damaged = H.get_damaged_organs(1,1)
|
||||
user.show_message("\blue Localized Damage, Brute/Burn:",1)
|
||||
if(length(damaged)>0)
|
||||
for(var/datum/organ/external/org in damaged)
|
||||
user.show_message(text("\blue \t []: []\blue-[]",capitalize(org.getDisplayName()),(org.brute_dam > 0)?"\red [org.brute_dam]":0,(org.burn_dam > 0)?"\red [org.burn_dam]":0),1)
|
||||
else
|
||||
user.show_message("\blue \t Limbs are OK.",1)
|
||||
|
||||
if(M.status_flags & FAKEDEATH)
|
||||
user.show_message(text("\blue [] | [] | [] | []", fake_oxy > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal", M.getToxLoss() > 50 ? "\red Dangerous amount of toxins detected\blue" : "Subject bloodstream toxin level minimal", M.getFireLoss() > 50 ? "\red Severe burn damage detected\blue" : "Subject burn injury status O.K", M.getBruteLoss() > 50 ? "\red Severe anatomical damage detected\blue" : "Subject brute-force injury status O.K"), 1)
|
||||
else
|
||||
user.show_message(text("\blue [] | [] | [] | []", M.getOxyLoss() > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal", M.getToxLoss() > 50 ? "\red Dangerous amount of toxins detected\blue" : "Subject bloodstream toxin level minimal", M.getFireLoss() > 50 ? "\red Severe burn damage detected\blue" : "Subject burn injury status O.K", M.getBruteLoss() > 50 ? "\red Severe anatomical damage detected\blue" : "Subject brute-force injury status O.K"), 1)
|
||||
if (M.getCloneLoss())
|
||||
user.show_message(text("\red Subject appears to have been imperfectly cloned."), 1)
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
if(!D.hidden[SCANNER])
|
||||
user.show_message(text("\red <b>Warning: [D.form] Detected</b>\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]"))
|
||||
if (M.reagents && M.reagents.get_reagent_amount("inaprovaline"))
|
||||
user.show_message(text("\blue Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals."), 1)
|
||||
if (M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && M:brain_op_stage == 4.0)
|
||||
user.show_message(text("\red Subject is brain dead."), 1)
|
||||
else if (M.getBrainLoss() >= 60)
|
||||
user.show_message(text("\red Severe brain damage detected. Subject likely to have mental retardation."), 1)
|
||||
else if (M.getBrainLoss() >= 10)
|
||||
user.show_message(text("\red Significant brain damage detected. Subject may have had a concussion."), 1)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/device/healthanalyzer/verb/toggle_mode()
|
||||
set name = "Switch Verbosity"
|
||||
set category = "Object"
|
||||
|
||||
mode = !mode
|
||||
switch (mode)
|
||||
if(1)
|
||||
usr << "The scanner now shows specific limb damage."
|
||||
if(0)
|
||||
usr << "The scanner no longer shows limb damage."
|
||||
|
||||
|
||||
/obj/item/device/analyzer
|
||||
desc = "A hand-held environmental scanner which reports current gas levels."
|
||||
name = "analyzer"
|
||||
icon_state = "atmos"
|
||||
item_state = "analyzer"
|
||||
w_class = 2.0
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 5
|
||||
throw_speed = 4
|
||||
throw_range = 20
|
||||
m_amt = 30
|
||||
g_amt = 20
|
||||
origin_tech = "magnets=1;engineering=1"
|
||||
|
||||
/obj/item/device/analyzer/attack_self(mob/user as mob)
|
||||
|
||||
if (user.stat)
|
||||
return
|
||||
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
return
|
||||
|
||||
var/turf/location = user.loc
|
||||
if (!( istype(location, /turf) ))
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/total_moles = environment.total_moles()
|
||||
|
||||
user.show_message("\blue <B>Results:</B>", 1)
|
||||
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
||||
user.show_message("\blue Pressure: [round(pressure,0.1)] kPa", 1)
|
||||
else
|
||||
user.show_message("\red Pressure: [round(pressure,0.1)] kPa", 1)
|
||||
if(total_moles)
|
||||
var/o2_concentration = environment.oxygen/total_moles
|
||||
var/n2_concentration = environment.nitrogen/total_moles
|
||||
var/co2_concentration = environment.carbon_dioxide/total_moles
|
||||
var/plasma_concentration = environment.toxins/total_moles
|
||||
|
||||
var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration)
|
||||
if(abs(n2_concentration - N2STANDARD) < 20)
|
||||
user.show_message("\blue Nitrogen: [round(n2_concentration*100)]%", 1)
|
||||
else
|
||||
user.show_message("\red Nitrogen: [round(n2_concentration*100)]%", 1)
|
||||
|
||||
if(abs(o2_concentration - O2STANDARD) < 2)
|
||||
user.show_message("\blue Oxygen: [round(o2_concentration*100)]%", 1)
|
||||
else
|
||||
user.show_message("\red Oxygen: [round(o2_concentration*100)]%", 1)
|
||||
|
||||
if(co2_concentration > 0.01)
|
||||
user.show_message("\red CO2: [round(co2_concentration*100)]%", 1)
|
||||
else
|
||||
user.show_message("\blue CO2: [round(co2_concentration*100)]%", 1)
|
||||
|
||||
if(plasma_concentration > 0.01)
|
||||
user.show_message("\red Plasma: [round(plasma_concentration*100)]%", 1)
|
||||
|
||||
if(unknown_concentration > 0.01)
|
||||
user.show_message("\red Unknown: [round(unknown_concentration*100)]%", 1)
|
||||
|
||||
user.show_message("\blue Temperature: [round(environment.temperature-T0C)]°C", 1)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/device/mass_spectrometer/New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(5)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
|
||||
/obj/item/device/mass_spectrometer/on_reagent_change()
|
||||
if(reagents.total_volume)
|
||||
icon_state = initial(icon_state) + "_s"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/device/mass_spectrometer/attack_self(mob/user as mob)
|
||||
if (user.stat)
|
||||
return
|
||||
if (crit_fail)
|
||||
user << "\red This device has critically failed and is no longer functional!"
|
||||
return
|
||||
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
user << "\red You don't have the dexterity to do this!"
|
||||
return
|
||||
if(reagents.total_volume)
|
||||
var/list/blood_traces = list()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.id != "blood")
|
||||
reagents.clear_reagents()
|
||||
user << "\red The sample was contaminated! Please insert another sample"
|
||||
return
|
||||
else
|
||||
blood_traces = params2list(R.data["trace_chem"])
|
||||
break
|
||||
var/dat = "Trace Chemicals Found: "
|
||||
for(var/R in blood_traces)
|
||||
if(prob(reliability))
|
||||
if(details)
|
||||
dat += "[R] ([blood_traces[R]] units) "
|
||||
else
|
||||
dat += "[R] "
|
||||
recent_fail = 0
|
||||
else
|
||||
if(recent_fail)
|
||||
crit_fail = 1
|
||||
reagents.clear_reagents()
|
||||
return
|
||||
else
|
||||
recent_fail = 1
|
||||
user << "[dat]"
|
||||
reagents.clear_reagents()
|
||||
return
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/obj/item/weapon/cloaking_device
|
||||
name = "cloaking device"
|
||||
desc = "Use this to become invisible to the human eyesocket."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "shield0"
|
||||
var/active = 0.0
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
item_state = "electronic"
|
||||
throwforce = 10.0
|
||||
throw_speed = 2
|
||||
throw_range = 10
|
||||
w_class = 2.0
|
||||
origin_tech = "magnets=3;syndicate=4"
|
||||
|
||||
|
||||
/obj/item/weapon/cloaking_device/attack_self(mob/user as mob)
|
||||
src.active = !( src.active )
|
||||
if (src.active)
|
||||
user << "\blue The cloaking device is now active."
|
||||
src.icon_state = "shield1"
|
||||
else
|
||||
user << "\blue The cloaking device is now inactive."
|
||||
src.icon_state = "shield0"
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/weapon/cloaking_device/emp_act(severity)
|
||||
active = 0
|
||||
icon_state = "shield0"
|
||||
if(ismob(loc))
|
||||
loc:update_icons()
|
||||
..()
|
||||
@@ -0,0 +1,263 @@
|
||||
/obj/item/device/taperecorder
|
||||
desc = "A device that can record up to an hour of dialogue and play it back. It automatically translates the content in playback."
|
||||
name = "universal recorder"
|
||||
icon_state = "taperecorderidle"
|
||||
item_state = "analyzer"
|
||||
w_class = 1.0
|
||||
m_amt = 60
|
||||
g_amt = 30
|
||||
var/emagged = 0.0
|
||||
var/recording = 0.0
|
||||
var/playing = 0.0
|
||||
var/timerecorded = 0.0
|
||||
var/playsleepseconds = 0.0
|
||||
var/list/storedinfo = new/list()
|
||||
var/list/timestamp = new/list()
|
||||
var/canprint = 1
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
throwforce = 2
|
||||
throw_speed = 4
|
||||
throw_range = 20
|
||||
|
||||
/obj/item/device/taperecorder/hear_talk(mob/living/M as mob, msg)
|
||||
if (recording)
|
||||
var/ending = copytext(msg, length(msg))
|
||||
src.timestamp+= src.timerecorded
|
||||
if (M.stuttering)
|
||||
src.storedinfo += "\[[time2text(src.timerecorded*10,"mm:ss")]\] [M.name] stammers, \"[msg]\""
|
||||
return
|
||||
if (M.getBrainLoss() >= 60)
|
||||
src.storedinfo += "\[[time2text(src.timerecorded*10,"mm:ss")]\] [M.name] gibbers, \"[msg]\""
|
||||
return
|
||||
if (ending == "?")
|
||||
src.storedinfo += "\[[time2text(src.timerecorded*10,"mm:ss")]\] [M.name] asks, \"[msg]\""
|
||||
return
|
||||
else if (ending == "!")
|
||||
src.storedinfo += "\[[time2text(src.timerecorded*10,"mm:ss")]\] [M.name] exclaims, \"[msg]\""
|
||||
return
|
||||
src.storedinfo += "\[[time2text(src.timerecorded*10,"mm:ss")]\] [M.name] says, \"[msg]\""
|
||||
return
|
||||
|
||||
/obj/item/device/taperecorder/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
if (istype(W, /obj/item/weapon/card/emag))
|
||||
if (src.emagged == 0)
|
||||
src.emagged = 1
|
||||
src.recording = 0
|
||||
user << "\red PZZTTPFFFT"
|
||||
src.icon_state = "taperecorderidle"
|
||||
else
|
||||
user << "\red That is already emagged!"
|
||||
|
||||
/obj/item/device/taperecorder/proc/explode()
|
||||
var/turf/T = get_turf(src.loc)
|
||||
if (ismob(src.loc))
|
||||
var/mob/M = src.loc
|
||||
M.show_message("\red The [src] explodes!", 1)
|
||||
if(T)
|
||||
T.hotspot_expose(700,125)
|
||||
explosion(T, -1, -1, 0, 4)
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/item/device/taperecorder/verb/record()
|
||||
set name = "Start Recording"
|
||||
set category = "Object"
|
||||
if(usr.stat)
|
||||
usr << "Not when you're incapacitated."
|
||||
return
|
||||
if(src.emagged == 1)
|
||||
usr << "\red The tape recorder makes a scratchy noise."
|
||||
return
|
||||
src.icon_state = "taperecorderrecording"
|
||||
if(src.timerecorded < 3600 && src.playing == 0)
|
||||
usr << "\blue Recording started."
|
||||
src.recording = 1
|
||||
src.timestamp+= src.timerecorded
|
||||
src.storedinfo += "\[[time2text(src.timerecorded*10,"mm:ss")]\] Recording started."
|
||||
for(src.timerecorded, src.timerecorded<3600)
|
||||
if(src.recording == 0)
|
||||
break
|
||||
src.timerecorded++
|
||||
sleep(10)
|
||||
src.recording = 0
|
||||
src.icon_state = "taperecorderidle"
|
||||
return
|
||||
else
|
||||
usr << "\red Either your tape recorder's memory is full, or it is currently playing back its memory."
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/stop()
|
||||
set name = "Stop"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
usr << "Not when you're incapacitated."
|
||||
return
|
||||
if (src.recording == 1)
|
||||
src.recording = 0
|
||||
src.timestamp+= src.timerecorded
|
||||
src.storedinfo += "\[[time2text(src.timerecorded*10,"mm:ss")]\] Recording stopped."
|
||||
usr << "\blue Recording stopped."
|
||||
src.icon_state = "taperecorderidle"
|
||||
return
|
||||
else if (src.playing == 1)
|
||||
src.playing = 0
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/O in hearers(world.view-1, T))
|
||||
O.show_message("<font color=Maroon><B>Tape Recorder</B>: Playback stopped.</font>",2)
|
||||
src.icon_state = "taperecorderidle"
|
||||
return
|
||||
else
|
||||
usr << "\red Stop what?"
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/clear_memory()
|
||||
set name = "Clear Memory"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
usr << "Not when you're incapicated."
|
||||
return
|
||||
if(src.emagged == 1)
|
||||
usr << "\red The tape recorder makes a scratchy noise."
|
||||
return
|
||||
if (src.recording == 1 || src.playing == 1)
|
||||
usr << "\red You can't clear the memory while playing or recording!"
|
||||
return
|
||||
else
|
||||
src.storedinfo -= src.storedinfo
|
||||
src.timestamp -= src.timestamp
|
||||
src.timerecorded = 0
|
||||
usr << "\blue Memory cleared."
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/playback_memory()
|
||||
set name = "Playback Memory"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
usr << "Not when you're incapicated."
|
||||
return
|
||||
if (src.recording == 1)
|
||||
usr << "\red You can't playback when recording!"
|
||||
return
|
||||
if (src.playing == 1)
|
||||
usr << "\red You're already playing!"
|
||||
return
|
||||
src.playing = 1
|
||||
src.icon_state = "taperecorderplaying"
|
||||
usr << "\blue Playing started."
|
||||
for(var/i=1,src.timerecorded<3600,sleep(10 * (src.playsleepseconds) ))
|
||||
if (src.playing == 0)
|
||||
break
|
||||
if (src.storedinfo.len < i)
|
||||
break
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/O in hearers(world.view-1, T))
|
||||
O.show_message("<font color=Maroon><B>Tape Recorder</B>: [src.storedinfo[i]]</font>",2)
|
||||
if (src.storedinfo.len < i+1)
|
||||
src.playsleepseconds = 1
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
for(var/mob/O in hearers(world.view-1, T))
|
||||
O.show_message("<font color=Maroon><B>Tape Recorder</B>: End of recording.</font>",2)
|
||||
else
|
||||
src.playsleepseconds = src.timestamp[i+1] - src.timestamp[i]
|
||||
if (src.playsleepseconds > 19)
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
for(var/mob/O in hearers(world.view-1, T))
|
||||
O.show_message("<font color=Maroon><B>Tape Recorder</B>: Skipping [src.playsleepseconds] seconds of silence</font>",2)
|
||||
src.playsleepseconds = 1
|
||||
i++
|
||||
src.icon_state = "taperecorderidle"
|
||||
src.playing = 0
|
||||
if (src.emagged == 1.0)
|
||||
for(var/mob/O in hearers(world.view-1, get_turf(src)))
|
||||
O.show_message("Tape Recorder: This tape recorder will self destruct in <B>5</B>",2)
|
||||
sleep(10)
|
||||
for(var/mob/O in hearers(world.view-1, get_turf(src)))
|
||||
O.show_message("<B>4</B>",2)
|
||||
sleep(10)
|
||||
for(var/mob/O in hearers(world.view-1, get_turf(src)))
|
||||
O.show_message("<B>3</B>",2)
|
||||
sleep(10)
|
||||
for(var/mob/O in hearers(world.view-1, get_turf(src)))
|
||||
O.show_message("<B>2</B>",2)
|
||||
sleep(10)
|
||||
for(var/mob/O in hearers(world.view-1, get_turf(src)))
|
||||
O.show_message("<B>1</B>",2)
|
||||
sleep(10)
|
||||
src.explode()
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/verb/print_transcript()
|
||||
set name = "Print Transcript"
|
||||
set category = "Object"
|
||||
|
||||
if (!canprint)
|
||||
usr << "\red The recorder can't print that fast!"
|
||||
return
|
||||
if (src.recording == 1 || src.playing == 1)
|
||||
usr << "\red You can't print the transcript while playing or recording!"
|
||||
return
|
||||
usr << "\blue Transcript printed."
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src))
|
||||
var/t1 = "<B>Transcript:</B><BR><BR>"
|
||||
for(var/i=1,src.storedinfo.len >= i,i++)
|
||||
t1 += "[src.storedinfo[i]]<BR>"
|
||||
P.info = t1
|
||||
P.name = "paper- 'Transcript'"
|
||||
canprint = 0
|
||||
sleep(300)
|
||||
canprint = 1
|
||||
|
||||
|
||||
/obj/item/device/taperecorder/attack_self(mob/user)
|
||||
if(src.recording == 0 && src.playing == 0)
|
||||
if(usr.stat)
|
||||
usr << "Not when you're incapacitated."
|
||||
return
|
||||
if(src.emagged == 1)
|
||||
usr << "\red The tape recorder makes a scratchy noise."
|
||||
return
|
||||
src.icon_state = "taperecorderrecording"
|
||||
if(src.timerecorded < 3600 && src.playing == 0)
|
||||
usr << "\blue Recording started."
|
||||
src.recording = 1
|
||||
src.timestamp+= src.timerecorded
|
||||
src.storedinfo += "\[[time2text(src.timerecorded*10,"mm:ss")]\] Recording started."
|
||||
for(src.timerecorded, src.timerecorded<3600)
|
||||
if(src.recording == 0)
|
||||
break
|
||||
src.timerecorded++
|
||||
sleep(10)
|
||||
src.recording = 0
|
||||
src.icon_state = "taperecorderidle"
|
||||
return
|
||||
else
|
||||
usr << "\red Either your tape recorder's memory is full, or it is currently playing back its memory."
|
||||
else
|
||||
if(usr.stat)
|
||||
usr << "Not when you're incapacitated."
|
||||
return
|
||||
if (src.recording == 1)
|
||||
src.recording = 0
|
||||
src.timestamp+= src.timerecorded
|
||||
src.storedinfo += "\[[time2text(src.timerecorded*10,"mm:ss")]\] Recording stopped."
|
||||
usr << "\blue Recording stopped."
|
||||
src.icon_state = "taperecorderidle"
|
||||
return
|
||||
else if (src.playing == 1)
|
||||
src.playing = 0
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/O in hearers(world.view-1, T))
|
||||
O.show_message("<font color=Maroon><B>Tape Recorder</B>: Playback stopped.</font>",2)
|
||||
src.icon_state = "taperecorderidle"
|
||||
return
|
||||
else
|
||||
usr << "\red Stop what?"
|
||||
return
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
Miscellaneous traitor devices
|
||||
|
||||
BATTERER
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
The Batterer, like a flashbang but 50% chance to knock people over. Can be either very
|
||||
effective or pretty fucking useless.
|
||||
|
||||
*/
|
||||
|
||||
/obj/item/device/batterer
|
||||
name = "mind batterer"
|
||||
desc = "A strange device with twin antennas."
|
||||
icon_state = "batterer"
|
||||
throwforce = 5
|
||||
w_class = 1.0
|
||||
throw_speed = 4
|
||||
throw_range = 10
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
item_state = "electronic"
|
||||
origin_tech = "magnets=3;combat=3;syndicate=3"
|
||||
|
||||
var/times_used = 0 //Number of times it's been used.
|
||||
var/max_uses = 2
|
||||
|
||||
|
||||
/obj/item/device/batterer/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
|
||||
if(!user) return
|
||||
if(times_used >= max_uses)
|
||||
user << "\red The mind batterer has been burnt out!"
|
||||
return
|
||||
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used [src] to knock down people in the area.</font>")
|
||||
|
||||
for(var/mob/living/carbon/human/M in orange(10, user))
|
||||
spawn()
|
||||
if(prob(50))
|
||||
|
||||
M.Weaken(rand(10,20))
|
||||
if(prob(25))
|
||||
M.Stun(rand(5,10))
|
||||
M << "\red <b>You feel a tremendous, paralyzing wave flood your mind.</b>"
|
||||
|
||||
else
|
||||
M << "\red <b>You feel a sudden, electric jolt travel through your head.</b>"
|
||||
|
||||
playsound(src.loc, 'sound/misc/interference.ogg', 50, 1)
|
||||
user << "\blue You trigger [src]."
|
||||
times_used += 1
|
||||
if(times_used >= max_uses)
|
||||
icon_state = "battererburnt"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
/obj/item/device/transfer_valve
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
name = "tank transfer valve"
|
||||
icon_state = "valve_1"
|
||||
desc = "Regulates the transfer of air between two tanks"
|
||||
var/obj/item/weapon/tank/tank_one
|
||||
var/obj/item/weapon/tank/tank_two
|
||||
var/obj/item/device/attached_device
|
||||
var/mob/attacher = "Unknown"
|
||||
var/valve_open = 0
|
||||
var/toggle = 1
|
||||
|
||||
/obj/item/device/transfer_valve/proc/process_activation(var/obj/item/device/D)
|
||||
|
||||
/obj/item/device/transfer_valve/IsAssemblyHolder()
|
||||
return 1
|
||||
|
||||
/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user)
|
||||
if(istype(item, /obj/item/weapon/tank))
|
||||
if(tank_one && tank_two)
|
||||
user << "<span class='warning'>There are already two tanks attached, remove one first.</span>"
|
||||
return
|
||||
|
||||
if(!tank_one)
|
||||
tank_one = item
|
||||
user.drop_item()
|
||||
item.loc = src
|
||||
user << "<span class='notice'>You attach the tank to the transfer valve.</span>"
|
||||
else if(!tank_two)
|
||||
tank_two = item
|
||||
user.drop_item()
|
||||
item.loc = src
|
||||
user << "<span class='notice'>You attach the tank to the transfer valve.</span>"
|
||||
|
||||
update_icon()
|
||||
//TODO: Have this take an assemblyholder
|
||||
else if(isassembly(item))
|
||||
var/obj/item/device/assembly/A = item
|
||||
if(A.secured)
|
||||
user << "<span class='notice'>The device is secured.</span>"
|
||||
return
|
||||
if(attached_device)
|
||||
user << "<span class='warning'>There is already an device attached to the valve, remove it first.</span>"
|
||||
return
|
||||
user.remove_from_mob(item)
|
||||
attached_device = A
|
||||
A.loc = src
|
||||
user << "<span class='notice'>You attach the [item] to the valve controls and secure it.</span>"
|
||||
A.holder = src
|
||||
A.toggle_secure()
|
||||
|
||||
bombers += "[key_name(user)] attached a [item] to a transfer valve."
|
||||
message_admins("[key_name_admin(user)] attached a [item] to a transfer valve.")
|
||||
log_game("[key_name_admin(user)] attached a [item] to a transfer valve.")
|
||||
attacher = key_name(user)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/transfer_valve/HasProximity(atom/movable/AM as mob|obj)
|
||||
if(!attached_device) return
|
||||
attached_device.HasProximity(AM)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/transfer_valve/attack_self(mob/user as mob)
|
||||
user.machine = src
|
||||
var/dat = {"<B> Valve properties: </B>
|
||||
<BR> <B> Attachment one:</B> [tank_one] [tank_one ? "<A href='?src=\ref[src];tankone=1'>Remove</A>" : ""]
|
||||
<BR> <B> Attachment two:</B> [tank_two] [tank_two ? "<A href='?src=\ref[src];tanktwo=1'>Remove</A>" : ""]
|
||||
<BR> <B> Valve attachment:</B> [attached_device ? "<A href='?src=\ref[src];device=1'>[attached_device]</A>" : "None"] [attached_device ? "<A href='?src=\ref[src];rem_device=1'>Remove</A>" : ""]
|
||||
<BR> <B> Valve status: </B> [ valve_open ? "<A href='?src=\ref[src];open=1'>Closed</A> <B>Open</B>" : "<B>Closed</B> <A href='?src=\ref[src];open=1'>Open</A>"]"}
|
||||
|
||||
user << browse(dat, "window=trans_valve;size=600x300")
|
||||
onclose(user, "trans_valve")
|
||||
return
|
||||
|
||||
/obj/item/device/transfer_valve/Topic(href, href_list)
|
||||
..()
|
||||
if ( usr.stat || usr.restrained() )
|
||||
return
|
||||
if (src.loc == usr)
|
||||
if(tank_one && href_list["tankone"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_one.loc = get_turf(src)
|
||||
tank_one = null
|
||||
update_icon()
|
||||
else if(tank_two && href_list["tanktwo"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_two.loc = get_turf(src)
|
||||
tank_two = null
|
||||
update_icon()
|
||||
else if(href_list["open"])
|
||||
toggle_valve()
|
||||
else if(attached_device)
|
||||
if(href_list["rem_device"])
|
||||
attached_device.loc = get_turf(src)
|
||||
attached_device:holder = null
|
||||
attached_device = null
|
||||
update_icon()
|
||||
if(href_list["device"])
|
||||
attached_device.attack_self(usr)
|
||||
|
||||
src.attack_self(usr)
|
||||
src.add_fingerprint(usr)
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/device/transfer_valve/process_activation(var/obj/item/device/D)
|
||||
if(toggle)
|
||||
toggle = 0
|
||||
toggle_valve()
|
||||
spawn(50) // To stop a signal being spammed from a proxy sensor constantly going off or whatever
|
||||
toggle = 1
|
||||
|
||||
/obj/item/device/transfer_valve/update_icon()
|
||||
overlays = null
|
||||
underlays = null
|
||||
|
||||
if(!tank_one && !tank_two && !attached_device)
|
||||
icon_state = "valve_1"
|
||||
return
|
||||
icon_state = "valve"
|
||||
|
||||
if(tank_one)
|
||||
overlays += "[tank_one.icon_state]"
|
||||
if(tank_two)
|
||||
var/icon/J = new(icon, icon_state = "[tank_two.icon_state]")
|
||||
J.Shift(WEST, 13)
|
||||
underlays += J
|
||||
if(attached_device)
|
||||
overlays += "device"
|
||||
|
||||
/obj/item/device/transfer_valve/proc/merge_gases()
|
||||
tank_two.air_contents.volume += tank_one.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_one.air_contents.remove_ratio(1)
|
||||
tank_two.air_contents.merge(temp)
|
||||
|
||||
/obj/item/device/transfer_valve/proc/split_gases()
|
||||
if (!valve_open || !tank_one || !tank_two)
|
||||
return
|
||||
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_two.air_contents.remove_ratio(ratio1)
|
||||
tank_one.air_contents.merge(temp)
|
||||
tank_two.air_contents.volume -= tank_one.air_contents.volume
|
||||
|
||||
/*
|
||||
Exadv1: I know this isn't how it's going to work, but this was just to check
|
||||
it explodes properly when it gets a signal (and it does).
|
||||
*/
|
||||
|
||||
/obj/item/device/transfer_valve/proc/toggle_valve()
|
||||
if(valve_open==0 && (tank_one && tank_two))
|
||||
valve_open = 1
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/bombarea = bombturf.loc.name
|
||||
var/log_str = "Bomb valve opened in [bombarea] with device attacher: [attacher]. Last touched by: [src.fingerprintslast]"
|
||||
bombers += log_str
|
||||
message_admins(log_str)
|
||||
log_game(log_str)
|
||||
merge_gases()
|
||||
spawn(20) // In case one tank bursts
|
||||
for (var/i=0,i<5,i++)
|
||||
src.update_icon()
|
||||
sleep(10)
|
||||
src.update_icon()
|
||||
|
||||
else if(valve_open==1 && (tank_one && tank_two))
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
src.update_icon()
|
||||
|
||||
// this doesn't do anything but the timer etc. expects it to be here
|
||||
// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
|
||||
/obj/item/device/transfer_valve/proc/c_state()
|
||||
return
|
||||
@@ -0,0 +1,385 @@
|
||||
//This could either be split into the proper DM files or placed somewhere else all together, but it'll do for now -Nodrak
|
||||
|
||||
/*
|
||||
|
||||
SYNDICATE UPLINKS
|
||||
|
||||
TO-DO:
|
||||
Once wizard is fixed, make sure the uplinks work correctly for it. wizard.dm is right now uncompiled and with broken code in it.
|
||||
|
||||
Clean the code up and comment it. Part of it is right now copy-pasted, with the general Topic() and modifications by Abi79.
|
||||
|
||||
I should take a more in-depth look at both the copy-pasted code for the individual uplinks below, and at each gamemode's code
|
||||
to see how uplinks are assigned and if there are any bugs with those.
|
||||
|
||||
|
||||
A list of items and costs is stored under the datum of every game mode, alongside the number of crystals, and the welcoming message.
|
||||
|
||||
*/
|
||||
|
||||
/obj/item/device/uplink
|
||||
var/welcome // Welcoming menu message
|
||||
var/items // List of items
|
||||
var/item_data // raw item text
|
||||
var/list/ItemList // Parsed list of items
|
||||
var/uses // Numbers of crystals
|
||||
// List of items not to shove in their hands.
|
||||
var/list/NotInHand = list(/obj/machinery/singularity_beacon/syndicate)
|
||||
|
||||
/obj/item/device/uplink/New()
|
||||
welcome = ticker.mode.uplink_welcome
|
||||
if(!item_data)
|
||||
items = dd_replacetext(ticker.mode.uplink_items, "\n", "") // Getting the text string of items
|
||||
else
|
||||
items = dd_replacetext(item_data)
|
||||
ItemList = dd_text2list(src.items, ";") // Parsing the items text string
|
||||
uses = ticker.mode.uplink_uses
|
||||
|
||||
//Let's build a menu!
|
||||
/obj/item/device/uplink/proc/generate_menu()
|
||||
|
||||
var/dat = "<B>[src.welcome]</B><BR>"
|
||||
dat += "Tele-Crystals left: [src.uses]<BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<B>Request item:</B><BR>"
|
||||
dat += "<I>Each item costs a number of tele-crystals as indicated by the number following their name.</I><br><BR>"
|
||||
|
||||
var/cost
|
||||
var/item
|
||||
var/name
|
||||
var/path_obj
|
||||
var/path_text
|
||||
var/category_items = 1 //To prevent stupid :P
|
||||
|
||||
for(var/D in ItemList)
|
||||
var/list/O = stringsplit(D, ":")
|
||||
if(O.len != 3) //If it is not an actual item, make a break in the menu.
|
||||
if(O.len == 1) //If there is one item, it's probably a title
|
||||
dat += "<b>[O[1]]</b><br>"
|
||||
category_items = 0
|
||||
else //Else, it's a white space.
|
||||
if(category_items < 1) //If there were no itens in the last category...
|
||||
dat += "<i>We apologize, as you could not afford anything from this category.</i><br>"
|
||||
dat += "<br>"
|
||||
continue
|
||||
|
||||
path_text = O[1]
|
||||
cost = text2num(O[2])
|
||||
|
||||
if(cost>uses)
|
||||
continue
|
||||
|
||||
path_obj = text2path(path_text)
|
||||
item = new path_obj()
|
||||
name = O[3]
|
||||
del item
|
||||
|
||||
dat += "<A href='byond://?src=\ref[src];buy_item=[path_text];cost=[cost]'>[name]</A> ([cost])<BR>"
|
||||
category_items++
|
||||
|
||||
dat += "<A href='byond://?src=\ref[src];buy_item=random'>Random Item (??)</A><br>"
|
||||
dat += "<HR>"
|
||||
return dat
|
||||
|
||||
//If 'random' was selected
|
||||
/obj/item/device/uplink/proc/chooseRandomItem()
|
||||
var/list/randomItems = list()
|
||||
|
||||
//Sorry for all the ifs, but it makes it 1000 times easier for other people/servers to add or remove items from this list
|
||||
//Add only items the player can afford:
|
||||
if(uses > 19)
|
||||
randomItems.Add("/obj/item/weapon/circuitboard/teleporter") //Teleporter Circuit Board (costs 20, for nuke ops)
|
||||
|
||||
if(uses > 9)
|
||||
randomItems.Add("/obj/item/toy/syndicateballoon")//Syndicate Balloon
|
||||
randomItems.Add("/obj/item/weapon/storage/syndie_kit/imp_uplink") //Uplink Implanter
|
||||
randomItems.Add("/obj/item/weapon/storage/box/syndicate") //Syndicate bundle
|
||||
|
||||
//if(uses > 8) //Nothing... yet.
|
||||
//if(uses > 7) //Nothing... yet.
|
||||
|
||||
if(uses > 6)
|
||||
randomItems.Add("/obj/item/weapon/aiModule/syndicate") //Hacked AI Upload Module
|
||||
randomItems.Add("/obj/item/device/radio/beacon/syndicate") //Singularity Beacon
|
||||
|
||||
if(uses > 5)
|
||||
randomItems.Add("/obj/item/weapon/gun/projectile") //Revolver
|
||||
|
||||
if(uses > 4)
|
||||
randomItems.Add("/obj/item/weapon/gun/energy/crossbow") //Energy Crossbow
|
||||
randomItems.Add("/obj/item/device/powersink") //Powersink
|
||||
|
||||
if(uses > 3)
|
||||
randomItems.Add("/obj/item/weapon/melee/energy/sword") //Energy Sword
|
||||
randomItems.Add("/obj/item/clothing/mask/gas/voice") //Voice Changer
|
||||
randomItems.Add("/obj/item/device/chameleon") //Chameleon Projector
|
||||
|
||||
if(uses > 2)
|
||||
randomItems.Add("/obj/item/weapon/storage/emp_kit") //EMP Grenades
|
||||
randomItems.Add("/obj/item/weapon/pen/paralysis") //Paralysis Pen
|
||||
randomItems.Add("/obj/item/weapon/cartridge/syndicate") //Detomatix Cartridge
|
||||
randomItems.Add("/obj/item/clothing/under/chameleon") //Chameleon Jumpsuit
|
||||
randomItems.Add("/obj/item/weapon/card/id/syndicate") //Agent ID Card
|
||||
randomItems.Add("/obj/item/weapon/card/emag") //Cryptographic Sequencer
|
||||
randomItems.Add("/obj/item/weapon/storage/syndie_kit/space") //Syndicate Space Suit
|
||||
randomItems.Add("/obj/item/device/encryptionkey/binary") //Binary Translator Key
|
||||
randomItems.Add("/obj/item/weapon/storage/syndie_kit/imp_freedom") //Freedom Implant
|
||||
randomItems.Add("/obj/item/clothing/glasses/thermal/syndi") //Thermal Imaging Goggles
|
||||
|
||||
if(uses > 1)
|
||||
/*
|
||||
var/list/usrItems = usr.get_contents() //Checks to see if the user has a revolver before giving ammo
|
||||
var/hasRevolver = 0
|
||||
for(var/obj/I in usrItems) //Only add revolver ammo if the user has a gun that can shoot it
|
||||
if(istype(I,/obj/item/weapon/gun/projectile))
|
||||
hasRevolver = 1
|
||||
|
||||
if(hasRevolver) randomItems.Add("/obj/item/ammo_magazine/a357") //Revolver ammo
|
||||
*/
|
||||
randomItems.Add("/obj/item/ammo_magazine/a357") //Revolver ammo
|
||||
randomItems.Add("/obj/item/clothing/shoes/syndigaloshes") //No-Slip Syndicate Shoes
|
||||
randomItems.Add("/obj/item/weapon/plastique") //C4
|
||||
|
||||
if(uses > 0)
|
||||
randomItems.Add("/obj/item/weapon/soap/syndie") //Syndicate Soap
|
||||
randomItems.Add("/obj/item/weapon/storage/toolbox/syndicate") //Syndicate Toolbox
|
||||
|
||||
if(!randomItems.len)
|
||||
del(randomItems)
|
||||
return 0
|
||||
else
|
||||
var/buyItem = pick(randomItems)
|
||||
|
||||
switch(buyItem) //Ok, this gets a little messy, sorry.
|
||||
if("/obj/item/weapon/circuitboard/teleporter")
|
||||
uses -= 20
|
||||
if("/obj/item/toy/syndicateballoon" , "/obj/item/weapon/storage/syndie_kit/imp_uplink" , "/obj/item/weapon/storage/box/syndicate")
|
||||
uses -= 10
|
||||
if("/obj/item/weapon/aiModule/syndicate" , "/obj/item/device/radio/beacon/syndicate")
|
||||
uses -= 7
|
||||
if("/obj/item/weapon/gun/projectile")
|
||||
uses -= 6
|
||||
if("/obj/item/weapon/gun/energy/crossbow" , "/obj/item/device/powersink")
|
||||
uses -= 5
|
||||
if("/obj/item/weapon/melee/energy/sword" , "/obj/item/clothing/mask/gas/voice" , "/obj/item/device/chameleon")
|
||||
uses -= 4
|
||||
if("/obj/item/weapon/storage/emp_kit" , "/obj/item/weapon/pen/paralysis" , "/obj/item/weapon/cartridge/syndicate" , "/obj/item/clothing/under/chameleon" , \
|
||||
"/obj/item/weapon/card/id/syndicate" , "/obj/item/weapon/card/emag" , "/obj/item/weapon/storage/syndie_kit/space" , "/obj/item/device/encryptionkey/binary" , \
|
||||
"/obj/item/weapon/storage/syndie_kit/imp_freedom" , "/obj/item/clothing/glasses/thermal/syndi")
|
||||
uses -= 3
|
||||
if("/obj/item/ammo_magazine/a357" , "/obj/item/clothing/shoes/syndigaloshes" , "/obj/item/weapon/plastique")
|
||||
uses -= 2
|
||||
if("/obj/item/weapon/soap/syndie" , "/obj/item/weapon/storage/toolbox/syndicate")
|
||||
uses -= 1
|
||||
del(randomItems)
|
||||
return buyItem
|
||||
|
||||
/obj/item/device/uplink/proc/handleStatTracking(var/boughtItem)
|
||||
//For stat tracking, sorry for making it so ugly
|
||||
if(!boughtItem) return
|
||||
|
||||
switch(boughtItem)
|
||||
if("/obj/item/weapon/circuitboard/teleporter")
|
||||
feedback_add_details("traitor_uplink_items_bought","TP")
|
||||
if("/obj/item/toy/syndicateballoon")
|
||||
feedback_add_details("traitor_uplink_items_bought","BS")
|
||||
if("/obj/item/weapon/storage/syndie_kit/imp_uplink")
|
||||
feedback_add_details("traitor_uplink_items_bought","UI")
|
||||
if("/obj/item/weapon/storage/box/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","BU")
|
||||
if("/obj/item/weapon/aiModule/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","AI")
|
||||
if("/obj/item/device/radio/beacon/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","SB")
|
||||
if("/obj/item/weapon/gun/projectile")
|
||||
feedback_add_details("traitor_uplink_items_bought","RE")
|
||||
if("/obj/item/weapon/gun/energy/crossbow")
|
||||
feedback_add_details("traitor_uplink_items_bought","XB")
|
||||
if("/obj/item/device/powersink")
|
||||
feedback_add_details("traitor_uplink_items_bought","PS")
|
||||
if("/obj/item/weapon/melee/energy/sword")
|
||||
feedback_add_details("traitor_uplink_items_bought","ES")
|
||||
if("/obj/item/clothing/mask/gas/voice")
|
||||
feedback_add_details("traitor_uplink_items_bought","VC")
|
||||
if("/obj/item/device/chameleon")
|
||||
feedback_add_details("traitor_uplink_items_bought","CP")
|
||||
if("/obj/item/weapon/storage/emp_kit")
|
||||
feedback_add_details("traitor_uplink_items_bought","EM")
|
||||
if("/obj/item/weapon/pen/paralysis")
|
||||
feedback_add_details("traitor_uplink_items_bought","PP")
|
||||
if("/obj/item/weapon/cartridge/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","DC")
|
||||
if("/obj/item/clothing/under/chameleon")
|
||||
feedback_add_details("traitor_uplink_items_bought","CJ")
|
||||
if("/obj/item/weapon/card/id/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","AC")
|
||||
if("/obj/item/weapon/card/emag")
|
||||
feedback_add_details("traitor_uplink_items_bought","EC")
|
||||
if("/obj/item/weapon/storage/syndie_kit/space")
|
||||
feedback_add_details("traitor_uplink_items_bought","SS")
|
||||
if("/obj/item/device/encryptionkey/binary")
|
||||
feedback_add_details("traitor_uplink_items_bought","BT")
|
||||
if("/obj/item/weapon/storage/syndie_kit/imp_freedom")
|
||||
feedback_add_details("traitor_uplink_items_bought","FI")
|
||||
if("/obj/item/clothing/glasses/thermal/syndi")
|
||||
feedback_add_details("traitor_uplink_items_bought","TM")
|
||||
if("/obj/item/ammo_magazine/a357")
|
||||
feedback_add_details("traitor_uplink_items_bought","RA")
|
||||
if("/obj/item/clothing/shoes/syndigaloshes")
|
||||
feedback_add_details("traitor_uplink_items_bought","SH")
|
||||
if("/obj/item/weapon/plastique")
|
||||
feedback_add_details("traitor_uplink_items_bought","C4")
|
||||
if("/obj/item/weapon/soap/syndie")
|
||||
feedback_add_details("traitor_uplink_items_bought","SP")
|
||||
if("/obj/item/weapon/storage/toolbox/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","ST")
|
||||
|
||||
/obj/item/device/uplink/Topic(href, href_list)
|
||||
|
||||
if (href_list["buy_item"])
|
||||
if(href_list["buy_item"] == "random")
|
||||
var/boughtItem = chooseRandomItem()
|
||||
if(boughtItem)
|
||||
href_list["buy_item"] = boughtItem
|
||||
feedback_add_details("traitor_uplink_items_bought","RN")
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
else
|
||||
if(text2num(href_list["cost"]) > uses) // Not enough crystals for the item
|
||||
return 0
|
||||
|
||||
//if(usr:mind && ticker.mode.traitors[usr:mind])
|
||||
//var/datum/traitorinfo/info = ticker.mode.traitors[usr:mind]
|
||||
//info.spawnlist += href_list["buy_item"]
|
||||
|
||||
uses -= text2num(href_list["cost"])
|
||||
handleStatTracking(href_list["buy_item"]) //Note: chooseRandomItem handles it's own stat tracking. This proc is not meant for 'random'.
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
// HIDDEN UPLINK - Can be stored in anything but the host item has to have a trigger for it.
|
||||
/* How to create an uplink in 3 easy steps!
|
||||
|
||||
1. All obj/item 's have a hidden_uplink var. By default it's null. Give the item one with "new(src)", it must be in it's contents. Feel free to add "uses".
|
||||
|
||||
2. Code in the triggers. Use check_trigger for this, I recommend closing the item's menu with "usr << browse(null, "window=windowname") if it returns true.
|
||||
The var/value is the value that will be compared with the var/target. If they are equal it will activate the menu.
|
||||
|
||||
3. If you want the menu to stay until the users locks his uplink, add an active_uplink_check(mob/user as mob) in your interact/attack_hand proc.
|
||||
Then check if it's true, if true return. This will stop the normal menu appearing and will instead show the uplink menu.
|
||||
*/
|
||||
|
||||
/obj/item/device/uplink/hidden
|
||||
name = "Hidden Uplink."
|
||||
desc = "There is something wrong if you're examining this."
|
||||
var/active = 0
|
||||
var/list/purchase_log = list()
|
||||
|
||||
// The hidden uplink MUST be inside an obj/item's contents.
|
||||
/obj/item/device/uplink/hidden/New()
|
||||
spawn(2)
|
||||
if(!istype(src.loc, /obj/item))
|
||||
del(src)
|
||||
..()
|
||||
|
||||
// Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated.
|
||||
/obj/item/device/uplink/hidden/proc/toggle()
|
||||
active = !active
|
||||
|
||||
// Directly trigger the uplink. Turn on if it isn't already.
|
||||
/obj/item/device/uplink/hidden/proc/trigger(mob/user as mob)
|
||||
if(!active)
|
||||
toggle()
|
||||
interact(user)
|
||||
|
||||
// Checks to see if the value meets the target. Like a frequency being a traitor_frequency, in order to unlock a headset.
|
||||
// If true, it accesses trigger() and returns 1. If it fails, it returns false. Use this to see if you need to close the
|
||||
// current item's menu.
|
||||
/obj/item/device/uplink/hidden/proc/check_trigger(mob/user as mob, var/value, var/target)
|
||||
if(value == target)
|
||||
trigger(user)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button.
|
||||
/obj/item/device/uplink/hidden/proc/interact(mob/user as mob)
|
||||
|
||||
var/dat = "<body link='yellow' alink='white' bgcolor='#601414'><font color='white'>"
|
||||
dat += src.generate_menu()
|
||||
dat += "<A href='byond://?src=\ref[src];lock=1'>Lock</a>"
|
||||
dat += "</font></body>"
|
||||
user << browse(dat, "window=hidden")
|
||||
onclose(user, "hidden")
|
||||
return
|
||||
|
||||
// The purchasing code.
|
||||
/obj/item/device/uplink/hidden/Topic(href, href_list)
|
||||
|
||||
if (usr.stat || usr.restrained())
|
||||
return
|
||||
|
||||
if (!( istype(usr, /mob/living/carbon/human)))
|
||||
return 0
|
||||
|
||||
if ((usr.contents.Find(src.loc) || (in_range(src.loc, usr) && istype(src.loc.loc, /turf))))
|
||||
usr.machine = src
|
||||
if(href_list["lock"])
|
||||
toggle()
|
||||
usr << browse(null, "window=hidden")
|
||||
return 1
|
||||
|
||||
if(..(href, href_list) == 1)
|
||||
var/path_obj = text2path(href_list["buy_item"])
|
||||
var/obj/I = new path_obj(get_turf(usr))
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/A = usr
|
||||
A.put_in_any_hand_if_possible(I)
|
||||
purchase_log += "[usr] ([usr.ckey]) bought [I]."
|
||||
interact(usr)
|
||||
return
|
||||
|
||||
// I placed this here because of how relevant it is.
|
||||
// You place this in your uplinkable item to check if an uplink is active or not.
|
||||
// If it is, it will display the uplink menu and return 1, else it'll return false.
|
||||
// If it returns true, I recommend closing the item's normal menu with "user << browse(null, "window=name")"
|
||||
/obj/item/proc/active_uplink_check(mob/user as mob)
|
||||
// Activates the uplink if it's active
|
||||
if(src.hidden_uplink)
|
||||
if(src.hidden_uplink.active)
|
||||
src.hidden_uplink.trigger(user)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// PRESET UPLINKS
|
||||
// A collection of preset uplinks.
|
||||
//
|
||||
// Includes normal radio uplink, multitool uplink,
|
||||
// implant uplink (not the implant tool) and a preset headset uplink.
|
||||
|
||||
/obj/item/device/radio/uplink/New()
|
||||
hidden_uplink = new(src)
|
||||
|
||||
/obj/item/device/radio/uplink/attack_self(mob/user as mob)
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.trigger(user)
|
||||
|
||||
/obj/item/device/multitool/uplink/New()
|
||||
hidden_uplink = new(src)
|
||||
|
||||
/obj/item/device/multitool/uplink/attack_self(mob/user as mob)
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.trigger(user)
|
||||
|
||||
/obj/item/device/radio/headset/uplink
|
||||
traitor_frequency = 1445
|
||||
|
||||
/obj/item/device/radio/headset/uplink/New()
|
||||
..()
|
||||
hidden_uplink = new(src)
|
||||
hidden_uplink.uses = 10
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user