Merge branch 'master' into kk-adminships

This commit is contained in:
Novacat
2020-09-27 17:02:08 -04:00
committed by GitHub
746 changed files with 49441 additions and 38323 deletions

35
.github/workflows/render_nanomaps.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
# GitHub action to autorender nanomaps outside the game
# This kills off the awful verb we have that takes a full 50 seconds and hangs the whole server
# The file names and locations are VERY important here
# DO NOT EDIT THIS UNLESS YOU KNOW WHAT YOU ARE DOING
# -aa
name: 'Render Nanomaps'
on:
push:
branches: master
paths:
- 'maps/**'
jobs:
generate_maps:
name: 'Generate NanoMaps'
runs-on: ubuntu-18.04
steps:
- name: 'Update Branch'
uses: actions/checkout@v2
with:
fetch-depth: 1
- name: 'Generate Maps'
run: './tools/github-actions/nanomap-renderer-invoker.sh'
- name: 'Commit Maps'
run: |
git config --local user.email "action@github.com"
git config --local user.name "NanoMap Generation"
git pull origin master
git commit -m "NanoMap Auto-Update (`date`)" -a || true
- name: 'Push Maps'
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -8,6 +8,8 @@ Going to make a Pull Request? Make sure you read the [CONTRIBUTING.md](.github/C
VOREStation is a fork of the Polaris code branch, itself a fork of the Baystation12 code branch, for the game Space Station 13. VOREStation is a fork of the Polaris code branch, itself a fork of the Baystation12 code branch, for the game Space Station 13.
![Render Nanomaps](https://github.com/VOREStation/VOREStation/workflows/Render%20Nanomaps/badge.svg)
--- ---
### LICENSE ### LICENSE

View File

@@ -13,6 +13,7 @@
desc = "A one-way air valve that can be used to regulate input or output pressure, and flow rate. Does not require power." desc = "A one-way air valve that can be used to regulate input or output pressure, and flow rate. Does not require power."
use_power = USE_POWER_OFF use_power = USE_POWER_OFF
interact_offline = TRUE
var/unlocked = 0 //If 0, then the valve is locked closed, otherwise it is open(-able, it's a one-way valve so it closes if gas would flow backwards). var/unlocked = 0 //If 0, then the valve is locked closed, otherwise it is open(-able, it's a one-way valve so it closes if gas would flow backwards).
var/target_pressure = ONE_ATMOSPHERE var/target_pressure = ONE_ATMOSPHERE
@@ -216,7 +217,7 @@
tgui_interact(user) tgui_interact(user)
/obj/machinery/atmospherics/binary/passive_gate/tgui_interact(mob/user, datum/tgui/ui) /obj/machinery/atmospherics/binary/passive_gate/tgui_interact(mob/user, datum/tgui/ui)
if(stat & (BROKEN|NOPOWER)) if(stat & BROKEN)
return FALSE return FALSE
ui = SStgui.try_update_ui(user, src, ui) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)

View File

@@ -33,8 +33,10 @@
return ..() return ..()
/obj/machinery/atmospherics/omni/atmos_filter/sort_ports() /obj/machinery/atmospherics/omni/atmos_filter/sort_ports()
var/any_updated = FALSE
for(var/datum/omni_port/P in ports) for(var/datum/omni_port/P in ports)
if(P.update) if(P.update)
any_updated = TRUE
if(output == P) if(output == P)
output = null output = null
if(input == P) if(input == P)
@@ -50,6 +52,8 @@
output = P output = P
if(ATM_O2 to ATM_N2O) if(ATM_O2 to ATM_N2O)
atmos_filters += P atmos_filters += P
if(any_updated)
rebuild_filtering_list()
/obj/machinery/atmospherics/omni/atmos_filter/error_check() /obj/machinery/atmospherics/omni/atmos_filter/error_check()
if(!input || !output || !atmos_filters) if(!input || !output || !atmos_filters)
@@ -231,7 +235,6 @@
target_port.mode = mode target_port.mode = mode
if(target_port.mode != previous_mode) if(target_port.mode != previous_mode)
handle_port_change(target_port) handle_port_change(target_port)
rebuild_filtering_list()
else else
return return
else else

View File

@@ -70,10 +70,6 @@
if(istype(W, /obj/item/device/pipe_painter)) if(istype(W, /obj/item/device/pipe_painter))
return return
if(istype(W, /obj/item/device/analyzer) && in_range(user, src))
var/obj/item/device/analyzer/A = W
A.analyze_gases(src, user)
/obj/machinery/atmospherics/pipe/tank/air /obj/machinery/atmospherics/pipe/tank/air
name = "Pressure Tank (Air)" name = "Pressure Tank (Air)"
icon_state = "air_map" icon_state = "air_map"

3
code/__defines/pda.dm Normal file
View File

@@ -0,0 +1,3 @@
#define PDA_APP_UPDATE 0
#define PDA_APP_NOUPDATE 1
#define PDA_APP_UPDATE_SLOW 2

View File

@@ -21,6 +21,27 @@
/* /*
* Text sanitization * Text sanitization
*/ */
// Can be used almost the same way as normal input for text
/proc/clean_input(Message, Title, Default, mob/user=usr)
var/txt = input(user, Message, Title, Default) as text | null
if(txt)
return html_encode(txt)
//Simply removes < and > and limits the length of the message
/proc/strip_html_simple(var/t,var/limit=MAX_MESSAGE_LEN)
var/list/strip_chars = list("<",">")
t = copytext(t,1,limit)
for(var/char in strip_chars)
var/index = findtext(t, char)
while(index)
t = copytext(t, 1, index) + copytext(t, index+1)
index = findtext(t, char)
return t
//Runs byond's sanitization proc along-side strip_html_simple
//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '&lt;' that html_encode() would cause
/proc/adminscrub(var/t,var/limit=MAX_MESSAGE_LEN)
return copytext((html_encode(strip_html_simple(t))),1,limit)
//Used for preprocessing entered text //Used for preprocessing entered text
/proc/sanitize(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1) /proc/sanitize(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1)

View File

@@ -141,8 +141,9 @@
return 1 return 1
/obj/machinery/turretid/AICtrlClick() //turns off/on Turrets /obj/machinery/turretid/AICtrlClick() //turns off/on Turrets
Topic(src, list("command"="enable", "value"="[!enabled]")) enabled = !enabled
return 1 updateTurrets()
return TRUE
/atom/proc/AIAltClick(var/atom/A) /atom/proc/AIAltClick(var/atom/A)
return AltClick(A) return AltClick(A)
@@ -156,8 +157,10 @@
return 1 return 1
/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets /obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
Topic(src, list("command"="lethal", "value"="[!lethal]")) if(lethal_is_configurable)
return 1 lethal = !lethal
updateTurrets()
return TRUE
/atom/proc/AIMiddleClick(var/mob/living/silicon/user) /atom/proc/AIMiddleClick(var/mob/living/silicon/user)
return 0 return 0

View File

@@ -515,7 +515,7 @@
if("Show Crew Manifest") if("Show Crew Manifest")
if(isAI(usr)) if(isAI(usr))
var/mob/living/silicon/ai/AI = usr var/mob/living/silicon/ai/AI = usr
AI.ai_roster() AI.subsystem_crew_manifest()
if("Show Alerts") if("Show Alerts")
if(isAI(usr)) if(isAI(usr))
@@ -540,12 +540,14 @@
if("PDA - Send Message") if("PDA - Send Message")
if(isAI(usr)) if(isAI(usr))
var/mob/living/silicon/ai/AI = usr var/mob/living/silicon/ai/AI = usr
AI.aiPDA.cmd_send_pdamesg(usr) AI.aiPDA.start_program(AI.aiPDA.find_program(/datum/data/pda/app/messenger))
AI.aiPDA.cmd_pda_open_ui(usr)
if("PDA - Show Message Log") if("PDA - Show Message Log")
if(isAI(usr)) if(isAI(usr))
var/mob/living/silicon/ai/AI = usr var/mob/living/silicon/ai/AI = usr
AI.aiPDA.cmd_show_message_log(usr) AI.aiPDA.start_program(AI.aiPDA.find_program(/datum/data/pda/app/messenger))
AI.aiPDA.cmd_pda_open_ui(usr)
if("Take Image") if("Take Image")
if(isAI(usr)) if(isAI(usr))

View File

@@ -1,22 +0,0 @@
SUBSYSTEM_DEF(nanoui)
name = "NanoUI"
wait = 5
flags = SS_NO_INIT
// a list of current open /nanoui UIs, grouped by src_object and ui_key
var/list/open_uis = list()
// a list of current open /nanoui UIs, not grouped, for use in processing
var/list/processing_uis = list()
/datum/controller/subsystem/nanoui/Recover()
if(SSnanoui.open_uis)
open_uis |= SSnanoui.open_uis
if(SSnanoui.processing_uis)
processing_uis |= SSnanoui.processing_uis
/datum/controller/subsystem/nanoui/stat_entry()
return ..("[processing_uis.len] UIs")
/datum/controller/subsystem/nanoui/fire(resumed)
for(var/thing in processing_uis)
var/datum/nanoui/UI = thing
UI.process()

View File

@@ -31,7 +31,7 @@ SUBSYSTEM_DEF(persistence)
return return
// if((!T.z in GLOB.using_map.station_levels) || !initialized) // if((!T.z in GLOB.using_map.station_levels) || !initialized)
if(!T.z in using_map.station_levels) if(!(T.z in using_map.station_levels))
return return
if(!tracking_values[track_type]) if(!tracking_values[track_type])

View File

@@ -31,5 +31,5 @@
weakref = null // Clear this reference to ensure it's kept for as brief duration as possible. weakref = null // Clear this reference to ensure it's kept for as brief duration as possible.
tag = null tag = null
SSnanoui.close_uis(src) SStgui.close_uis(src)
return QDEL_HINT_QUEUE return QDEL_HINT_QUEUE

View File

@@ -85,7 +85,6 @@
current.verbs -= /datum/changeling/proc/EvolutionMenu current.verbs -= /datum/changeling/proc/EvolutionMenu
current.mind = null current.mind = null
SSnanoui.user_transferred(current, new_character) // transfer active NanoUI instances to new user
if(new_character.mind) //remove any mind currently in our new body's mind variable if(new_character.mind) //remove any mind currently in our new body's mind variable
new_character.mind.current = null new_character.mind.current = null

View File

@@ -38,9 +38,10 @@ var/global/datum/repository/crew/crew_repository = new()
crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job") crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job")
if(C.sensor_mode >= SUIT_SENSOR_BINARY) if(C.sensor_mode >= SUIT_SENSOR_BINARY)
crewmemberData["dead"] = H.stat > UNCONSCIOUS crewmemberData["dead"] = H.stat == DEAD
if(C.sensor_mode >= SUIT_SENSOR_VITAL) if(C.sensor_mode >= SUIT_SENSOR_VITAL)
crewmemberData["stat"] = H.stat
crewmemberData["oxy"] = round(H.getOxyLoss(), 1) crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
crewmemberData["tox"] = round(H.getToxLoss(), 1) crewmemberData["tox"] = round(H.getToxLoss(), 1)
crewmemberData["fire"] = round(H.getFireLoss(), 1) crewmemberData["fire"] = round(H.getFireLoss(), 1)

View File

@@ -25,16 +25,7 @@
return list("title" = title, "message" = message) return list("title" = title, "message" = message)
/datum/uplink_item/abstract/announcements/fake_centcom/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user, var/list/args) /datum/uplink_item/abstract/announcements/fake_centcom/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user, var/list/args)
for (var/obj/machinery/computer/communications/C in machines) post_comm_message(args["title"], replacetext(args["message"], "\n", "<br/>"))
if(! (C.stat & (BROKEN|NOPOWER) ) )
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
P.name = "'[command_name()] Update.'"
P.info = replacetext(args["message"], "\n", "<br/>")
P.update_space(P.info)
P.update_icon()
C.messagetitle.Add(args["title"])
C.messagetext.Add(P.info)
command_announcement.Announce(args["message"], args["title"]) command_announcement.Announce(args["message"], args["title"])
return 1 return 1

View File

@@ -73,3 +73,13 @@
name = "Integrated Surge Implant" name = "Integrated Surge Implant"
item_cost = 40 item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/surge path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/surge
/datum/uplink_item/item/implants/imp_armblade
name = "Integrated Armblade Implant"
item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/armblade
/datum/uplink_item/item/implants/imp_handblade
name = "Integrated Handblade Implant"
item_cost = 25
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/handblade

View File

@@ -51,7 +51,7 @@ var/datum/uplink/uplink = new()
if(!can_buy(U)) if(!can_buy(U))
return return
if(U.CanUseTopic(user, inventory_state) != STATUS_INTERACTIVE) if(U.CanUseTopic(user, GLOB.tgui_inventory_state) != STATUS_INTERACTIVE)
return return
var/cost = cost(U.uses, U) var/cost = cost(U.uses, U)

View File

@@ -10,6 +10,8 @@
w_class = ITEMSIZE_SMALL w_class = ITEMSIZE_SMALL
attack_verb = list("called", "rang") attack_verb = list("called", "rang")
hitsound = 'sound/weapons/ring.ogg' hitsound = 'sound/weapons/ring.ogg'
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
/obj/item/weapon/rsp /obj/item/weapon/rsp
name = "\improper Rapid-Seed-Producer (RSP)" name = "\improper Rapid-Seed-Producer (RSP)"
@@ -22,6 +24,8 @@
var/stored_matter = 0 var/stored_matter = 0
var/mode = 1 var/mode = 1
w_class = ITEMSIZE_NORMAL w_class = ITEMSIZE_NORMAL
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
/obj/item/weapon/soap /obj/item/weapon/soap
name = "soap" name = "soap"
@@ -35,7 +39,6 @@
throwforce = 0 throwforce = 0
throw_speed = 4 throw_speed = 4
throw_range = 20 throw_range = 20
drop_sound = 'sound/misc/slip.ogg'
/obj/item/weapon/soap/nanotrasen /obj/item/weapon/soap/nanotrasen
desc = "A NanoTrasen-brand bar of soap. Smells of phoron." desc = "A NanoTrasen-brand bar of soap. Smells of phoron."
@@ -149,6 +152,8 @@
throw_range = 20 throw_range = 20
matter = list(DEFAULT_WALL_MATERIAL = 100) matter = list(DEFAULT_WALL_MATERIAL = 100)
origin_tech = list(TECH_MAGNET = 1) origin_tech = list(TECH_MAGNET = 1)
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
/obj/item/weapon/staff /obj/item/weapon/staff
name = "wizards staff" name = "wizards staff"
@@ -196,6 +201,8 @@
item_state = "std_mod" item_state = "std_mod"
w_class = ITEMSIZE_SMALL w_class = ITEMSIZE_SMALL
var/mtype = 1 // 1=electronic 2=hardware var/mtype = 1 // 1=electronic 2=hardware
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
/obj/item/weapon/module/card_reader /obj/item/weapon/module/card_reader
name = "card reader module" name = "card reader module"
@@ -227,7 +234,6 @@
item_state = "std_mod" item_state = "std_mod"
desc = "Charging circuits for power cells." desc = "Charging circuits for power cells."
/obj/item/device/camera_bug /obj/item/device/camera_bug
name = "camera bug" name = "camera bug"
icon = 'icons/obj/device.dmi' icon = 'icons/obj/device.dmi'
@@ -303,6 +309,8 @@
display_contents_with_number = 1 display_contents_with_number = 1
max_w_class = ITEMSIZE_NORMAL max_w_class = ITEMSIZE_NORMAL
max_storage_space = 100 max_storage_space = 100
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
/obj/item/weapon/storage/part_replacer/adv /obj/item/weapon/storage/part_replacer/adv
name = "advanced rapid part exchange device" name = "advanced rapid part exchange device"
@@ -326,7 +334,8 @@
icon = 'icons/obj/stock_parts.dmi' icon = 'icons/obj/stock_parts.dmi'
w_class = ITEMSIZE_SMALL w_class = ITEMSIZE_SMALL
var/rating = 1 var/rating = 1
drop_sound = 'sound/items/drop/glass.ogg' drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
/obj/item/weapon/stock_parts/New() /obj/item/weapon/stock_parts/New()
src.pixel_x = rand(-5.0, 5) src.pixel_x = rand(-5.0, 5)

View File

@@ -276,7 +276,7 @@ var/global/list/datum/dna/gene/dna_genes[0]
// Set a DNA UI block's raw value. // Set a DNA UI block's raw value.
/datum/dna/proc/SetUIValue(var/block,var/value,var/defer=0) /datum/dna/proc/SetUIValue(var/block,var/value,var/defer=0)
if (block<=0) return if (block<=0) return
ASSERT(value>0) ASSERT(value>=0)
ASSERT(value<=4095) ASSERT(value<=4095)
UI[block]=value UI[block]=value
dirtyUI=1 dirtyUI=1
@@ -292,7 +292,6 @@ var/global/list/datum/dna/gene/dna_genes[0]
// Used in hair and facial styles (value being the index and maxvalue being the len of the hairstyle list) // Used in hair and facial styles (value being the index and maxvalue being the len of the hairstyle list)
/datum/dna/proc/SetUIValueRange(var/block,var/value,var/maxvalue,var/defer=0) /datum/dna/proc/SetUIValueRange(var/block,var/value,var/maxvalue,var/defer=0)
if (block<=0) return if (block<=0) return
if (value==0) value = 1 // FIXME: hair/beard/eye RGB values if they are 0 are not set, this is a work around we'll encode it in the DNA to be 1 instead.
ASSERT(maxvalue<=4095) ASSERT(maxvalue<=4095)
var/range = (4095 / maxvalue) var/range = (4095 / maxvalue)
if(value) if(value)
@@ -302,7 +301,7 @@ var/global/list/datum/dna/gene/dna_genes[0]
/datum/dna/proc/GetUIValueRange(var/block,var/maxvalue) /datum/dna/proc/GetUIValueRange(var/block,var/maxvalue)
if (block<=0) return 0 if (block<=0) return 0
var/value = GetUIValue(block) var/value = GetUIValue(block)
return round(0.5 + (value / 4096) * maxvalue) return round(0.5 + (value / 4095) * maxvalue)
// Is the UI gene "on" or "off"? // Is the UI gene "on" or "off"?
// For UI, this is simply a check of if the value is > 2050. // For UI, this is simply a check of if the value is > 2050.
@@ -388,7 +387,7 @@ var/global/list/datum/dna/gene/dna_genes[0]
/datum/dna/proc/GetSEValueRange(var/block,var/maxvalue) /datum/dna/proc/GetSEValueRange(var/block,var/maxvalue)
if (block<=0) return 0 if (block<=0) return 0
var/value = GetSEValue(block) var/value = GetSEValue(block)
return round(1 +(value / 4096)*maxvalue) return round(1 +(value / 4095)*maxvalue)
// Is the block "on" (1) or "off" (0)? (Un-assigned genes are always off.) // Is the block "on" (1) or "off" (0)? (Un-assigned genes are always off.)
/datum/dna/proc/GetSEState(var/block) /datum/dna/proc/GetSEState(var/block)

View File

@@ -177,7 +177,7 @@
// Ears // Ears
var/ears = dna.GetUIValueRange(DNA_UI_EAR_STYLE, ear_styles_list.len + 1) - 1 var/ears = dna.GetUIValueRange(DNA_UI_EAR_STYLE, ear_styles_list.len + 1) - 1
if(ears <= 1) if(ears < 1)
H.ear_style = null H.ear_style = null
else if((0 < ears) && (ears <= ear_styles_list.len)) else if((0 < ears) && (ears <= ear_styles_list.len))
H.ear_style = ear_styles_list[ear_styles_list[ears]] H.ear_style = ear_styles_list[ear_styles_list[ears]]
@@ -192,14 +192,14 @@
//Tail //Tail
var/tail = dna.GetUIValueRange(DNA_UI_TAIL_STYLE, tail_styles_list.len + 1) - 1 var/tail = dna.GetUIValueRange(DNA_UI_TAIL_STYLE, tail_styles_list.len + 1) - 1
if(tail <= 1) if(tail < 1)
H.tail_style = null H.tail_style = null
else if((0 < tail) && (tail <= tail_styles_list.len)) else if((0 < tail) && (tail <= tail_styles_list.len))
H.tail_style = tail_styles_list[tail_styles_list[tail]] H.tail_style = tail_styles_list[tail_styles_list[tail]]
//Wing //Wing
var/wing = dna.GetUIValueRange(DNA_UI_WING_STYLE, wing_styles_list.len + 1) - 1 var/wing = dna.GetUIValueRange(DNA_UI_WING_STYLE, wing_styles_list.len + 1) - 1
if(wing <= 1) if(wing < 1)
H.wing_style = null H.wing_style = null
else if((0 < wing) && (wing <= wing_styles_list.len)) else if((0 < wing) && (wing <= wing_styles_list.len))
H.wing_style = wing_styles_list[wing_styles_list[wing]] H.wing_style = wing_styles_list[wing_styles_list[wing]]

View File

@@ -286,5 +286,5 @@ var/global/list/changeling_fabricated_clothing = list(
if(!registered_user) if(!registered_user)
registered_user = usr registered_user = usr
usr.set_id_info(src) usr.set_id_info(src)
ui_interact(registered_user) tgui_interact(registered_user)
..() ..()

View File

@@ -180,7 +180,7 @@
/proc/get_access_by_id(id) /proc/get_access_by_id(id)
var/list/AS = get_all_access_datums_by_id() var/list/AS = get_all_access_datums_by_id()
return AS[id] return AS["[id]"]
/proc/get_all_jobs() /proc/get_all_jobs()
var/list/all_jobs = list() var/list/all_jobs = list()

View File

@@ -540,6 +540,8 @@ var/global/datum/controller/occupations/job_master
// EMAIL GENERATION // EMAIL GENERATION
// Email addresses will be created under this domain name. Mostly for the looks. // Email addresses will be created under this domain name. Mostly for the looks.
var/domain = "freemail.nt" var/domain = "freemail.nt"
if(using_map && LAZYLEN(using_map.usable_email_tlds))
domain = using_map.usable_email_tlds[1]
var/sanitized_name = sanitize(replacetext(replacetext(lowertext(H.real_name), " ", "."), "'", "")) var/sanitized_name = sanitize(replacetext(replacetext(lowertext(H.real_name), " ", "."), "'", ""))
var/complete_login = "[sanitized_name]@[domain]" var/complete_login = "[sanitized_name]@[domain]"

View File

@@ -260,7 +260,7 @@ update_flag
..() ..()
SSnanoui.update_uis(src) // Update all NanoUIs attached to src SStgui.update_uis(src) // Update all NanoUIs attached to src
/obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob) /obj/machinery/portable_atmospherics/canister/attack_ai(var/mob/user as mob)
return src.attack_hand(user) return src.attack_hand(user)

View File

@@ -136,12 +136,6 @@
else else
to_chat(user, "<span class='notice'>Nothing happens.</span>") to_chat(user, "<span class='notice'>Nothing happens.</span>")
return return
else if ((istype(W, /obj/item/device/analyzer)) && Adjacent(user))
var/obj/item/device/analyzer/A = W
A.analyze_gases(src, user)
return
return return

View File

@@ -204,7 +204,9 @@
else else
P = W P = W
itemname = P.name itemname = P.name
info = P.notehtml var/datum/data/pda/app/notekeeper/N = P.find_program(/datum/data/pda/app/notekeeper)
if(N)
info = N.notehtml
to_chat(U, "You hold \a [itemname] up to the camera ...") to_chat(U, "You hold \a [itemname] up to the camera ...")
for(var/mob/living/silicon/ai/O in living_mob_list) for(var/mob/living/silicon/ai/O in living_mob_list)
if(!O.client) if(!O.client)

View File

@@ -92,8 +92,11 @@
var/blocked = 0 //Player cannot attack/heal while set var/blocked = 0 //Player cannot attack/heal while set
var/turtle = 0 var/turtle = 0
/obj/machinery/computer/arcade/battle/New() /obj/machinery/computer/arcade/battle/Initialize()
..() . = ..()
randomize_characters()
/obj/machinery/computer/arcade/battle/proc/randomize_characters()
var/name_action var/name_action
var/name_part1 var/name_part1
var/name_part2 var/name_part2
@@ -111,17 +114,17 @@
if(..()) if(..())
return return
user.set_machine(src) user.set_machine(src)
ui_interact(user) tgui_interact(user)
/** /obj/machinery/computer/arcade/battle/tgui_interact(mob/user, datum/tgui/ui)
* Display the NanoUI window for the arcade machine. ui = SStgui.try_update_ui(user, src, ui)
* if(!ui)
* See NanoUI documentation for details. ui = new(user, src, "ArcadeBattle", name)
*/ ui.open()
/obj/machinery/computer/arcade/battle/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = list() /obj/machinery/computer/arcade/battle/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
data["name"] = name
data["temp"] = temp data["temp"] = temp
data["enemyAction"] = enemy_action data["enemyAction"] = enemy_action
data["enemyName"] = enemy_name data["enemyName"] = enemy_name
@@ -129,59 +132,54 @@
data["playerMP"] = player_mp data["playerMP"] = player_mp
data["enemyHP"] = enemy_hp data["enemyHP"] = enemy_hp
data["gameOver"] = gameover data["gameOver"] = gameover
return data
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) /obj/machinery/computer/arcade/battle/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if (!ui)
ui = new(user, src, ui_key, "arcade_battle.tmpl", src.name, 400, 300)
ui.set_initial_data(data)
ui.open()
//ui.set_auto_update(2)
/obj/machinery/computer/arcade/battle/Topic(href, href_list)
if(..()) if(..())
return 1 return TRUE
if (!blocked && !gameover) if(!blocked && !gameover)
if (href_list["attack"]) switch(action)
blocked = 1 if("attack")
var/attackamt = rand(2,6) blocked = 1
temp = "You attack for [attackamt] damage!" var/attackamt = rand(2,6)
playsound(src, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) temp = "You attack for [attackamt] damage!"
if(turtle > 0) playsound(src, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
turtle-- if(turtle > 0)
turtle--
sleep(10) sleep(10)
enemy_hp -= attackamt enemy_hp -= attackamt
arcade_action() arcade_action()
else if (href_list["heal"]) if("heal")
blocked = 1 blocked = 1
var/pointamt = rand(1,3) var/pointamt = rand(1,3)
var/healamt = rand(6,8) var/healamt = rand(6,8)
temp = "You use [pointamt] magic to heal for [healamt] damage!" temp = "You use [pointamt] magic to heal for [healamt] damage!"
playsound(src, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) playsound(src, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
turtle++ turtle++
sleep(10) sleep(10)
player_mp -= pointamt player_mp -= pointamt
player_hp += healamt player_hp += healamt
blocked = 1 blocked = 1
arcade_action() arcade_action()
else if (href_list["charge"]) if("charge")
blocked = 1 blocked = 1
var/chargeamt = rand(4,7) var/chargeamt = rand(4,7)
temp = "You regain [chargeamt] points" temp = "You regain [chargeamt] points"
playsound(src, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) playsound(src, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
player_mp += chargeamt player_mp += chargeamt
if(turtle > 0) if(turtle > 0)
turtle-- turtle--
sleep(10) sleep(10)
arcade_action() arcade_action()
else if (href_list["newgame"]) //Reset everything if(action == "newgame") //Reset everything
temp = "New Round" temp = "New Round"
player_hp = 30 player_hp = 30
player_mp = 10 player_mp = 10
@@ -191,12 +189,11 @@
turtle = 0 turtle = 0
if(emagged) if(emagged)
src.New() randomize_characters()
emagged = 0 emagged = 0
src.add_fingerprint(usr) add_fingerprint(usr)
SSnanoui.update_uis(src) return TRUE
return
/obj/machinery/computer/arcade/battle/proc/arcade_action() /obj/machinery/computer/arcade/battle/proc/arcade_action()
if ((enemy_mp <= 0) || (enemy_hp <= 0)) if ((enemy_mp <= 0) || (enemy_hp <= 0))
@@ -211,7 +208,7 @@
new /obj/item/clothing/head/collectable/petehat(src.loc) new /obj/item/clothing/head/collectable/petehat(src.loc)
message_admins("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.") message_admins("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.")
log_game("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.") log_game("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.")
src.New() randomize_characters()
emagged = 0 emagged = 0
else if(!contents.len) else if(!contents.len)
feedback_inc("arcade_win_normal") feedback_inc("arcade_win_normal")

View File

@@ -36,6 +36,13 @@
return return
tgui_interact(user) tgui_interact(user)
/obj/machinery/computer/security/attack_robot(mob/user)
if(isrobot(user))
var/mob/living/silicon/robot/R = user
if(!R.shell)
return attack_hand(user)
..()
/obj/machinery/computer/security/attack_ai(mob/user) /obj/machinery/computer/security/attack_ai(mob/user)
if(isAI(user)) if(isAI(user))
to_chat(user, "<span class='notice'>You realise its kind of stupid to access a camera console when you have the entire camera network at your metaphorical fingertips</span>") to_chat(user, "<span class='notice'>You realise its kind of stupid to access a camera console when you have the entire camera network at your metaphorical fingertips</span>")

View File

@@ -26,7 +26,7 @@
var/list/formatted = list() var/list/formatted = list()
for(var/job in jobs) for(var/job in jobs)
formatted.Add(list(list( formatted.Add(list(list(
"display_name" = replacetext(job, " ", "&nbsp"), "display_name" = replacetext(job, " ", "&nbsp;"),
"target_rank" = get_target_rank(), "target_rank" = get_target_rank(),
"job" = job))) "job" = job)))
@@ -68,7 +68,7 @@
id_card.forceMove(src) id_card.forceMove(src)
modify = id_card modify = id_card
SSnanoui.update_uis(src) SStgui.update_uis(src)
attack_hand(user) attack_hand(user)
/obj/machinery/computer/card/attack_ai(var/mob/user as mob) /obj/machinery/computer/card/attack_ai(var/mob/user as mob)
@@ -77,20 +77,27 @@
/obj/machinery/computer/card/attack_hand(mob/user as mob) /obj/machinery/computer/card/attack_hand(mob/user as mob)
if(..()) return if(..()) return
if(stat & (NOPOWER|BROKEN)) return if(stat & (NOPOWER|BROKEN)) return
ui_interact(user) tgui_interact(user)
/obj/machinery/computer/card/ui_interact(mob/user, ui_key="main", var/datum/nanoui/ui = null, var/force_open = 1) /obj/machinery/computer/card/tgui_interact(mob/user, datum/tgui/ui)
user.set_machine(src) ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "IdentificationComputer", name)
ui.open()
/obj/machinery/computer/card/tgui_static_data(mob/user)
var/list/data = ..()
if(data_core) if(data_core)
data_core.get_manifest_list() data_core.get_manifest_list()
data["manifest"] = PDA_Manifest
return data
/obj/machinery/computer/card/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
var/data[0]
data["src"] = "\ref[src]"
data["station_name"] = station_name() data["station_name"] = station_name()
data["mode"] = mode data["mode"] = mode
data["printing"] = printing data["printing"] = printing
data["manifest"] = PDA_Manifest
data["target_name"] = modify ? modify.name : "-----" data["target_name"] = modify ? modify.name : "-----"
data["target_owner"] = modify && modify.registered_name ? modify.registered_name : "-----" data["target_owner"] = modify && modify.registered_name ? modify.registered_name : "-----"
data["target_rank"] = get_target_rank() data["target_rank"] = get_target_rank()
@@ -110,27 +117,27 @@
continue continue
if(dept.centcom_only && !is_centcom()) if(dept.centcom_only && !is_centcom())
continue continue
departments[++departments.len] = list("department_name" = dept.name, "jobs" = format_jobs(SSjob.get_job_titles_in_department(dept.name)) ) departments.Add(list(list(
"department_name" = dept.name,
"jobs" = format_jobs(SSjob.get_job_titles_in_department(dept.name))
)))
data["departments"] = departments data["departments"] = departments
if (modify && is_centcom()) var/list/all_centcom_access = list()
var/list/all_centcom_access = list() var/list/regions = list()
if(modify && is_centcom())
for(var/access in get_all_centcom_access()) for(var/access in get_all_centcom_access())
all_centcom_access.Add(list(list( all_centcom_access.Add(list(list(
"desc" = replacetext(get_centcom_access_desc(access), " ", "&nbsp"), "desc" = replacetext(get_centcom_access_desc(access), " ", "&nbsp;"),
"ref" = access, "ref" = access,
"allowed" = (access in modify.access) ? 1 : 0))) "allowed" = (access in modify.access) ? 1 : 0)))
else if(modify)
data["all_centcom_access"] = all_centcom_access for(var/i in ACCESS_REGION_SECURITY to ACCESS_REGION_SUPPLY)
else if (modify)
var/list/regions = list()
for(var/i = 1; i <= 7; i++)
var/list/accesses = list() var/list/accesses = list()
for(var/access in get_region_accesses(i)) for(var/access in get_region_accesses(i))
if (get_access_desc(access)) if (get_access_desc(access))
accesses.Add(list(list( accesses.Add(list(list(
"desc" = replacetext(get_access_desc(access), " ", "&nbsp"), "desc" = replacetext(get_access_desc(access), " ", "&nbsp;"),
"ref" = access, "ref" = access,
"allowed" = (access in modify.access) ? 1 : 0))) "allowed" = (access in modify.access) ? 1 : 0)))
@@ -138,23 +145,20 @@
"name" = get_region_accesses_name(i), "name" = get_region_accesses_name(i),
"accesses" = accesses))) "accesses" = accesses)))
data["regions"] = regions data["regions"] = regions
data["all_centcom_access"] = all_centcom_access
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) return data
if (!ui)
ui = new(user, src, ui_key, "identification_computer.tmpl", src.name, 600, 700)
ui.set_initial_data(data)
ui.open()
/obj/machinery/computer/card/Topic(href, href_list) /obj/machinery/computer/card/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..()) if(..())
return 1 return TRUE
switch(href_list["choice"]) switch(action)
if ("modify") if("modify")
if (modify) if(modify)
data_core.manifest_modify(modify.registered_name, modify.assignment) data_core.manifest_modify(modify.registered_name, modify.assignment)
modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])") modify.name = "[modify.registered_name]'s ID Card ([modify.assignment])"
if(ishuman(usr)) if(ishuman(usr))
modify.forceMove(get_turf(src)) modify.forceMove(get_turf(src))
if(!usr.get_active_hand()) if(!usr.get_active_hand())
@@ -165,12 +169,13 @@
modify = null modify = null
else else
var/obj/item/I = usr.get_active_hand() var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) if(istype(I, /obj/item/weapon/card/id) && usr.unEquip(I))
I.forceMove(src) I.forceMove(src)
modify = I modify = I
. = TRUE
if ("scan") if("scan")
if (scan) if(scan)
if(ishuman(usr)) if(ishuman(usr))
scan.forceMove(get_turf(src)) scan.forceMove(get_turf(src))
if(!usr.get_active_hand()) if(!usr.get_active_hand())
@@ -181,25 +186,26 @@
scan = null scan = null
else else
var/obj/item/I = usr.get_active_hand() var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id)) if(istype(I, /obj/item/weapon/card/id))
usr.drop_item() usr.drop_item()
I.forceMove(src) I.forceMove(src)
scan = I scan = I
. = TRUE
if("access") if("access")
if(href_list["allowed"]) if(is_authenticated())
if(is_authenticated()) var/access_type = text2num(params["access_target"])
var/access_type = text2num(href_list["access_target"]) var/access_allowed = text2num(params["allowed"])
var/access_allowed = text2num(href_list["allowed"]) if(access_type in (is_centcom() ? get_all_centcom_access() : get_all_station_access()))
if(access_type in (is_centcom() ? get_all_centcom_access() : get_all_station_access())) modify.access -= access_type
modify.access -= access_type if(!access_allowed)
if(!access_allowed) modify.access += access_type
modify.access += access_type modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications
modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications . = TRUE
if ("assign") if("assign")
if (is_authenticated() && modify) if(is_authenticated() && modify)
var/t1 = href_list["assign_target"] var/t1 = params["assign_target"]
if(t1 == "Custom") if(t1 == "Custom")
var/temp_t = sanitize(input("Enter a custom job assignment.","Assignment"), 45) var/temp_t = sanitize(input("Enter a custom job assignment.","Assignment"), 45)
//let custom jobs function as an impromptu alt title, mainly for sechuds //let custom jobs function as an impromptu alt title, mainly for sechuds
@@ -222,44 +228,42 @@
modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications
callHook("reassign_employee", list(modify)) callHook("reassign_employee", list(modify))
. = TRUE
if ("reg") if("reg")
if (is_authenticated()) if(is_authenticated())
var/t2 = modify var/temp_name = sanitizeName(params["reg"])
if ((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf))) if(temp_name)
var/temp_name = sanitizeName(href_list["reg"]) modify.registered_name = temp_name
if(temp_name) else
modify.registered_name = temp_name visible_message("<span class='notice'>[src] buzzes rudely.</span>")
else . = TRUE
src.visible_message("<span class='notice'>[src] buzzes rudely.</span>")
SSnanoui.update_uis(src)
if ("account") if("account")
if (is_authenticated()) if(is_authenticated())
var/t2 = modify var/account_num = text2num(params["account"])
if ((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf))) modify.associated_account_number = account_num
var/account_num = text2num(href_list["account"]) . = TRUE
modify.associated_account_number = account_num
SSnanoui.update_uis(src)
if ("mode") if("mode")
mode = text2num(href_list["mode_target"]) mode = text2num(params["mode_target"])
. = TRUE
if ("print") if("print")
if (!printing) if(!printing)
printing = 1 printing = 1
spawn(50) spawn(50)
printing = null printing = null
SSnanoui.update_uis(src) SStgui.update_uis(src)
var/obj/item/weapon/paper/P = new(loc) var/obj/item/weapon/paper/P = new(loc)
if (mode) if(mode)
P.name = text("crew manifest ([])", stationtime2text()) P.name = text("crew manifest ([])", stationtime2text())
P.info = {"<h4>Crew Manifest</h4> P.info = {"<h4>Crew Manifest</h4>
<br> <br>
[data_core ? data_core.get_manifest(0) : ""] [data_core ? data_core.get_manifest(0) : ""]
"} "}
else if (modify) else if(modify)
P.name = "access report" P.name = "access report"
P.info = {"<h4>Access Report</h4> P.info = {"<h4>Access Report</h4>
<u>Prepared By:</u> [scan.registered_name ? scan.registered_name : "Unknown"]<br> <u>Prepared By:</u> [scan.registered_name ? scan.registered_name : "Unknown"]<br>
@@ -273,19 +277,20 @@
for(var/A in modify.access) for(var/A in modify.access)
P.info += " [get_access_desc(A)]" P.info += " [get_access_desc(A)]"
. = TRUE
if ("terminate") if("terminate")
if (is_authenticated()) if(is_authenticated())
modify.assignment = "Dismissed" //VOREStation Edit: setting adjustment modify.assignment = "Dismissed" //VOREStation Edit: setting adjustment
modify.access = list() modify.access = list()
modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications
callHook("terminate_employee", list(modify)) callHook("terminate_employee", list(modify))
if (modify) . = TRUE
modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])")
return 1 if(modify)
modify.name = "[modify.registered_name]'s ID Card ([modify.assignment])"
/obj/machinery/computer/card/centcom /obj/machinery/computer/card/centcom
name = "\improper CentCom ID card modification console" name = "\improper CentCom ID card modification console"

View File

@@ -9,553 +9,24 @@
light_color = "#0099ff" light_color = "#0099ff"
req_access = list(access_heads) req_access = list(access_heads)
circuit = /obj/item/weapon/circuitboard/communications circuit = /obj/item/weapon/circuitboard/communications
var/prints_intercept = 1
var/authenticated = 0
var/list/messagetitle = list()
var/list/messagetext = list()
var/currmsg = 0
var/aicurrmsg = 0
var/state = STATE_DEFAULT
var/aistate = STATE_DEFAULT
var/message_cooldown = 0
var/centcomm_message_cooldown = 0
var/tmp_alertlevel = 0
var/const/STATE_DEFAULT = 1
var/const/STATE_CALLSHUTTLE = 2
var/const/STATE_CANCELSHUTTLE = 3
var/const/STATE_MESSAGELIST = 4
var/const/STATE_VIEWMESSAGE = 5
var/const/STATE_DELMESSAGE = 6
var/const/STATE_STATUSDISPLAY = 7
var/const/STATE_ALERT_LEVEL = 8
var/const/STATE_CONFIRM_LEVEL = 9
var/const/STATE_CREWTRANSFER = 10
var/status_display_freq = "1435" var/datum/tgui_module/communications/communications
var/stat_msg1
var/stat_msg2
var/datum/lore/atc_controller/ATC /obj/machinery/computer/communications/Initialize()
var/datum/announcement/priority/crew_announcement = new . = ..()
communications = new(src)
/obj/machinery/computer/communications/New()
..()
ATC = atc
crew_announcement.newscast = 1
/obj/machinery/computer/communications/process()
if(..())
if(state != STATE_STATUSDISPLAY)
src.updateDialog()
/obj/machinery/computer/communications/Topic(href, href_list)
if(..())
return 1
if (using_map && !(src.z in using_map.contact_levels))
to_chat(usr, "<font color='red'><b>Unable to establish a connection:</b></font> <font color='black'>You're too far away from the station!</font>")
return
usr.set_machine(src)
if(!href_list["operation"])
return
switch(href_list["operation"])
// main interface
if("main")
src.state = STATE_DEFAULT
if("login")
var/mob/M = usr
var/obj/item/weapon/card/id/I = M.GetIdCard()
if (I && istype(I))
if(src.check_access(I))
authenticated = 1
if(access_captain in I.access)
authenticated = 2
crew_announcement.announcer = GetNameAndAssignmentFromId(I)
if("logout")
authenticated = 0
crew_announcement.announcer = ""
if("swipeidseclevel")
if(src.authenticated) //Let heads change the alert level.
var/old_level = security_level
if(!tmp_alertlevel) tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel < SEC_LEVEL_GREEN) tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel > SEC_LEVEL_BLUE) tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this
set_security_level(tmp_alertlevel)
if(security_level != old_level)
//Only notify the admins if an actual change happened
log_game("[key_name(usr)] has changed the security level to [get_security_level()].")
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
switch(security_level)
if(SEC_LEVEL_GREEN)
feedback_inc("alert_comms_green",1)
if(SEC_LEVEL_YELLOW)
feedback_inc("alert_comms_yellow",1)
if(SEC_LEVEL_VIOLET)
feedback_inc("alert_comms_violet",1)
if(SEC_LEVEL_ORANGE)
feedback_inc("alert_comms_orange",1)
if(SEC_LEVEL_BLUE)
feedback_inc("alert_comms_blue",1)
tmp_alertlevel = 0
state = STATE_DEFAULT
if("announce")
if(src.authenticated==2)
if(message_cooldown)
to_chat(usr, "Please allow at least one minute to pass between announcements")
return
var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") as null|message
if(!input || !(usr in view(1,src)))
return
crew_announcement.Announce(input)
message_cooldown = 1
spawn(600)//One minute cooldown
message_cooldown = 0
if("callshuttle")
src.state = STATE_DEFAULT
if(src.authenticated)
src.state = STATE_CALLSHUTTLE
if("callshuttle2")
if(src.authenticated)
call_shuttle_proc(usr)
if(emergency_shuttle.online())
post_status("shuttle")
src.state = STATE_DEFAULT
if("cancelshuttle")
src.state = STATE_DEFAULT
if(src.authenticated)
src.state = STATE_CANCELSHUTTLE
if("cancelshuttle2")
if(src.authenticated)
cancel_call_proc(usr)
src.state = STATE_DEFAULT
if("messagelist")
src.currmsg = 0
src.state = STATE_MESSAGELIST
if("toggleatc")
src.ATC.squelched = !src.ATC.squelched
if("viewmessage")
src.state = STATE_VIEWMESSAGE
if (!src.currmsg)
if(href_list["message-num"])
src.currmsg = text2num(href_list["message-num"])
else
src.state = STATE_MESSAGELIST
if("delmessage")
src.state = (src.currmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
if("delmessage2")
if(src.authenticated)
if(src.currmsg)
var/title = src.messagetitle[src.currmsg]
var/text = src.messagetext[src.currmsg]
src.messagetitle.Remove(title)
src.messagetext.Remove(text)
if(src.currmsg == src.aicurrmsg)
src.aicurrmsg = 0
src.currmsg = 0
src.state = STATE_MESSAGELIST
else
src.state = STATE_VIEWMESSAGE
if("status")
src.state = STATE_STATUSDISPLAY
// Status display stuff
if("setstat")
switch(href_list["statdisp"])
if("message")
post_status("message", stat_msg1, stat_msg2)
if("alert")
post_status("alert", href_list["alert"])
else
post_status(href_list["statdisp"])
if("setmsg1")
stat_msg1 = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40), 40)
src.updateDialog()
if("setmsg2")
stat_msg2 = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40), 40)
src.updateDialog()
// OMG CENTCOMM LETTERHEAD
if("MessageCentCom")
if(src.authenticated==2)
if(centcomm_message_cooldown)
to_chat(usr, "<font color='red'>Arrays recycling. Please stand by.</font>")
return
var/input = sanitize(input("Please choose a message to transmit to [using_map.boss_short] via quantum entanglement. \
Please be aware that this process is very expensive, and abuse will lead to... termination. \
Transmission does not guarantee a response. \
There is a 30 second delay before you may send another message, be clear, full and concise.", "Central Command Quantum Messaging") as null|message)
if(!input || !(usr in view(1,src)))
return
CentCom_announce(input, usr)
to_chat(usr, "<font color='blue'>Message transmitted.</font>")
log_game("[key_name(usr)] has made an IA [using_map.boss_short] announcement: [input]")
centcomm_message_cooldown = 1
spawn(300)//10 minute cooldown
centcomm_message_cooldown = 0
// OMG SYNDICATE ...LETTERHEAD
if("MessageSyndicate")
if((src.authenticated==2) && (src.emagged))
if(centcomm_message_cooldown)
to_chat(usr, "<font color='red'>Arrays recycling. Please stand by.</font>")
return
var/input = sanitize(input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", ""))
if(!input || !(usr in view(1,src)))
return
Syndicate_announce(input, usr)
to_chat(usr, "<font color='blue'>Message transmitted.</font>")
log_game("[key_name(usr)] has made an illegal announcement: [input]")
centcomm_message_cooldown = 1
spawn(300)//10 minute cooldown
centcomm_message_cooldown = 0
if("RestoreBackup")
to_chat(usr, "Backup routing data restored!")
src.emagged = 0
src.updateDialog()
// AI interface
if("ai-main")
src.aicurrmsg = 0
src.aistate = STATE_DEFAULT
if("ai-callshuttle")
src.aistate = STATE_CALLSHUTTLE
if("ai-callshuttle2")
call_shuttle_proc(usr)
src.aistate = STATE_DEFAULT
if("ai-messagelist")
src.aicurrmsg = 0
src.aistate = STATE_MESSAGELIST
if("ai-viewmessage")
src.aistate = STATE_VIEWMESSAGE
if (!src.aicurrmsg)
if(href_list["message-num"])
src.aicurrmsg = text2num(href_list["message-num"])
else
src.aistate = STATE_MESSAGELIST
if("ai-delmessage")
src.aistate = (src.aicurrmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
if("ai-delmessage2")
if(src.aicurrmsg)
var/title = src.messagetitle[src.aicurrmsg]
var/text = src.messagetext[src.aicurrmsg]
src.messagetitle.Remove(title)
src.messagetext.Remove(text)
if(src.currmsg == src.aicurrmsg)
src.currmsg = 0
src.aicurrmsg = 0
src.aistate = STATE_MESSAGELIST
if("ai-status")
src.aistate = STATE_STATUSDISPLAY
if("securitylevel")
src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
if(!tmp_alertlevel) tmp_alertlevel = 0
state = STATE_CONFIRM_LEVEL
if("changeseclevel")
state = STATE_ALERT_LEVEL
src.updateUsrDialog()
/obj/machinery/computer/communications/emag_act(var/remaining_charges, var/mob/user) /obj/machinery/computer/communications/emag_act(var/remaining_charges, var/mob/user)
if(!emagged) if(!emagged)
src.emagged = 1 emagged = TRUE
communications.emagged = TRUE
to_chat(user, "You scramble the communication routing circuits!") to_chat(user, "You scramble the communication routing circuits!")
return 1 return TRUE
/obj/machinery/computer/communications/attack_ai(var/mob/user as mob) /obj/machinery/computer/communications/attack_ai(mob/user)
return src.attack_hand(user) return attack_hand(user)
/obj/machinery/computer/communications/attack_hand(var/mob/user as mob) /obj/machinery/computer/communications/attack_hand(mob/user)
if(..()) if(..())
return return
if (using_map && !(src.z in using_map.contact_levels)) communications.tgui_interact(user)
to_chat(user, "<font color='red'><b>Unable to establish a connection:</b></font> <font color='black'>You're too far away from the station!</font>")
return
user.set_machine(src)
var/dat = "<head><title>Communications Console</title></head><body>"
if (emergency_shuttle.has_eta())
var/timeleft = emergency_shuttle.estimate_arrival_time()
dat += "<B>Emergency shuttle</B>\n<BR>\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]<BR>"
if (istype(user, /mob/living/silicon))
var/dat2 = src.interact_ai(user) // give the AI a different interact proc to limit its access
if(dat2)
dat += dat2
user << browse(dat, "window=communications;size=400x500")
onclose(user, "communications")
return
switch(src.state)
if(STATE_DEFAULT)
if (src.authenticated)
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=logout'>Log Out</A> \]"
if (src.authenticated==2)
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=announce'>Make An Announcement</A> \]"
if(src.emagged == 0)
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=MessageCentCom'>Send an emergency message to [using_map.boss_short]</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=MessageSyndicate'>Send an emergency message to \[UNKNOWN\]</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=RestoreBackup'>Restore Backup Routing Data</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=changeseclevel'>Change alert level</A> \]"
if(emergency_shuttle.location())
if (emergency_shuttle.online())
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=cancelshuttle'>Cancel Shuttle Call</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=callshuttle'>Call Emergency Shuttle</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=status'>Set Status Display</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=login'>Log In</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=messagelist'>Message List</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=toggleatc'>[ATC.squelched ? "Enable" : "Disable"] ATC Relay</A> \]"
if(STATE_CALLSHUTTLE)
dat += "Are you sure you want to call the shuttle? \[ <A HREF='?src=\ref[src];operation=callshuttle2'>OK</A> | <A HREF='?src=\ref[src];operation=main'>Cancel</A> \]"
if(STATE_CANCELSHUTTLE)
dat += "Are you sure you want to cancel the shuttle? \[ <A HREF='?src=\ref[src];operation=cancelshuttle2'>OK</A> | <A HREF='?src=\ref[src];operation=main'>Cancel</A> \]"
if(STATE_MESSAGELIST)
dat += "Messages:"
for(var/i = 1; i<=src.messagetitle.len; i++)
dat += "<BR><A HREF='?src=\ref[src];operation=viewmessage;message-num=[i]'>[src.messagetitle[i]]</A>"
if(STATE_VIEWMESSAGE)
if (src.currmsg)
dat += "<B>[src.messagetitle[src.currmsg]]</B><BR><BR>[src.messagetext[src.currmsg]]"
if (src.authenticated)
dat += "<BR><BR>\[ <A HREF='?src=\ref[src];operation=delmessage'>Delete \]"
else
src.state = STATE_MESSAGELIST
src.attack_hand(user)
return
if(STATE_DELMESSAGE)
if (src.currmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=\ref[src];operation=delmessage2'>OK</A> | <A HREF='?src=\ref[src];operation=viewmessage'>Cancel</A> \]"
else
src.state = STATE_MESSAGELIST
src.attack_hand(user)
return
if(STATE_STATUSDISPLAY)
dat += "Set Status Displays<BR>"
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=blank'>Clear</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=time'>Station Time</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=message'>Message</A> \]"
dat += "<ul><li> Line 1: <A HREF='?src=\ref[src];operation=setmsg1'>[ stat_msg1 ? stat_msg1 : "(none)"]</A>"
dat += "<li> Line 2: <A HREF='?src=\ref[src];operation=setmsg2'>[ stat_msg2 ? stat_msg2 : "(none)"]</A></ul><br>"
dat += "\[ Alert: <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=default'>None</A> |"
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
if(STATE_ALERT_LEVEL)
dat += "Current alert level: [get_security_level()]<BR>"
if(security_level == SEC_LEVEL_DELTA)
dat += "<font color='red'><b>The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate.</b></font>"
else
dat += "<A HREF='?src=\ref[src];operation=securitylevel;newalertlevel=[SEC_LEVEL_BLUE]'>Blue</A><BR>"
dat += "<A HREF='?src=\ref[src];operation=securitylevel;newalertlevel=[SEC_LEVEL_ORANGE]'>Orange</A><BR>"
dat += "<A HREF='?src=\ref[src];operation=securitylevel;newalertlevel=[SEC_LEVEL_VIOLET]'>Violet</A><BR>"
dat += "<A HREF='?src=\ref[src];operation=securitylevel;newalertlevel=[SEC_LEVEL_YELLOW]'>Yellow</A><BR>"
dat += "<A HREF='?src=\ref[src];operation=securitylevel;newalertlevel=[SEC_LEVEL_GREEN]'>Green</A>"
if(STATE_CONFIRM_LEVEL)
dat += "Current alert level: [get_security_level()]<BR>"
dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]<BR>"
dat += "<A HREF='?src=\ref[src];operation=swipeidseclevel'>OK</A> to confirm change.<BR>"
dat += "<BR>\[ [(src.state != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
user << browse(dat, "window=communications;size=400x500")
onclose(user, "communications")
/obj/machinery/computer/communications/proc/interact_ai(var/mob/living/silicon/ai/user as mob)
var/dat = ""
switch(src.aistate)
if(STATE_DEFAULT)
if(emergency_shuttle.location() && !emergency_shuttle.online())
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=ai-callshuttle'>Call Emergency Shuttle</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=ai-messagelist'>Message List</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=ai-status'>Set Status Display</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=toggleatc'>[ATC.squelched ? "Enable" : "Disable"] ATC Relay</A> \]"
if(STATE_CALLSHUTTLE)
dat += "Are you sure you want to call the shuttle? \[ <A HREF='?src=\ref[src];operation=ai-callshuttle2'>OK</A> | <A HREF='?src=\ref[src];operation=ai-main'>Cancel</A> \]"
if(STATE_MESSAGELIST)
dat += "Messages:"
for(var/i = 1; i<=src.messagetitle.len; i++)
dat += "<BR><A HREF='?src=\ref[src];operation=ai-viewmessage;message-num=[i]'>[src.messagetitle[i]]</A>"
if(STATE_VIEWMESSAGE)
if (src.aicurrmsg)
dat += "<B>[src.messagetitle[src.aicurrmsg]]</B><BR><BR>[src.messagetext[src.aicurrmsg]]"
dat += "<BR><BR>\[ <A HREF='?src=\ref[src];operation=ai-delmessage'>Delete</A> \]"
else
src.aistate = STATE_MESSAGELIST
src.attack_hand(user)
return null
if(STATE_DELMESSAGE)
if(src.aicurrmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=\ref[src];operation=ai-delmessage2'>OK</A> | <A HREF='?src=\ref[src];operation=ai-viewmessage'>Cancel</A> \]"
else
src.aistate = STATE_MESSAGELIST
src.attack_hand(user)
return
if(STATE_STATUSDISPLAY)
dat += "Set Status Displays<BR>"
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=blank'>Clear</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=time'>Station Time</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=message'>Message</A> \]"
dat += "<ul><li> Line 1: <A HREF='?src=\ref[src];operation=setmsg1'>[ stat_msg1 ? stat_msg1 : "(none)"]</A>"
dat += "<li> Line 2: <A HREF='?src=\ref[src];operation=setmsg2'>[ stat_msg2 ? stat_msg2 : "(none)"]</A></ul><br>"
dat += "\[ Alert: <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=default'>None</A> |"
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
dat += "<BR>\[ [(src.aistate != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=ai-main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
return dat
/proc/enable_prison_shuttle(var/mob/user)
for(var/obj/machinery/computer/prison_shuttle/PS in machines)
PS.allowedtocall = !(PS.allowedtocall)
/proc/call_shuttle_proc(var/mob/user)
if ((!( ticker ) || !emergency_shuttle.location()))
return
if(!universe.OnShuttleCall(usr))
to_chat(user, "<span class='notice'>Cannot establish a bluespace connection.</span>")
return
if(deathsquad.deployed)
to_chat(user, "[using_map.boss_short] will not allow the shuttle to be called. Consider all contracts terminated.")
return
if(emergency_shuttle.deny_shuttle)
to_chat(user, "The emergency shuttle may not be sent at this time. Please try again later.")
return
if(world.time < 6000) // Ten minute grace period to let the game get going without lolmetagaming. -- TLE
to_chat(user, "The emergency shuttle is refueling. Please wait another [round((6000-world.time)/600)] minute\s before trying again.")
return
if(emergency_shuttle.going_to_centcom())
to_chat(user, "The emergency shuttle may not be called while returning to [using_map.boss_short].")
return
if(emergency_shuttle.online())
to_chat(user, "The emergency shuttle is already on its way.")
return
if(ticker.mode.name == "blob")
to_chat(user, "Under directive 7-10, [station_name()] is quarantined until further notice.")
return
emergency_shuttle.call_evac()
log_game("[key_name(user)] has called the shuttle.")
message_admins("[key_name_admin(user)] has called the shuttle.", 1)
admin_chat_message(message = "Emergency evac beginning! Called by [key_name(user)]!", color = "#CC2222") //VOREStation Add
return
/proc/init_shift_change(var/mob/user, var/force = 0)
if ((!( ticker ) || !emergency_shuttle.location()))
return
if(emergency_shuttle.going_to_centcom())
to_chat(user, "The shuttle may not be called while returning to [using_map.boss_short].")
return
if(emergency_shuttle.online())
to_chat(user, "The shuttle is already on its way.")
return
// if force is 0, some things may stop the shuttle call
if(!force)
if(emergency_shuttle.deny_shuttle)
to_chat(user, "[using_map.boss_short] does not currently have a shuttle available in your sector. Please try again later.")
return
if(deathsquad.deployed == 1)
to_chat(user, "[using_map.boss_short] will not allow the shuttle to be called. Consider all contracts terminated.")
return
if(world.time < 54000) // 30 minute grace period to let the game get going
to_chat(user, "The shuttle is refueling. Please wait another [round((54000-world.time)/60)] minutes before trying again.")
return
if(ticker.mode.auto_recall_shuttle)
//New version pretends to call the shuttle but cause the shuttle to return after a random duration.
emergency_shuttle.auto_recall = 1
if(ticker.mode.name == "blob" || ticker.mode.name == "epidemic")
to_chat(user, "Under directive 7-10, [station_name()] is quarantined until further notice.")
return
emergency_shuttle.call_transfer()
//delay events in case of an autotransfer
if (isnull(user))
SSevents.delay_events(EVENT_LEVEL_MODERATE, 9000) //15 minutes
SSevents.delay_events(EVENT_LEVEL_MAJOR, 9000)
log_game("[user? key_name(user) : "Autotransfer"] has called the shuttle.")
message_admins("[user? key_name_admin(user) : "Autotransfer"] has called the shuttle.", 1)
admin_chat_message(message = "Autotransfer shuttle dispatched, shift ending soon.", color = "#2277BB") //VOREStation Add
return
/proc/cancel_call_proc(var/mob/user)
if (!( ticker ) || !emergency_shuttle.can_recall())
return
if((ticker.mode.name == "blob")||(ticker.mode.name == "Meteor"))
return
if(!emergency_shuttle.going_to_centcom()) //check that shuttle isn't already heading to CentCom
emergency_shuttle.recall()
log_game("[key_name(user)] has recalled the shuttle.")
message_admins("[key_name_admin(user)] has recalled the shuttle.", 1)
return
/proc/is_relay_online()
for(var/obj/machinery/telecomms/relay/M in world)
if(M.stat == 0)
return 1
return 0
/obj/machinery/computer/communications/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 = TRANSMISSION_RADIO
status_signal.data["command"] = command
switch(command)
if("message")
status_signal.data["msg1"] = data1
status_signal.data["msg2"] = data2
log_admin("STATUS: [src.fingerprintslast] set status screen message with [src]: [data1] [data2]")
//message_admins("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]")
if("alert")
status_signal.data["picture_state"] = data1
frequency.post_signal(src, status_signal)

View File

@@ -13,14 +13,14 @@
var/reason = "NOT SPECIFIED" var/reason = "NOT SPECIFIED"
/obj/item/weapon/card/id/guest/GetAccess() /obj/item/weapon/card/id/guest/GetAccess()
if (world.time > expiration_time) if(world.time > expiration_time)
return access return access
else else
return temp_access return temp_access
/obj/item/weapon/card/id/guest/examine(mob/user) /obj/item/weapon/card/id/guest/examine(mob/user)
. = ..() . = ..()
if (world.time < expiration_time) if(world.time < expiration_time)
. += "<span class='notice'>This pass expires at [worldtime2stationtime(expiration_time)].</span>" . += "<span class='notice'>This pass expires at [worldtime2stationtime(expiration_time)].</span>"
else else
. += "<span class='warning'>It expired at [worldtime2stationtime(expiration_time)].</span>" . += "<span class='warning'>It expired at [worldtime2stationtime(expiration_time)].</span>"
@@ -28,7 +28,7 @@
/obj/item/weapon/card/id/guest/read() /obj/item/weapon/card/id/guest/read()
if(!Adjacent(usr)) if(!Adjacent(usr))
return //Too far to read return //Too far to read
if (world.time > expiration_time) if(world.time > expiration_time)
to_chat(usr, "<span class='notice'>This pass expired at [worldtime2stationtime(expiration_time)].</span>") to_chat(usr, "<span class='notice'>This pass expired at [worldtime2stationtime(expiration_time)].</span>")
else else
to_chat(usr, "<span class='notice'>This pass expires at [worldtime2stationtime(expiration_time)].</span>") to_chat(usr, "<span class='notice'>This pass expires at [worldtime2stationtime(expiration_time)].</span>")
@@ -105,7 +105,7 @@
if(!giver && user.unEquip(I)) if(!giver && user.unEquip(I))
I.forceMove(src) I.forceMove(src)
giver = I giver = I
SSnanoui.update_uis(src) SStgui.update_uis(src)
else if(giver) else if(giver)
to_chat(user, "<span class='warning'>There is already ID card inside.</span>") to_chat(user, "<span class='warning'>There is already ID card inside.</span>")
return return
@@ -119,128 +119,119 @@
return return
user.set_machine(src) user.set_machine(src)
tgui_interact(user)
ui_interact(user) /obj/machinery/computer/guestpass/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GuestPass", name)
ui.open()
/** /obj/machinery/computer/guestpass/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
* Display the NanoUI window for the guest pass console. var/list/data = ..()
*
* See NanoUI documentation for details.
*/
/obj/machinery/computer/guestpass/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = list() var/list/area_list = list()
var/area_list[0] data["access"] = null
if(giver && giver.access)
if (giver && giver.access)
data["access"] = giver.access data["access"] = giver.access
for (var/A in giver.access) for (var/A in giver.access)
if(A in accesses) if(A in accesses)
area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = 1) area_list.Add(list(list("area" = A, "area_name" = get_access_desc(A), "on" = 1)))
else else
area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = null) area_list.Add(list(list("area" = A, "area_name" = get_access_desc(A), "on" = null)))
data["area"] = area_list
data["giver"] = giver data["giver"] = giver
data["giveName"] = giv_name data["giveName"] = giv_name
data["reason"] = reason data["reason"] = reason
data["duration"] = duration data["duration"] = duration
data["area"] = area_list
data["mode"] = mode data["mode"] = mode
data["log"] = internal_log data["log"] = internal_log
data["uid"] = uid data["uid"] = uid
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) return data
if (!ui)
ui = new(user, src, ui_key, "guest_pass.tmpl", src.name, 400, 520)
ui.set_initial_data(data)
ui.open()
//ui.set_auto_update(5)
/obj/machinery/computer/guestpass/Topic(href, href_list) /obj/machinery/computer/guestpass/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..()) if(..())
return 1 return TRUE
usr.set_machine(src)
if (href_list["mode"])
mode = href_list["mode"]
if (href_list["choice"]) switch(action)
switch(href_list["choice"]) if("mode")
if ("giv_name") mode = params["mode"]
var/nam = sanitizeName(input("Person pass is issued to", "Name", giv_name) as text|null)
if (nam) if("giv_name")
giv_name = nam var/nam = sanitizeName(input("Person pass is issued to", "Name", giv_name) as text|null)
if ("reason") if(nam)
var/reas = sanitize(input("Reason why pass is issued", "Reason", reason) as text|null) giv_name = nam
if(reas) if("reason")
reason = reas var/reas = sanitize(input("Reason why pass is issued", "Reason", reason) as text|null)
if ("duration") if(reas)
var/dur = input("Duration (in minutes) during which pass is valid (up to 120 minutes).", "Duration") as num|null reason = reas
if (dur) if("duration")
if (dur > 0 && dur <= 120) var/dur = input("Duration (in minutes) during which pass is valid (up to 120 minutes).", "Duration") as num|null
duration = dur if(dur)
else if(dur > 0 && dur <= 120)
to_chat(usr, "<span class='warning'>Invalid duration.</span>") duration = dur
if ("access")
var/A = text2num(href_list["access"])
if (A in accesses)
accesses.Remove(A)
else else
if(A in giver.access) //Let's make sure the ID card actually has the access. to_chat(usr, "<span class='warning'>Invalid duration.</span>")
accesses.Add(A) if("access")
else var/A = text2num(params["access"])
to_chat(usr, "<span class='warning'>Invalid selection, please consult technical support if there are any issues.</span>") if(A in accesses)
log_debug("[key_name_admin(usr)] tried selecting an invalid guest pass terminal option.") accesses.Remove(A)
if (href_list["action"]) else
switch(href_list["action"]) if(A in giver.access) //Let's make sure the ID card actually has the access.
if ("id") accesses.Add(A)
if (giver)
if(ishuman(usr))
giver.loc = usr.loc
if(!usr.get_active_hand())
usr.put_in_hands(giver)
giver = null
else
giver.loc = src.loc
giver = null
accesses.Cut()
else else
var/obj/item/I = usr.get_active_hand() to_chat(usr, "<span class='warning'>Invalid selection, please consult technical support if there are any issues.</span>")
if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) log_debug("[key_name_admin(usr)] tried selecting an invalid guest pass terminal option.")
I.loc = src if("id")
giver = I if(giver)
if(ishuman(usr))
if ("print") giver.loc = usr.loc
var/dat = "<h3>Activity log of guest pass terminal #[uid]</h3><br>" if(!usr.get_active_hand())
for (var/entry in internal_log) usr.put_in_hands(giver)
dat += "[entry]<br><hr>" giver = null
//to_chat(usr, "Printing the log, standby...")
//sleep(50)
var/obj/item/weapon/paper/P = new/obj/item/weapon/paper( loc )
P.name = "activity log"
P.info = dat
if ("issue")
if (giver)
var/number = add_zero("[rand(0,9999)]", 4)
var/entry = "\[[stationtime2text()]\] Pass #[number] issued by [giver.registered_name] ([giver.assignment]) to [giv_name]. Reason: [reason]. Grants access to following areas: "
for (var/i=1 to accesses.len)
var/A = accesses[i]
if (A)
var/area = get_access_desc(A)
entry += "[i > 1 ? ", [area]" : "[area]"]"
entry += ". Expires at [worldtime2stationtime(world.time + duration*10*60)]."
internal_log.Add(entry)
var/obj/item/weapon/card/id/guest/pass = new(src.loc)
pass.temp_access = accesses.Copy()
pass.registered_name = giv_name
pass.expiration_time = world.time + duration*10*60
pass.reason = reason
pass.name = "guest pass #[number]"
else else
to_chat(usr, "<span class='warning'>Cannot issue pass without issuing ID.</span>") giver.loc = src.loc
giver = null
accesses.Cut()
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/weapon/card/id) && usr.unEquip(I))
I.loc = src
giver = I
src.add_fingerprint(usr) if("print")
SSnanoui.update_uis(src) var/dat = "<h3>Activity log of guest pass terminal #[uid]</h3><br>"
for (var/entry in internal_log)
dat += "[entry]<br><hr>"
//to_chat(usr, "Printing the log, standby...")
//sleep(50)
var/obj/item/weapon/paper/P = new/obj/item/weapon/paper( loc )
P.name = "activity log"
P.info = dat
if("issue")
if(giver)
var/number = add_zero("[rand(0,9999)]", 4)
var/entry = "\[[stationtime2text()]\] Pass #[number] issued by [giver.registered_name] ([giver.assignment]) to [giv_name]. Reason: [reason]. Grants access to following areas: "
for (var/i=1 to accesses.len)
var/A = accesses[i]
if(A)
var/area = get_access_desc(A)
entry += "[i > 1 ? ", [area]" : "[area]"]"
entry += ". Expires at [worldtime2stationtime(world.time + duration*10*60)]."
internal_log.Add(entry)
var/obj/item/weapon/card/id/guest/pass = new(src.loc)
pass.temp_access = accesses.Copy()
pass.registered_name = giv_name
pass.expiration_time = world.time + duration*10*60
pass.reason = reason
pass.name = "guest pass #[number]"
else
to_chat(usr, "<span class='warning'>Cannot issue pass without issuing ID.</span>")
add_fingerprint(usr)
return TRUE

View File

@@ -131,7 +131,10 @@
//Get out list of viable PDAs //Get out list of viable PDAs
var/list/obj/item/device/pda/sendPDAs = list() var/list/obj/item/device/pda/sendPDAs = list()
for(var/obj/item/device/pda/P in PDAs) for(var/obj/item/device/pda/P in PDAs)
if(!P.owner || P.toff || P.hidden) if(!P.owner || P.hidden)
continue
var/datum/data/pda/app/messenger/M = P.find_program(/datum/data/pda/app/messenger)
if(!M || M.toff)
continue continue
sendPDAs["[P.name]"] = "\ref[P]" sendPDAs["[P.name]"] = "\ref[P]"
data["possibleRecipients"] = sendPDAs data["possibleRecipients"] = sendPDAs
@@ -265,7 +268,11 @@
if("set_recipient") if("set_recipient")
var/ref = params["val"] var/ref = params["val"]
var/obj/item/device/pda/P = locate(ref) var/obj/item/device/pda/P = locate(ref)
if(!istype(P) || !P.owner || P.toff || P.hidden) if(!istype(P) || !P.owner || P.hidden)
return FALSE
var/datum/data/pda/app/messenger/M = P.find_program(/datum/data/pda/app/messenger)
if(!M || M.toff)
return FALSE return FALSE
customrecepient = P customrecepient = P
. = TRUE . = TRUE
@@ -286,22 +293,26 @@
var/obj/item/device/pda/PDARec = null var/obj/item/device/pda/PDARec = null
for(var/obj/item/device/pda/P in PDAs) for(var/obj/item/device/pda/P in PDAs)
if(!P.owner || P.toff || P.hidden) continue if(!P.owner || P.hidden)
continue
var/datum/data/pda/app/messenger/M = P.find_program(/datum/data/pda/app/messenger)
if(!M || M.toff)
continue
if(P.owner == customsender) if(P.owner == customsender)
PDARec = P PDARec = P
//Sender isn't faking as someone who exists //Sender isn't faking as someone who exists
if(isnull(PDARec)) if(isnull(PDARec))
linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]") linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]")
customrecepient.new_message(customsender, customsender, customjob, custommessage) var/datum/data/pda/app/messenger/M = customrecepient.find_program(/datum/data/pda/app/messenger)
if(M)
M.receive_message(list("sent" = 0, "owner" = customsender, "job" = customjob, "message" = custommessage), null)
//Sender is faking as someone who exists //Sender is faking as someone who exists
else else
linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]") linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]")
customrecepient.tnote.Add(list(list("sent" = 0, "owner" = "[PDARec.owner]", "job" = "[customjob]", "message" = "[custommessage]", "target" ="\ref[PDARec]")))
var/datum/data/pda/app/messenger/M = customrecepient.find_program(/datum/data/pda/app/messenger)
if(!customrecepient.conversations.Find("\ref[PDARec]")) if(M)
customrecepient.conversations.Add("\ref[PDARec]") M.receive_message(list("sent" = 0, "owner" = "[PDARec.owner]", "job" = "[customjob]", "message" = "[custommessage]", "target" = "\ref[PDARec]"), "\ref[PDARec]")
customrecepient.new_message(PDARec, custommessage)
//Finally.. //Finally..
ResetMessage() ResetMessage()
. = TRUE . = TRUE

View File

@@ -55,7 +55,7 @@
if(!card && user.unEquip(I)) if(!card && user.unEquip(I))
I.forceMove(src) I.forceMove(src)
card = I card = I
SSnanoui.update_uis(src) SStgui.update_uis(src)
update_icon() update_icon()
else if(card) else if(card)
to_chat(user, "<span class='warning'>There is already ID card inside.</span>") to_chat(user, "<span class='warning'>There is already ID card inside.</span>")

View File

@@ -851,11 +851,13 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/attack_ghost(mob/user) /obj/machinery/door/airlock/attack_ghost(mob/user)
tgui_interact(user) tgui_interact(user)
/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui) /obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state)
ui = SStgui.try_update_ui(user, src, ui) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
ui = new(user, src, "AiAirlock", name) ui = new(user, src, "AiAirlock", name)
ui.open() ui.open()
if(custom_state)
ui.set_state(custom_state)
return TRUE return TRUE
/obj/machinery/door/airlock/tgui_data(mob/user) /obj/machinery/door/airlock/tgui_data(mob/user)

View File

@@ -7,7 +7,6 @@
layer = ABOVE_OBJ_LAYER layer = ABOVE_OBJ_LAYER
var/id_tag var/id_tag
var/datum/topic_state/remote/remote_state
var/obj/machinery/embedded_controller/radio/airlock/master_controller var/obj/machinery/embedded_controller/radio/airlock/master_controller
/obj/machinery/dummy_airlock_controller/process() /obj/machinery/dummy_airlock_controller/process()
@@ -25,15 +24,10 @@
break break
if(!master_controller) if(!master_controller)
qdel(src) qdel(src)
else
remote_state = new /datum/topic_state/remote(src, master_controller)
/obj/machinery/dummy_airlock_controller/Destroy() /obj/machinery/dummy_airlock_controller/Destroy()
if(master_controller) if(master_controller)
master_controller.dummy_terminals -= src master_controller.dummy_terminals -= src
if(remote_state)
qdel(remote_state)
remote_state = null
return ..() return ..()
/obj/machinery/dummy_airlock_controller/interface_interact(var/mob/user) /obj/machinery/dummy_airlock_controller/interface_interact(var/mob/user)

View File

@@ -192,7 +192,6 @@
if(inoperable()) if(inoperable())
to_chat(usr, "\The [src] doesn't appear to function.") to_chat(usr, "\The [src] doesn't appear to function.")
return return
ui_interact(user)
tgui_interact(user) tgui_interact(user)
/obj/machinery/media/jukebox/tgui_status(mob/user) /obj/machinery/media/jukebox/tgui_status(mob/user)

View File

@@ -101,22 +101,22 @@
NEWSCASTER.newsAlert(annoncement) NEWSCASTER.newsAlert(annoncement)
NEWSCASTER.update_icon() NEWSCASTER.update_icon()
var/list/receiving_pdas = new // var/list/receiving_pdas = new
for (var/obj/item/device/pda/P in PDAs) // for (var/obj/item/device/pda/P in PDAs)
if(!P.owner) // if(!P.owner)
continue // continue
if(P.toff) // if(P.toff)
continue // continue
receiving_pdas += P // receiving_pdas += P
spawn(0) // get_receptions sleeps further down the line, spawn of elsewhere // spawn(0) // get_receptions sleeps further down the line, spawn of elsewhere
var/datum/receptions/receptions = get_receptions(null, receiving_pdas) // datums are not atoms, thus we have to assume the newscast network always has reception // var/datum/receptions/receptions = get_receptions(null, receiving_pdas) // datums are not atoms, thus we have to assume the newscast network always has reception
for(var/obj/item/device/pda/PDA in receiving_pdas) // for(var/obj/item/device/pda/PDA in receiving_pdas)
if(!(receptions.receiver_reception[PDA] & TELECOMMS_RECEPTION_RECEIVER)) // if(!(receptions.receiver_reception[PDA] & TELECOMMS_RECEPTION_RECEIVER))
continue // continue
PDA.new_news(annoncement) // PDA.new_news(annoncement)
var/datum/feed_network/news_network = new /datum/feed_network //The global news-network, which is coincidentally a global list. var/datum/feed_network/news_network = new /datum/feed_network //The global news-network, which is coincidentally a global list.

View File

@@ -79,7 +79,7 @@
update_use_power(USE_POWER_IDLE) update_use_power(USE_POWER_IDLE)
/obj/machinery/oxygen_pump/attack_ai(mob/user as mob) /obj/machinery/oxygen_pump/attack_ai(mob/user as mob)
ui_interact(user) tgui_interact(user)
/obj/machinery/oxygen_pump/proc/attach_mask(var/mob/living/carbon/C) /obj/machinery/oxygen_pump/proc/attach_mask(var/mob/living/carbon/C)
if(C && istype(C)) if(C && istype(C))
@@ -176,61 +176,60 @@
set src in oview(1) set src in oview(1)
set category = "Object" set category = "Object"
set name = "Show Tank Settings" set name = "Show Tank Settings"
ui_interact(usr) tgui_interact(usr)
//GUI Tank Setup /obj/machinery/oxygen_pump/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
/obj/machinery/oxygen_pump/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
if(!tank) if(!tank)
to_chat(usr, "<span class='warning'>It is missing a tank!</span>") to_chat(user, "<span class='warning'>[src] is missing a tank.</span>")
data["tankPressure"] = 0 if(ui)
data["releasePressure"] = 0 ui.close()
data["defaultReleasePressure"] = 0 return
data["maxReleasePressure"] = 0
data["maskConnected"] = 0 ui = SStgui.try_update_ui(user, src, ui)
data["tankInstalled"] = 0 if(!ui)
// this is the data which will be sent to the ui ui = new(user, src, "Tank", name)
ui.open()
/obj/machinery/oxygen_pump/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
data["showToggle"] = FALSE
data["maskConnected"] = !!breather
data["tankPressure"] = 0
data["releasePressure"] = 0
data["defaultReleasePressure"] = 0
data["minReleasePressure"] = 0
data["releasePressure"] = round(tank.distribute_pressure ? tank.distribute_pressure : 0)
data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE)
if(tank) if(tank)
data["tankPressure"] = round(tank.air_contents.return_pressure() ? tank.air_contents.return_pressure() : 0) data["tankPressure"] = round(tank.air_contents.return_pressure() ? tank.air_contents.return_pressure() : 0)
data["releasePressure"] = round(tank.distribute_pressure ? tank.distribute_pressure : 0)
data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE) data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE)
data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE)
data["maskConnected"] = 0
data["tankInstalled"] = 1
if(!breather) return data
data["maskConnected"] = 0
if(breather)
data["maskConnected"] = 1
/obj/machinery/oxygen_pump/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
// update the ui if it exists, returns null if no ui is passed/found
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "Oxygen_pump.tmpl", "Tank", 500, 300)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every Master Controller tick
ui.set_auto_update(1)
/obj/machinery/oxygen_pump/Topic(href, href_list)
if(..()) if(..())
return 1 return TRUE
if (href_list["dist_p"]) switch(action)
if (href_list["dist_p"] == "reset") if("pressure")
tank.distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE var/pressure = params["pressure"]
else if (href_list["dist_p"] == "max") if(pressure == "reset")
tank.distribute_pressure = TANK_MAX_RELEASE_PRESSURE pressure = TANK_DEFAULT_RELEASE_PRESSURE
else . = TRUE
var/cp = text2num(href_list["dist_p"]) else if(pressure == "min")
tank.distribute_pressure += cp pressure = 0
tank.distribute_pressure = min(max(round(tank.distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE) . = TRUE
return 1 else if(pressure == "max")
pressure = TANK_MAX_RELEASE_PRESSURE
. = TRUE
else if(text2num(pressure) != null)
pressure = text2num(pressure)
. = TRUE
if(.)
tank.distribute_pressure = clamp(round(pressure), 0, TANK_MAX_RELEASE_PRESSURE)
/obj/machinery/oxygen_pump/anesthetic /obj/machinery/oxygen_pump/anesthetic
name = "anesthetic pump" name = "anesthetic pump"

View File

@@ -233,7 +233,6 @@
/obj/machinery/partslathe/attack_hand(mob/user) /obj/machinery/partslathe/attack_hand(mob/user)
if(..()) if(..())
return return
ui_interact(user)
tgui_interact(user) tgui_interact(user)
/obj/machinery/partslathe/ui_assets(mob/user) /obj/machinery/partslathe/ui_assets(mob/user)

View File

@@ -63,7 +63,9 @@
/obj/machinery/pda_multicaster/proc/update_PDAs(var/turn_off) /obj/machinery/pda_multicaster/proc/update_PDAs(var/turn_off)
for(var/obj/item/device/pda/pda in contents) for(var/obj/item/device/pda/pda in contents)
pda.toff = turn_off var/datum/data/pda/app/messenger/M = pda.find_program(/datum/data/pda/app/messenger/multicast)
if(M)
M.toff = turn_off
/obj/machinery/pda_multicaster/proc/update_power() /obj/machinery/pda_multicaster/proc/update_power()
if(toggle) if(toggle)

View File

@@ -95,7 +95,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
/obj/machinery/pointdefense_control/attackby(var/obj/item/W, var/mob/user) /obj/machinery/pointdefense_control/attackby(var/obj/item/W, var/mob/user)
if(W?.is_multitool()) if(W?.is_multitool())
var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, physical_state)) if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state))
// Check for duplicate controllers with this ID // Check for duplicate controllers with this ID
for(var/thing in pointdefense_controllers) for(var/thing in pointdefense_controllers)
var/obj/machinery/pointdefense_control/PC = thing var/obj/machinery/pointdefense_control/PC = thing
@@ -211,7 +211,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
/obj/machinery/power/pointdefense/attackby(var/obj/item/W, var/mob/user) /obj/machinery/power/pointdefense/attackby(var/obj/item/W, var/mob/user)
if(W?.is_multitool()) if(W?.is_multitool())
var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, physical_state)) if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state))
to_chat(user, "<span class='notice'>You register [src] with the [new_ident] network.</span>") to_chat(user, "<span class='notice'>You register [src] with the [new_ident] network.</span>")
id_tag = new_ident id_tag = new_ident
return return

View File

@@ -66,6 +66,7 @@
var/last_fired = FALSE //TRUE: if the turret is cooling down from a shot, FALSE: turret is ready to fire var/last_fired = FALSE //TRUE: if the turret is cooling down from a shot, FALSE: turret is ready to fire
var/shot_delay = 1.5 SECONDS //1.5 seconds between each shot var/shot_delay = 1.5 SECONDS //1.5 seconds between each shot
var/targetting_is_configurable = TRUE // if false, you cannot change who this turret attacks via its UI
var/check_arrest = TRUE //checks if the perp is set to arrest var/check_arrest = TRUE //checks if the perp is set to arrest
var/check_records = TRUE //checks if a security record exists at all var/check_records = TRUE //checks if a security record exists at all
var/check_weapons = FALSE //checks if it can shoot people that have a weapon they aren't authorized to have var/check_weapons = FALSE //checks if it can shoot people that have a weapon they aren't authorized to have
@@ -81,6 +82,7 @@
var/enabled = TRUE //determines if the turret is on var/enabled = TRUE //determines if the turret is on
var/lethal = FALSE //whether in lethal or stun mode var/lethal = FALSE //whether in lethal or stun mode
var/lethal_is_configurable = TRUE // if false, its lethal setting cannot be changed
var/disabled = FALSE var/disabled = FALSE
var/shot_sound //what sound should play when the turret fires var/shot_sound //what sound should play when the turret fires
@@ -214,6 +216,9 @@
req_one_access = list() req_one_access = list()
installation = /obj/item/weapon/gun/energy/lasertag/omni installation = /obj/item/weapon/gun/energy/lasertag/omni
targetting_is_configurable = FALSE
lethal_is_configurable = FALSE
locked = FALSE locked = FALSE
enabled = FALSE enabled = FALSE
anchored = FALSE anchored = FALSE
@@ -262,43 +267,14 @@
if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag) && check_weapons) // Checks if they are a blue player if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag) && check_weapons) // Checks if they are a blue player
return TURRET_PRIORITY_TARGET return TURRET_PRIORITY_TARGET
/obj/machinery/porta_turret/lasertag/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) /obj/machinery/porta_turret/lasertag/tgui_data(mob/user)
var/data[0] var/list/data = list(
data["access"] = !isLocked(user) "locked" = isLocked(user), // does the current user have access?
data["locked"] = locked "on" = enabled, // is turret turned on?
data["enabled"] = enabled "lethal" = lethal,
//data["is_lethal"] = 1 // VOREStation Removal of "Lethal" setting - it does nothing. Rykka did dis. "lethal_is_configurable" = lethal_is_configurable
//data["lethal"] = lethal // VOREStation Removal of "Lethal" setting - it does nothing. Rykka did dis. )
return data
if(data["access"])
var/settings[0]
settings[++settings.len] = list("category" = "Target Red", "setting" = "check_synth", "value" = check_synth) // Could not get the UI to work with new vars specifically for lasertag turrets -Nalarac
settings[++settings.len] = list("category" = "Target Blue", "setting" = "check_weapons", "value" = check_weapons) // So I'm using these variables since they don't do anything else in this case
data["settings"] = settings
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/porta_turret/lasertag/Topic(href, href_list)
if(..())
return 1
if(href_list["command"] && href_list["value"])
var/value = text2num(href_list["value"])
if(href_list["command"] == "enable")
enabled = value
//else if(href_list["command"] == "lethal") // VOREStation Removal of "Lethal" setting - it does nothing. Rykka did dis.
//lethal = value // VOREStation Removal of "Lethal" setting - it does nothing. Rykka did dis.
else if(href_list["command"] == "check_synth")
check_synth = value
else if(href_list["command"] == "check_weapons")
check_weapons = value
return 1
/obj/machinery/porta_turret/Initialize() /obj/machinery/porta_turret/Initialize()
//Sets up a spark system //Sets up a spark system
@@ -401,102 +377,99 @@
lethal_shot_sound = 'sound/weapons/eluger.ogg' lethal_shot_sound = 'sound/weapons/eluger.ogg'
shot_sound = 'sound/weapons/Taser.ogg' shot_sound = 'sound/weapons/Taser.ogg'
/obj/machinery/porta_turret/proc/isLocked(mob/user)
if(ailock && issilicon(user))
to_chat(user, "<span class='notice'>There seems to be a firewall preventing you from accessing this device.</span>")
return 1
if(locked && !issilicon(user))
to_chat(user, "<span class='notice'>Controls locked.</span>")
return 1
return 0
/obj/machinery/porta_turret/attack_ai(mob/user)
if(isLocked(user))
return
ui_interact(user)
/obj/machinery/porta_turret/attack_hand(mob/user)
if(isLocked(user))
return
ui_interact(user)
/obj/machinery/porta_turret/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
data["access"] = !isLocked(user)
data["locked"] = locked
data["enabled"] = enabled
data["is_lethal"] = 1
data["lethal"] = lethal
if(data["access"])
var/settings[0]
settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth)
settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons)
settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records)
settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest)
settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access)
settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies)
settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all)
settings[++settings.len] = list("category" = "Neutralize Downed Entities", "setting" = "check_down", "value" = check_down)
data["settings"] = settings
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/porta_turret/proc/HasController() /obj/machinery/porta_turret/proc/HasController()
var/area/A = get_area(src) var/area/A = get_area(src)
return A && A.turret_controls.len > 0 return A && A.turret_controls.len > 0
/obj/machinery/porta_turret/CanUseTopic(var/mob/user) /obj/machinery/porta_turret/proc/isLocked(mob/user)
if(HasController()) if(HasController())
to_chat(user, "<span class='notice'>Turrets can only be controlled using the assigned turret controller.</span>") return TRUE
return STATUS_CLOSE if(isrobot(user) || isAI(user))
if(ailock)
to_chat(user, "<span class='notice'>There seems to be a firewall preventing you from accessing this device.</span>")
return TRUE
else
return FALSE
if(isobserver(user))
var/mob/observer/dead/D = user
if(D.can_admin_interact())
return FALSE
else
return TRUE
if(locked)
return TRUE
return FALSE
if(isLocked(user)) /obj/machinery/porta_turret/attack_ai(mob/user)
return STATUS_CLOSE tgui_interact(user)
/obj/machinery/porta_turret/attack_ghost(mob/user)
tgui_interact(user)
/obj/machinery/porta_turret/attack_hand(mob/user)
tgui_interact(user)
/obj/machinery/porta_turret/tgui_interact(mob/user, datum/tgui/ui = null)
if(HasController())
to_chat(user, "<span class='notice'>[src] can only be controlled using the assigned turret controller.</span>")
return
if(!anchored) if(!anchored)
to_chat(user, "<span class='notice'>\The [src] has to be secured first!</span>") to_chat(user, "<span class='notice'>[src] has to be secured first!</span>")
return STATUS_CLOSE return
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PortableTurret", name, 500, 400)
ui.open()
return ..() /obj/machinery/porta_turret/tgui_data(mob/user)
var/list/data = list(
"locked" = isLocked(user), // does the current user have access?
"on" = enabled,
"targetting_is_configurable" = targetting_is_configurable, // If false, targetting settings don't show up
"lethal" = lethal,
"lethal_is_configurable" = lethal_is_configurable,
"check_weapons" = check_weapons,
"neutralize_noaccess" = check_access,
"neutralize_norecord" = check_records,
"neutralize_criminals" = check_arrest,
"neutralize_all" = check_all,
"neutralize_nonsynth" = check_synth,
"neutralize_unidentified" = check_anomalies,
"neutralize_down" = check_down,
)
return data
/obj/machinery/porta_turret/Topic(href, href_list) /obj/machinery/porta_turret/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..()) if(..())
return 1 return TRUE
if(isLocked(usr))
return TRUE
. = TRUE
if(href_list["command"] && href_list["value"]) switch(action)
var/value = text2num(href_list["value"]) if("power")
if(href_list["command"] == "enable") enabled = !enabled
enabled = value if("lethal")
else if(href_list["command"] == "lethal") if(lethal_is_configurable)
lethal = value lethal = !lethal
else if(href_list["command"] == "check_synth") if(targetting_is_configurable)
check_synth = value switch(action)
else if(href_list["command"] == "check_weapons") if("authweapon")
check_weapons = value check_weapons = !check_weapons
else if(href_list["command"] == "check_records") if("authaccess")
check_records = value check_access = !check_access
else if(href_list["command"] == "check_arrest") if("authnorecord")
check_arrest = value check_records = !check_records
else if(href_list["command"] == "check_access") if("autharrest")
check_access = value check_arrest = !check_arrest
else if(href_list["command"] == "check_anomalies") if("authxeno")
check_anomalies = value check_anomalies = !check_anomalies
else if(href_list["command"] == "check_all") if("authsynth")
check_all = value check_synth = !check_synth
else if(href_list["command"] == "check_down") if("authall")
check_down = value check_all = !check_all
if("authdown")
return 1 check_down = !check_down
/obj/machinery/porta_turret/power_change() /obj/machinery/porta_turret/power_change()
if(powered()) if(powered())
@@ -929,6 +902,7 @@
var/check_weapons var/check_weapons
var/check_anomalies var/check_anomalies
var/check_all var/check_all
var/check_down
var/ailock var/ailock
/obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC) /obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC)
@@ -944,6 +918,7 @@
check_weapons = TC.check_weapons check_weapons = TC.check_weapons
check_anomalies = TC.check_anomalies check_anomalies = TC.check_anomalies
check_all = TC.check_all check_all = TC.check_all
check_down = TC.check_down
ailock = TC.ailock ailock = TC.ailock
power_change() power_change()

View File

@@ -93,6 +93,8 @@
return return
/obj/machinery/recharger/attack_hand(mob/user as mob) /obj/machinery/recharger/attack_hand(mob/user as mob)
if(!Adjacent(user))
return FALSE
add_fingerprint(user) add_fingerprint(user)
if(charging) if(charging)

View File

@@ -104,7 +104,6 @@ var/list/obj/machinery/requests_console/allConsoles = list()
/obj/machinery/requests_console/attack_hand(user as mob) /obj/machinery/requests_console/attack_hand(user as mob)
if(..(user)) if(..(user))
return return
ui_interact(user)
tgui_interact(user) tgui_interact(user)
/obj/machinery/requests_console/tgui_interact(mob/user, datum/tgui/ui) /obj/machinery/requests_console/tgui_interact(mob/user, datum/tgui/ui)

View File

@@ -602,37 +602,37 @@
name = "Engineering suit cycler" name = "Engineering suit cycler"
model_text = "Engineering" model_text = "Engineering"
req_access = list(access_construction) req_access = list(access_construction)
departments = list("Engineering","Atmospherics","HAZMAT","Construction") departments = list("Engineering","Atmospherics","HAZMAT","Construction","No Change")
/obj/machinery/suit_cycler/mining /obj/machinery/suit_cycler/mining
name = "Mining suit cycler" name = "Mining suit cycler"
model_text = "Mining" model_text = "Mining"
req_access = list(access_mining) req_access = list(access_mining)
departments = list("Mining") departments = list("Mining","No Change")
/obj/machinery/suit_cycler/security /obj/machinery/suit_cycler/security
name = "Security suit cycler" name = "Security suit cycler"
model_text = "Security" model_text = "Security"
req_access = list(access_security) req_access = list(access_security)
departments = list("Security","Crowd Control","Security EVA") departments = list("Security","Crowd Control","Security EVA","No Change")
/obj/machinery/suit_cycler/medical /obj/machinery/suit_cycler/medical
name = "Medical suit cycler" name = "Medical suit cycler"
model_text = "Medical" model_text = "Medical"
req_access = list(access_medical) req_access = list(access_medical)
departments = list("Medical","Biohazard","Emergency Medical Response") departments = list("Medical","Biohazard","Emergency Medical Response","No Change")
/obj/machinery/suit_cycler/syndicate /obj/machinery/suit_cycler/syndicate
name = "Nonstandard suit cycler" name = "Nonstandard suit cycler"
model_text = "Nonstandard" model_text = "Nonstandard"
req_access = list(access_syndicate) req_access = list(access_syndicate)
departments = list("Mercenary", "Charring") departments = list("Mercenary", "Charring","No Change")
can_repair = 1 can_repair = 1
/obj/machinery/suit_cycler/exploration /obj/machinery/suit_cycler/exploration
name = "Explorer suit cycler" name = "Explorer suit cycler"
model_text = "Exploration" model_text = "Exploration"
departments = list("Exploration","Old Exploration") departments = list("Exploration","Old Exploration","No Change")
/obj/machinery/suit_cycler/exploration/Initialize() /obj/machinery/suit_cycler/exploration/Initialize()
species -= SPECIES_TESHARI species -= SPECIES_TESHARI
@@ -641,33 +641,33 @@
/obj/machinery/suit_cycler/pilot /obj/machinery/suit_cycler/pilot
name = "Pilot suit cycler" name = "Pilot suit cycler"
model_text = "Pilot" model_text = "Pilot"
departments = list("Pilot Blue","Pilot") departments = list("Pilot Blue","Pilot","No Change")
/obj/machinery/suit_cycler/vintage /obj/machinery/suit_cycler/vintage
name = "Vintage Crew suit cycler" name = "Vintage Crew suit cycler"
model_text = "Vintage" model_text = "Vintage"
departments = list("Vintage Crew") departments = list("Vintage Crew","No Change")
req_access = null req_access = null
/obj/machinery/suit_cycler/vintage/pilot /obj/machinery/suit_cycler/vintage/pilot
name = "Vintage Pilot suit cycler" name = "Vintage Pilot suit cycler"
model_text = "Vintage Pilot" model_text = "Vintage Pilot"
departments = list("Vintage Pilot (Bubble Helm)","Vintage Pilot (Closed Helm)") departments = list("Vintage Pilot (Bubble Helm)","Vintage Pilot (Closed Helm)","No Change")
/obj/machinery/suit_cycler/vintage/medsci /obj/machinery/suit_cycler/vintage/medsci
name = "Vintage MedSci suit cycler" name = "Vintage MedSci suit cycler"
model_text = "Vintage MedSci" model_text = "Vintage MedSci"
departments = list("Vintage Medical (Bubble Helm)","Vintage Medical (Closed Helm)","Vintage Research (Bubble Helm)","Vintage Research (Closed Helm)") departments = list("Vintage Medical (Bubble Helm)","Vintage Medical (Closed Helm)","Vintage Research (Bubble Helm)","Vintage Research (Closed Helm)","No Change")
/obj/machinery/suit_cycler/vintage/rugged /obj/machinery/suit_cycler/vintage/rugged
name = "Vintage Ruggedized suit cycler" name = "Vintage Ruggedized suit cycler"
model_text = "Vintage Ruggedized" model_text = "Vintage Ruggedized"
departments = list("Vintage Engineering","Vintage Marine","Vintage Officer","Vintage Mercenary") departments = list("Vintage Engineering","Vintage Marine","Vintage Officer","Vintage Mercenary","No Change")
/obj/machinery/suit_cycler/vintage/omni /obj/machinery/suit_cycler/vintage/omni
name = "Vintage Master suit cycler" name = "Vintage Master suit cycler"
model_text = "Vintage Master" model_text = "Vintage Master"
departments = list("Vintage Crew","Vintage Engineering","Vintage Pilot (Bubble Helm)","Vintage Pilot (Closed Helm)","Vintage Medical (Bubble Helm)","Vintage Medical (Closed Helm)","Vintage Research (Bubble Helm)","Vintage Research (Closed Helm)","Vintage Marine","Vintage Officer","Vintage Mercenary") departments = list("Vintage Crew","Vintage Engineering","Vintage Pilot (Bubble Helm)","Vintage Pilot (Closed Helm)","Vintage Medical (Bubble Helm)","Vintage Medical (Closed Helm)","Vintage Research (Bubble Helm)","Vintage Research (Closed Helm)","Vintage Marine","Vintage Officer","Vintage Mercenary","No Change")
/obj/machinery/suit_cycler/vintage/Initialize() /obj/machinery/suit_cycler/vintage/Initialize()
species -= SPECIES_TESHARI species -= SPECIES_TESHARI
@@ -1049,17 +1049,9 @@
/obj/machinery/suit_cycler/proc/apply_paintjob() /obj/machinery/suit_cycler/proc/apply_paintjob()
var/obj/item/clothing/head/helmet/parent_helmet var/obj/item/clothing/head/helmet/parent_helmet
var/obj/item/clothing/suit/space/parent_suit var/obj/item/clothing/suit/space/parent_suit
var/turf/T = get_turf(src)
if(!target_species || !target_department) if(!target_species || !target_department)
return return
if(target_species)
if(helmet) helmet.refit_for_species(target_species)
if(suit)
suit.refit_for_species(target_species)
if(suit.helmet)
suit.helmet.refit_for_species(target_species)
//Now "Complete" with most departmental and variant suits, and sorted by department. These aren't available in the standard or emagged cycler lists because they're incomplete for most species. //Now "Complete" with most departmental and variant suits, and sorted by department. These aren't available in the standard or emagged cycler lists because they're incomplete for most species.
switch(target_department) switch(target_department)
if("No Change") if("No Change")
@@ -1217,7 +1209,32 @@
parent_suit = /obj/item/clothing/suit/space/void/refurb/mercenary/talon parent_suit = /obj/item/clothing/suit/space/void/refurb/mercenary/talon
//VOREStation Addition End //VOREStation Addition End
//END: downstream variant space //END: downstream variant space
if(target_species)
//Only run these checks if they have a sprite sheet defined, otherwise they use human's anyways, and there is almost definitely a sprite.
if((helmet!=null&&(target_species in helmet.sprite_sheets_obj))||(suit!=null&&(target_species in suit.sprite_sheets_obj)))
//Making sure all of our items have the sprites to be refitted.
var/helmet_check = ((helmet!=null && (initial(parent_helmet.icon_state) in icon_states(helmet.sprite_sheets_obj[target_species],1))) || helmet==null)
//If the helmet exists, only return true if there's also sprites for it. If the helmet doesn't exist, return true.
var/suit_check = ((suit!=null && (initial(parent_suit.icon_state) in icon_states(suit.sprite_sheets_obj[target_species],1))) || suit==null)
var/suit_helmet_check = ((suit!=null && suit.helmet!=null && (initial(parent_helmet.icon_state) in icon_states(suit.helmet.sprite_sheets_obj[target_species],1))) || suit==null || suit.helmet==null)
if(helmet_check && suit_check && suit_helmet_check)
if(helmet)
helmet.refit_for_species(target_species)
if(suit)
suit.refit_for_species(target_species)
if(suit.helmet)
suit.helmet.refit_for_species(target_species)
else
//If they don't, alert the user and stop here.
T.visible_message("[bicon(src)]<span class='warning'>Unable to apply specified cosmetics with specified species. Please try again with a different species or cosmetic option selected.</span>")
return
else
if(helmet)
helmet.refit_for_species(target_species)
if(suit)
suit.refit_for_species(target_species)
if(suit.helmet)
suit.helmet.refit_for_species(target_species)
//look at this! isn't it beautiful? -KK (well ok not beautiful but it's a lot cleaner) //look at this! isn't it beautiful? -KK (well ok not beautiful but it's a lot cleaner)
if(helmet && target_department != "No Change") if(helmet && target_department != "No Change")
var/obj/item/clothing/H = new parent_helmet var/obj/item/clothing/H = new parent_helmet

View File

@@ -1,11 +1,11 @@
/obj/machinery/suit_cycler /obj/machinery/suit_cycler
departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Emergency Medical Response","Crowd Control","Exploration","Pilot Blue","Pilot","Manager","Prototype") departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Emergency Medical Response","Crowd Control","Exploration","Pilot Blue","Pilot","Manager","Prototype","No Change")
species = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_UNATHI, SPECIES_TAJ, SPECIES_TESHARI, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_VULPKANIN) species = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_UNATHI, SPECIES_TAJ, SPECIES_TESHARI, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_VULPKANIN)
// Old Exploration is too WIP to use right now // Old Exploration is too WIP to use right now
/obj/machinery/suit_cycler/exploration /obj/machinery/suit_cycler/exploration
req_access = list(access_explorer) req_access = list(access_explorer)
departments = list("Exploration") departments = list("Exploration","No Change")
/obj/machinery/suit_cycler/pilot /obj/machinery/suit_cycler/pilot
req_access = list(access_pilot) req_access = list(access_pilot)
@@ -14,7 +14,7 @@
name = "Manager suit cycler" name = "Manager suit cycler"
model_text = "Manager" model_text = "Manager"
req_access = list(access_captain) req_access = list(access_captain)
departments = list("Manager") departments = list("Manager","No Change")
/obj/machinery/suit_cycler/captain/Initialize() //No Teshari Sprites /obj/machinery/suit_cycler/captain/Initialize() //No Teshari Sprites
species -= SPECIES_TESHARI species -= SPECIES_TESHARI
@@ -24,7 +24,7 @@
name = "Prototype suit cycler" name = "Prototype suit cycler"
model_text = "Prototype" model_text = "Prototype"
req_access = list(access_hos) req_access = list(access_hos)
departments = list("Prototype") departments = list("Prototype","No Change")
/obj/machinery/suit_cycler/prototype/Initialize() //No Teshari Sprites /obj/machinery/suit_cycler/prototype/Initialize() //No Teshari Sprites
species -= SPECIES_TESHARI species -= SPECIES_TESHARI
@@ -34,34 +34,34 @@
name = "Talon crew suit cycler" name = "Talon crew suit cycler"
model_text = "Talon crew" model_text = "Talon crew"
req_access = list(access_talon) req_access = list(access_talon)
departments = list("Talon Crew") departments = list("Talon Crew","No Change")
/obj/machinery/suit_cycler/vintage/tpilot /obj/machinery/suit_cycler/vintage/tpilot
name = "Talon pilot suit cycler" name = "Talon pilot suit cycler"
model_text = "Talon pilot" model_text = "Talon pilot"
req_access = list(access_talon) req_access = list(access_talon)
departments = list("Talon Pilot (Bubble Helm)","Talon Pilot (Closed Helm)") departments = list("Talon Pilot (Bubble Helm)","Talon Pilot (Closed Helm)","No Change")
/obj/machinery/suit_cycler/vintage/tengi /obj/machinery/suit_cycler/vintage/tengi
name = "Talon engineer suit cycler" name = "Talon engineer suit cycler"
model_text = "Talon engineer" model_text = "Talon engineer"
req_access = list(access_talon) req_access = list(access_talon)
departments = list("Talon Engineering") departments = list("Talon Engineering","No Change")
/obj/machinery/suit_cycler/vintage/tguard /obj/machinery/suit_cycler/vintage/tguard
name = "Talon guard suit cycler" name = "Talon guard suit cycler"
model_text = "Talon guard" model_text = "Talon guard"
req_access = list(access_talon) req_access = list(access_talon)
departments = list("Talon Marine","Talon Mercenary") departments = list("Talon Marine","Talon Mercenary","No Change")
/obj/machinery/suit_cycler/vintage/tmedic /obj/machinery/suit_cycler/vintage/tmedic
name = "Talon doctor suit cycler" name = "Talon doctor suit cycler"
model_text = "Talon doctor" model_text = "Talon doctor"
req_access = list(access_talon) req_access = list(access_talon)
departments = list("Talon Medical (Bubble Helm)","Talon Medical (Closed Helm)") departments = list("Talon Medical (Bubble Helm)","Talon Medical (Closed Helm)","No Change")
/obj/machinery/suit_cycler/vintage/tcaptain /obj/machinery/suit_cycler/vintage/tcaptain
name = "Talon captain suit cycler" name = "Talon captain suit cycler"
model_text = "Talon captain" model_text = "Talon captain"
req_access = list(access_talon) req_access = list(access_talon)
departments = list("Talon Officer") departments = list("Talon Officer","No Change")

View File

@@ -11,7 +11,7 @@
var/id = null var/id = null
var/one_time_use = 0 //Used for one-time-use teleport cards (such as clown planet coordinates.) var/one_time_use = 0 //Used for one-time-use teleport cards (such as clown planet coordinates.)
//Setting this to 1 will set locked to null after a player enters the portal and will not allow hand-teles to open portals to that location. //Setting this to 1 will set locked to null after a player enters the portal and will not allow hand-teles to open portals to that location.
var/datum/nano_module/program/teleport_control/teleport_control var/datum/tgui_module/teleport_control/teleport_control
/obj/machinery/computer/teleporter/New() /obj/machinery/computer/teleporter/New()
id = "[rand(1000, 9999)]" id = "[rand(1000, 9999)]"
@@ -44,7 +44,7 @@
teleport_control.station = station teleport_control.station = station
/obj/machinery/computer/teleporter/Destroy() /obj/machinery/computer/teleporter/Destroy()
qdel_null(teleport_control) QDEL_NULL(teleport_control)
return ..() return ..()
/obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob) /obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob)
@@ -96,108 +96,13 @@
attack_hand() attack_hand()
/obj/machinery/computer/teleporter/attack_ai(mob/user) /obj/machinery/computer/teleporter/attack_ai(mob/user)
ui_interact(user) teleport_control.tgui_interact(user)
/obj/machinery/computer/teleporter/attack_hand(mob/user) /obj/machinery/computer/teleporter/attack_hand(mob/user)
add_fingerprint(user) add_fingerprint(user)
if(stat & (BROKEN|NOPOWER)) if(stat & (BROKEN|NOPOWER))
return return
ui_interact(user) teleport_control.tgui_interact(user)
/obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
teleport_control.ui_interact(user, ui_key, ui, force_open)
/obj/machinery/computer/teleporter/interact(mob/user)
teleport_control.ui_interact(user)
//////
////// Nano-module for teleporter
//////
/datum/nano_module/program/teleport_control
name = "Teleporter Control"
var/locked_name = "Not Locked"
var/obj/item/locked = null
var/obj/machinery/teleport/station/station = null
var/obj/machinery/teleport/hub/hub = null
/datum/nano_module/program/teleport_control/Topic(href, href_list)
if(..()) return 1
if(href_list["select_target"])
var/list/L = list()
var/list/areaindex = list()
for(var/obj/item/device/radio/beacon/R in all_beacons)
var/turf/T = get_turf(R)
if(!T)
continue
if(!(T.z in using_map.player_levels))
continue
var/tmpname = T.loc.name
if(areaindex[tmpname])
tmpname = "[tmpname] ([++areaindex[tmpname]])"
else
areaindex[tmpname] = 1
L[tmpname] = R
for (var/obj/item/weapon/implant/tracking/I in all_tracking_implants)
if(!I.implanted || !ismob(I.loc))
continue
else
var/mob/M = I.loc
if(M.stat == 2)
if(M.timeofdeath + 6000 < world.time)
continue
var/turf/T = get_turf(M)
if(T) continue
if(T.z == 2) continue
var/tmpname = M.real_name
if(areaindex[tmpname])
tmpname = "[tmpname] ([++areaindex[tmpname]])"
else
areaindex[tmpname] = 1
L[tmpname] = I
var/desc = input("Please select a location to lock in.", "Locking Menu") in L|null
if(!desc)
return 0
if(get_dist(host, usr) > 1 && !issilicon(usr))
return 0
locked = L[desc]
locked_name = desc
return 1
if(href_list["test_fire"])
station?.testfire()
return 1
if(href_list["toggle_on"])
if(!station)
return 0
if(station.engaged)
station.disengage()
else
station.engage()
return 1
/datum/nano_module/program/teleport_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
data["locked_name"] = locked_name ? locked_name : "No Target"
data["station_connected"] = station ? 1 : 0
data["hub_connected"] = hub ? 1 : 0
data["calibrated"] = hub ? hub.accurate : 0
data["teleporter_on"] = station ? station.engaged : 0
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "teleport_control.tmpl", "Teleport Control Console", 400, 500, state = state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/teleporter/verb/set_id(t as text) /obj/machinery/computer/teleporter/verb/set_id(t as text)
set category = "Object" set category = "Object"
@@ -211,14 +116,6 @@
id = t id = t
return return
/proc/find_loc(obj/R as obj)
if(!R) return null
var/turf/T = R.loc
while(!istype(T, /turf))
T = T.loc
if(!T || istype(T, /area)) return null
return T
////// //////
////// Root of all the machinery ////// Root of all the machinery
////// //////

View File

@@ -11,31 +11,35 @@
desc = "Used to control a room's automated defenses." desc = "Used to control a room's automated defenses."
icon = 'icons/obj/machines/turret_control.dmi' icon = 'icons/obj/machines/turret_control.dmi'
icon_state = "control_standby" icon_state = "control_standby"
anchored = 1 anchored = TRUE
density = 0 density = FALSE
var/enabled = 0 var/enabled = FALSE
var/lethal = 0 var/lethal = FALSE
var/locked = 1 var/lethal_is_configurable = TRUE
var/locked = TRUE
var/area/control_area //can be area name, path or nothing. var/area/control_area //can be area name, path or nothing.
var/check_arrest = 1 //checks if the perp is set to arrest var/targetting_is_configurable = TRUE // if false, you cannot change who this turret attacks via its UI
var/check_records = 1 //checks if a security record exists at all var/check_arrest = TRUE //checks if the perp is set to arrest
var/check_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have var/check_records = TRUE //checks if a security record exists at all
var/check_access = 1 //if this is active, the turret shoots everything that does not meet the access requirements var/check_weapons = FALSE //checks if it can shoot people that have a weapon they aren't authorized to have
var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos) var/check_access = TRUE //if this is active, the turret shoots everything that does not meet the access requirements
var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg var/check_anomalies = TRUE //checks if it can shoot at unidentified lifeforms (ie xenos)
var/check_all = 0 //If active, will shoot at anything. var/check_synth = FALSE //if active, will shoot at anything not an AI or cyborg
var/ailock = 0 //Silicons cannot use this var/check_all = FALSE //If active, will shoot at anything.
var/check_down = TRUE //If active, won't shoot laying targets.
var/ailock = FALSE //Silicons cannot use this
var/syndicate = FALSE
req_access = list(access_ai_upload) req_access = list(access_ai_upload)
/obj/machinery/turretid/stun /obj/machinery/turretid/stun
enabled = 1 enabled = TRUE
icon_state = "control_stun" icon_state = "control_stun"
/obj/machinery/turretid/lethal /obj/machinery/turretid/lethal
enabled = 1 enabled = TRUE
lethal = 1 lethal = TRUE
icon_state = "control_kill" icon_state = "control_kill"
/obj/machinery/turretid/Destroy() /obj/machinery/turretid/Destroy()
@@ -67,21 +71,24 @@
. = ..() . = ..()
/obj/machinery/turretid/proc/isLocked(mob/user) /obj/machinery/turretid/proc/isLocked(mob/user)
if(ailock && issilicon(user)) if(isrobot(user) || isAI(user))
to_chat(user, "<span class='notice'>There seems to be a firewall preventing you from accessing this device.</span>") if(ailock)
return 1 to_chat(user, "<span class='notice'>There seems to be a firewall preventing you from accessing this device.</span>")
return TRUE
else
return FALSE
if(locked && !issilicon(user)) if(isobserver(user))
to_chat(user, "<span class='notice'>Access denied.</span>") var/mob/observer/dead/D = user
return 1 if(D.can_admin_interact())
return FALSE
else
return TRUE
return 0 if(locked)
return TRUE
/obj/machinery/turretid/CanUseTopic(mob/user) return FALSE
if(isLocked(user))
return STATUS_CLOSE
return ..()
/obj/machinery/turretid/attackby(obj/item/weapon/W, mob/user) /obj/machinery/turretid/attackby(obj/item/weapon/W, mob/user)
if(stat & BROKEN) if(stat & BROKEN)
@@ -100,77 +107,80 @@
/obj/machinery/turretid/emag_act(var/remaining_charges, var/mob/user) /obj/machinery/turretid/emag_act(var/remaining_charges, var/mob/user)
if(!emagged) if(!emagged)
to_chat(user, "<span class='danger'>You short out the turret controls' access analysis module.</span>") to_chat(user, "<span class='danger'>You short out the turret controls' access analysis module.</span>")
emagged = 1 emagged = TRUE
locked = 0 locked = FALSE
ailock = 0 ailock = FALSE
return 1 return TRUE
/obj/machinery/turretid/attack_ai(mob/user as mob) /obj/machinery/turretid/attack_ai(mob/user as mob)
if(isLocked(user)) tgui_interact(user)
return
ui_interact(user) /obj/machinery/turretid/attack_ghost(mob/user as mob)
tgui_interact(user)
/obj/machinery/turretid/attack_hand(mob/user as mob) /obj/machinery/turretid/attack_hand(mob/user as mob)
if(isLocked(user)) tgui_interact(user)
/obj/machinery/turretid/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PortableTurret", name) // 500, 400
ui.open()
/obj/machinery/turretid/tgui_data(mob/user)
var/list/data = list(
"locked" = isLocked(user), // does the current user have access?
"on" = enabled,
"targetting_is_configurable" = targetting_is_configurable,
"lethal" = lethal,
"lethal_is_configurable" = lethal_is_configurable,
"check_weapons" = check_weapons,
"neutralize_noaccess" = check_access,
"one_access" = FALSE,
"selectedAccess" = list(),
"access_is_configurable" = FALSE,
"neutralize_norecord" = check_records,
"neutralize_criminals" = check_arrest,
"neutralize_nonsynth" = check_synth,
"neutralize_all" = check_all,
"neutralize_unidentified" = check_anomalies,
"neutralize_down" = check_down,
)
return data
/obj/machinery/turretid/tgui_act(action, params)
if(..())
return
if(isLocked(usr))
return return
ui_interact(user) . = TRUE
switch(action)
if("power")
enabled = !enabled
if("lethal")
if(lethal_is_configurable)
lethal = !lethal
if(targetting_is_configurable)
switch(action)
if("authweapon")
check_weapons = !check_weapons
if("authaccess")
check_access = !check_access
if("authnorecord")
check_records = !check_records
if("autharrest")
check_arrest = !check_arrest
if("authxeno")
check_anomalies = !check_anomalies
if("authsynth")
check_synth = !check_synth
if("authall")
check_all = !check_all
if("authdown")
check_down = !check_down
/obj/machinery/turretid/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) updateTurrets()
var/data[0]
data["access"] = !isLocked(user)
data["locked"] = locked
data["enabled"] = enabled
data["is_lethal"] = 1
data["lethal"] = lethal
if(data["access"])
var/settings[0]
settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth)
settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons)
settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records)
settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest)
settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access)
settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies)
settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all)
data["settings"] = settings
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/turretid/Topic(href, href_list)
if(..())
return 1
if(href_list["command"] && href_list["value"])
var/value = text2num(href_list["value"])
if(href_list["command"] == "enable")
enabled = value
else if(href_list["command"] == "lethal")
lethal = value
else if(href_list["command"] == "check_synth")
check_synth = value
else if(href_list["command"] == "check_weapons")
check_weapons = value
else if(href_list["command"] == "check_records")
check_records = value
else if(href_list["command"] == "check_arrest")
check_arrest = value
else if(href_list["command"] == "check_access")
check_access = value
else if(href_list["command"] == "check_anomalies")
check_anomalies = value
else if(href_list["command"] == "check_all")
check_all = value
updateTurrets()
return 1
/obj/machinery/turretid/proc/updateTurrets() /obj/machinery/turretid/proc/updateTurrets()
var/datum/turret_checks/TC = new var/datum/turret_checks/TC = new
@@ -183,10 +193,11 @@
TC.check_weapons = check_weapons TC.check_weapons = check_weapons
TC.check_anomalies = check_anomalies TC.check_anomalies = check_anomalies
TC.check_all = check_all TC.check_all = check_all
TC.check_down = check_down
TC.ailock = ailock TC.ailock = ailock
if(istype(control_area)) if(istype(control_area))
for (var/obj/machinery/porta_turret/aTurret in control_area) for(var/obj/machinery/porta_turret/aTurret in control_area)
aTurret.setState(TC) aTurret.setState(TC)
update_icon() update_icon()

View File

@@ -144,6 +144,6 @@
if(!istype(user)) if(!istype(user))
return return
if(CanInteract(user, physical_state)) if(CanInteract(user, GLOB.tgui_physical_state))
beep = !beep beep = !beep
to_chat(user, "<span class='notice'>You turn the sound on \the [src] [beep ? "on" : "off"].</span>") to_chat(user, "<span class='notice'>You turn the sound on \the [src] [beep ? "on" : "off"].</span>")

View File

@@ -17,6 +17,8 @@
max_special_equip = 1 max_special_equip = 1
cargo_capacity = 1 cargo_capacity = 1
encumbrance_gap = 1.5
starting_components = list( starting_components = list(
/obj/item/mecha_parts/component/hull/durable, /obj/item/mecha_parts/component/hull/durable,
/obj/item/mecha_parts/component/actuator, /obj/item/mecha_parts/component/actuator,

View File

@@ -25,6 +25,8 @@
max_universal_equip = 3 max_universal_equip = 3
max_special_equip = 4 max_special_equip = 4
encumbrance_gap = 2
starting_components = list( starting_components = list(
/obj/item/mecha_parts/component/hull/durable, /obj/item/mecha_parts/component/hull/durable,
/obj/item/mecha_parts/component/actuator, /obj/item/mecha_parts/component/actuator,

View File

@@ -49,11 +49,34 @@
for(var/obj/item/weapon/ore/ore in range(chassis,1)) for(var/obj/item/weapon/ore/ore in range(chassis,1))
if(get_dir(chassis,ore)&chassis.dir) if(get_dir(chassis,ore)&chassis.dir)
ore.forceMove(ore_box) ore.forceMove(ore_box)
else if(isliving(target))
drill_mob(target, chassis.occupant)
return 1
else if(target.loc == C) else if(target.loc == C)
log_message("Drilled through [target]") log_message("Drilled through [target]")
target.ex_act(2) target.ex_act(2)
return 1 return 1
/obj/item/mecha_parts/mecha_equipment/tool/drill/proc/drill_mob(mob/living/target, mob/user)
add_attack_logs(user, target, "attacked", "[name]", "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
var/drill_force = force //Couldn't manage it otherwise.
if(ishuman(target))
target.apply_damage(drill_force, BRUTE)
return
else if(istype(target, /mob/living/simple_mob))
var/mob/living/simple_mob/S = target
if(target.stat == DEAD)
if(S.meat_amount > 0)
S.harvest(user)
return
else
S.gib()
return
else
S.apply_damage(drill_force)
return
/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill /obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill
name = "diamond drill" name = "diamond drill"
desc = "This is an upgraded version of the drill that'll pierce the heavens!" desc = "This is an upgraded version of the drill that'll pierce the heavens!"

View File

@@ -31,7 +31,10 @@
var/initial_icon = null //Mech type for resetting icon. Only used for reskinning kits (see custom items) var/initial_icon = null //Mech type for resetting icon. Only used for reskinning kits (see custom items)
var/can_move = 1 var/can_move = 1
var/mob/living/carbon/occupant = null var/mob/living/carbon/occupant = null
var/step_in = 10 //Make a step in step_in/10 sec. var/step_in = 10 //Make a step in step_in/10 sec.
var/encumbrance_gap = 1 //How many points of slowdown are negated from equipment? Added to the mech's base step_in.
var/dir_in = 2 //What direction will the mech face when entered/powered on? Defaults to South. var/dir_in = 2 //What direction will the mech face when entered/powered on? Defaults to South.
var/step_energy_drain = 10 var/step_energy_drain = 10
var/health = 300 //Health is health var/health = 300 //Health is health
@@ -193,6 +196,7 @@
var/datum/action/innate/mecha/mech_toggle_cloaking/cloak_action = new var/datum/action/innate/mecha/mech_toggle_cloaking/cloak_action = new
var/weapons_only_cycle = FALSE //So combat mechs don't switch to their equipment at times. var/weapons_only_cycle = FALSE //So combat mechs don't switch to their equipment at times.
/obj/mecha/Initialize() /obj/mecha/Initialize()
..() ..()
@@ -559,12 +563,12 @@
target.attack_hand(src.occupant) target.attack_hand(src.occupant)
return 1 return 1
if(istype(target, /obj/machinery/embedded_controller)) if(istype(target, /obj/machinery/embedded_controller))
target.ui_interact(src.occupant) target.tgui_interact(src.occupant)
return 1 return 1
return 0 return 0
/obj/mecha/contents_nano_distance(var/src_object, var/mob/living/user) /obj/mecha/contents_tgui_distance(var/src_object, var/mob/living/user)
. = user.shared_living_nano_distance(src_object) //allow them to interact with anything they can interact with normally. . = user.shared_living_tgui_distance(src_object) //allow them to interact with anything they can interact with normally.
if(. != STATUS_INTERACTIVE) if(. != STATUS_INTERACTIVE)
//Allow interaction with the mecha or anything that is part of the mecha //Allow interaction with the mecha or anything that is part of the mecha
if(src_object == src || (src_object in src)) if(src_object == src || (src_object in src))
@@ -641,18 +645,21 @@
/obj/mecha/proc/get_step_delay() /obj/mecha/proc/get_step_delay()
var/tally = 0 var/tally = 0
if(overload) if(LAZYLEN(equipment))
tally = min(1, round(step_in/2)) for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
if(ME.get_step_delay())
tally += ME.get_step_delay()
if(tally <= encumbrance_gap) // If the total is less than our encumbrance gap, ignore equipment weight.
tally = 0
else // Otherwise, start the tally after cutting that gap out.
tally -= encumbrance_gap
for(var/slot in internal_components) for(var/slot in internal_components)
var/obj/item/mecha_parts/component/C = internal_components[slot] var/obj/item/mecha_parts/component/C = internal_components[slot]
if(C && C.get_step_delay()) if(C && C.get_step_delay())
tally += C.get_step_delay() tally += C.get_step_delay()
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
if(ME.get_step_delay())
tally += ME.get_step_delay()
var/obj/item/mecha_parts/component/actuator/actuator = internal_components[MECH_ACTUATOR] var/obj/item/mecha_parts/component/actuator/actuator = internal_components[MECH_ACTUATOR]
if(!actuator) // Relying purely on hydraulic pumps. You're going nowhere fast. if(!actuator) // Relying purely on hydraulic pumps. You're going nowhere fast.
@@ -674,7 +681,10 @@
break break
break break
return max(1, round(tally, 0.1)) if(overload) // At the end, because this would normally just make the mech *slower* since tally wasn't starting at 0.
tally = min(1, round(tally/2))
return max(1, round(tally, 0.1)) // Round the total to the nearest 10th. Can't go lower than 1 tick. Even humans have a delay longer than that.
/obj/mecha/proc/dyndomove(direction) /obj/mecha/proc/dyndomove(direction)
if(!can_move) if(!can_move)

View File

@@ -14,6 +14,8 @@
minimum_penetration = 10 minimum_penetration = 10
encumbrance_gap = 2
starting_components = list( starting_components = list(
/obj/item/mecha_parts/component/hull/durable, /obj/item/mecha_parts/component/hull/durable,
/obj/item/mecha_parts/component/actuator, /obj/item/mecha_parts/component/actuator,

View File

@@ -91,16 +91,16 @@
var/icon/default_worn_icon //Default on-mob icon var/icon/default_worn_icon //Default on-mob icon
var/worn_layer //Default on-mob layer var/worn_layer //Default on-mob layer
// Pickup/Drop/Equip/Throw Sounds // Pickup/Drop/Equip/Throw Sounds
///Used when thrown into a mob ///Used when thrown into a mob
var/mob_throw_hit_sound var/mob_throw_hit_sound
// Sound used when equipping the items into a valid slot. // Sound used when equipping the items into a valid slot.
var/equip_sound var/equip_sound
// pickup sound - this is the default // pickup sound - this is the default
var/pickup_sound = 'sound/items/pickup/device.ogg' var/pickup_sound = "generic_pickup"
// drop sound - this is the default // drop sound - this is the default
var/drop_sound = 'sound/items/drop/device.ogg' var/drop_sound = "generic_drop"
var/tip_timer // reference to timer id for a tooltip we might open soon var/tip_timer // reference to timer id for a tooltip we might open soon
@@ -468,12 +468,12 @@ var/list/global/slot_flags_enumeration = list(
if(!canremove) if(!canremove)
return 0 return 0
if(!slot) if(!slot)
if(issilicon(M)) if(issilicon(M))
return 1 // for stuff in grippers return 1 // for stuff in grippers
return 0 return 0
if(!M.slot_is_accessible(slot, src, disable_warning? null : M)) if(!M.slot_is_accessible(slot, src, disable_warning? null : M))
return 0 return 0
return 1 return 1
@@ -785,6 +785,8 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
// My best guess as to why this is here would be that it does so little. Still, keep it under all the procs, for sanity's sake. // My best guess as to why this is here would be that it does so little. Still, keep it under all the procs, for sanity's sake.
/obj/item/device /obj/item/device
icon = 'icons/obj/device.dmi' icon = 'icons/obj/device.dmi'
pickup_sound = 'sound/items/pickup/device.ogg'
drop_sound = 'sound/items/drop/device.ogg'
//Worn icon generation for on-mob sprites //Worn icon generation for on-mob sprites
/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer,var/icon/clip_mask = null) //VOREStation edit - add 'clip mask' argument. /obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer,var/icon/clip_mask = null) //VOREStation edit - add 'clip mask' argument.

File diff suppressed because it is too large Load Diff

View File

@@ -1,630 +0,0 @@
var/list/command_cartridges = list(
/obj/item/weapon/cartridge/captain,
/obj/item/weapon/cartridge/hop,
/obj/item/weapon/cartridge/hos,
/obj/item/weapon/cartridge/ce,
/obj/item/weapon/cartridge/rd,
/obj/item/weapon/cartridge/cmo,
/obj/item/weapon/cartridge/head,
/obj/item/weapon/cartridge/lawyer // Internal Affaris,
)
var/list/security_cartridges = list(
/obj/item/weapon/cartridge/security,
/obj/item/weapon/cartridge/detective,
/obj/item/weapon/cartridge/hos
)
var/list/engineering_cartridges = list(
/obj/item/weapon/cartridge/engineering,
/obj/item/weapon/cartridge/atmos,
/obj/item/weapon/cartridge/ce
)
var/list/medical_cartridges = list(
/obj/item/weapon/cartridge/medical,
/obj/item/weapon/cartridge/chemistry,
/obj/item/weapon/cartridge/cmo
)
var/list/research_cartridges = list(
/obj/item/weapon/cartridge/signal/science,
/obj/item/weapon/cartridge/rd
)
var/list/cargo_cartridges = list(
/obj/item/weapon/cartridge/quartermaster, // This also covers cargo-techs, apparently,
/obj/item/weapon/cartridge/miner,
/obj/item/weapon/cartridge/hop
)
var/list/civilian_cartridges = list(
/obj/item/weapon/cartridge/janitor,
/obj/item/weapon/cartridge/service,
/obj/item/weapon/cartridge/hop
)
/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 = ITEMSIZE_TINY
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
var/obj/item/radio/integrated/radio = null
var/access_security = 0
var/access_engine = 0
var/access_atmos = 0
var/access_medical = 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_detonate_pda = 0
var/access_hydroponics = 0
var/charges = 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/selected_sensor = null // Power Sensor
var/message1 // used for status_displays
var/message2
var/list/stored_data = list()
/obj/item/weapon/cartridge/Destroy()
QDEL_NULL(radio)
return ..()
/obj/item/weapon/cartridge/engineering
name = "\improper Power-ON cartridge"
icon_state = "cart-e"
access_engine = 1
/obj/item/weapon/cartridge/atmos
name = "\improper BreatheDeep cartridge"
icon_state = "cart-a"
access_atmos = 1
/obj/item/weapon/cartridge/medical
name = "\improper Med-U cartridge"
icon_state = "cart-m"
access_medical = 1
/obj/item/weapon/cartridge/chemistry
name = "\improper ChemWhiz cartridge"
icon_state = "cart-chem"
access_reagent_scanner = 1
access_medical = 1
/obj/item/weapon/cartridge/security
name = "\improper R.O.B.U.S.T. cartridge"
icon_state = "cart-s"
access_security = 1
/obj/item/weapon/cartridge/security/Initialize()
radio = new /obj/item/radio/integrated/beepsky(src)
. = ..()
/obj/item/weapon/cartridge/detective
name = "\improper D.E.T.E.C.T. cartridge"
icon_state = "cart-s"
access_security = 1
access_medical = 1
/obj/item/weapon/cartridge/janitor
name = "\improper CustodiPRO cartridge"
desc = "The ultimate in clean-room design."
icon_state = "cart-j"
access_janitor = 1
/obj/item/weapon/cartridge/lawyer
name = "\improper P.R.O.V.E. cartridge"
icon_state = "cart-s"
access_security = 1
/obj/item/weapon/cartridge/clown
name = "\improper Honkworks 5.0 cartridge"
icon_state = "cart-clown"
access_clown = 1
charges = 5
/obj/item/weapon/cartridge/mime
name = "\improper Gestur-O 1000 cartridge"
icon_state = "cart-mi"
access_mime = 1
charges = 5
/*
/obj/item/weapon/cartridge/botanist
name = "Green Thumb v4.20"
icon_state = "cart-b"
access_flora = 1
*/
/obj/item/weapon/cartridge/service
name = "\improper Serv-U Pro cartridge"
desc = "A data cartridge designed to serve YOU!"
/obj/item/weapon/cartridge/signal
name = "generic signaler cartridge"
desc = "A data cartridge with an integrated radio signaler module."
var/qdeled = 0
/obj/item/weapon/cartridge/signal/science
name = "\improper Signal Ace 2 cartridge"
desc = "Complete with integrated radio signaler!"
icon_state = "cart-tox"
access_reagent_scanner = 1
access_atmos = 1
/obj/item/weapon/cartridge/signal/Initialize()
radio = new /obj/item/radio/integrated/signal(src)
. = ..()
/obj/item/weapon/cartridge/quartermaster
name = "\improper Space Parts & Space Vendors cartridge"
desc = "Perfect for the Quartermaster on the go!"
icon_state = "cart-q"
access_quartermaster = 1
/obj/item/weapon/cartridge/miner
name = "\improper Drill-Jockey 4.5 cartridge"
desc = "It's covered in some sort of sand."
icon_state = "cart-q"
/obj/item/weapon/cartridge/head
name = "\improper Easy-Record DELUXE cartridge"
icon_state = "cart-h"
access_status_display = 1
/obj/item/weapon/cartridge/hop
name = "\improper HumanResources9001 cartridge"
icon_state = "cart-h"
access_status_display = 1
access_quartermaster = 1
access_janitor = 1
access_security = 1
/obj/item/weapon/cartridge/hos
name = "\improper R.O.B.U.S.T. DELUXE cartridge"
icon_state = "cart-hos"
access_status_display = 1
access_security = 1
/obj/item/weapon/cartridge/hos/Initialize()
radio = new /obj/item/radio/integrated/beepsky(src)
. = ..()
/obj/item/weapon/cartridge/ce
name = "\improper Power-On DELUXE cartridge"
icon_state = "cart-ce"
access_status_display = 1
access_engine = 1
access_atmos = 1
/obj/item/weapon/cartridge/cmo
name = "\improper Med-U DELUXE cartridge"
icon_state = "cart-cmo"
access_status_display = 1
access_reagent_scanner = 1
access_medical = 1
/obj/item/weapon/cartridge/rd
name = "\improper Signal Ace DELUXE cartridge"
icon_state = "cart-rd"
access_status_display = 1
access_reagent_scanner = 1
access_atmos = 1
/obj/item/weapon/cartridge/rd/Initialize()
radio = new /obj/item/radio/integrated/signal(src)
. = ..()
/obj/item/weapon/cartridge/captain
name = "\improper Value-PAK cartridge"
desc = "Now with 200% more value!"
icon_state = "cart-c"
access_quartermaster = 1
access_janitor = 1
access_engine = 1
access_security = 1
access_medical = 1
access_reagent_scanner = 1
access_status_display = 1
access_atmos = 1
/obj/item/weapon/cartridge/syndicate
name = "\improper Detomatix cartridge"
icon_state = "cart"
access_remote_door = 1
access_detonate_pda = 1
remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing.
charges = 4
/obj/item/weapon/cartridge/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 = TRANSMISSION_RADIO
status_signal.data["command"] = command
switch(command)
if("message")
status_signal.data["msg1"] = data1
status_signal.data["msg2"] = data2
if(loc)
var/obj/item/PDA = loc
var/mob/user = PDA.fingerprintslast
log_admin("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]")
message_admins("STATUS: [user] set status screen with [PDA]. Message: [data1] [data2]")
if("alert")
status_signal.data["picture_state"] = data1
frequency.post_signal(src, status_signal)
/*
This generates the nano values of the cart menus.
Because we close the UI when we insert a new cart
we don't have to worry about null values on items
the user can't access. Well, unless they are href hacking.
But in that case their UI will just lock up.
*/
/obj/item/weapon/cartridge/proc/create_NanoUI_values(mob/user as mob)
var/values[0]
/* Signaler (Mode: 40) */
if(istype(radio,/obj/item/radio/integrated/signal) && (mode==40))
var/obj/item/radio/integrated/signal/R = radio
values["signal_freq"] = format_frequency(R.frequency)
values["signal_code"] = R.code
/* Station Display (Mode: 42) */
if(mode==42)
values["message1"] = message1 ? message1 : "(none)"
values["message2"] = message2 ? message2 : "(none)"
/* Power Monitor (Mode: 43 / 433) */
if(mode==43 || mode==433)
var/list/sensors = list()
var/obj/machinery/power/sensor/MS = null
var/my_z = get_z(user)
var/list/levels = using_map.get_map_levels(my_z)
for(var/obj/machinery/power/sensor/S in machines)
if(!(get_z(S) in levels))
continue
sensors.Add(list(list("name_tag" = S.name_tag)))
if(S.name_tag == selected_sensor)
MS = S
values["power_sensors"] = sensors
if(selected_sensor && MS)
values["sensor_reading"] = MS.return_reading_data()
/* General Records (Mode: 44 / 441 / 45 / 451) */
if(mode == 44 || mode == 441 || mode == 45 || mode ==451)
if(istype(active1, /datum/data/record) && (active1 in data_core.general))
values["general"] = active1.fields
values["general_exists"] = 1
else
values["general_exists"] = 0
/* Medical Records (Mode: 44 / 441) */
if(mode == 44 || mode == 441)
var/medData[0]
for(var/datum/data/record/R in sortRecord(data_core.general))
medData[++medData.len] = list(Name = R.fields["name"],"ref" = "\ref[R]")
values["medical_records"] = medData
if(istype(active2, /datum/data/record) && (active2 in data_core.medical))
values["medical"] = active2.fields
values["medical_exists"] = 1
else
values["medical_exists"] = 0
/* Security Records (Mode:45 / 451) */
if(mode == 45 || mode == 451)
var/secData[0]
for (var/datum/data/record/R in sortRecord(data_core.general))
secData[++secData.len] = list(Name = R.fields["name"], "ref" = "\ref[R]")
values["security_records"] = secData
if(istype(active3, /datum/data/record) && (active3 in data_core.security))
values["security"] = active3.fields
values["security_exists"] = 1
else
values["security_exists"] = 0
/* Security Bot Control (Mode: 46) */
if(mode==46)
var/botsData[0]
var/beepskyData[0]
if(istype(radio,/obj/item/radio/integrated/beepsky))
var/obj/item/radio/integrated/beepsky/SC = radio
beepskyData["active"] = SC.active
if(SC.active && !isnull(SC.botstatus))
var/area/loca = SC.botstatus["loca"]
var/loca_name = sanitize(loca.name)
beepskyData["botstatus"] = list("loca" = loca_name, "mode" = SC.botstatus["mode"])
else
beepskyData["botstatus"] = list("loca" = null, "mode" = -1)
var/botsCount=0
if(SC.botlist && SC.botlist.len)
for(var/mob/living/bot/B in SC.botlist)
botsCount++
if(B.loc)
botsData[++botsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "ref" = "\ref[B]")
if(!botsData.len)
botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
beepskyData["bots"] = botsData
beepskyData["count"] = botsCount
else
beepskyData["active"] = 0
botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "ref"= null)
beepskyData["botstatus"] = list("loca" = null, "mode" = null)
beepskyData["bots"] = botsData
beepskyData["count"] = 0
values["beepsky"] = beepskyData
/* MULEBOT Control (Mode: 48) */
if(mode==48)
var/mulebotsData[0]
var/count = 0
for(var/mob/living/bot/mulebot/M in living_mob_list)
if(!M.on)
continue
++count
var/muleData[0]
muleData["name"] = M.suffix
muleData["location"] = get_area(M)
muleData["paused"] = M.paused
muleData["home"] = M.homeName
muleData["target"] = M.targetName
muleData["ref"] = "\ref[M]"
muleData["load"] = M.load ? M.load.name : "Nothing"
mulebotsData[++mulebotsData.len] = muleData.Copy()
values["mulebotcount"] = count
values["mulebots"] = mulebotsData
/* Supply Shuttle Requests Menu (Mode: 47) */
if(mode==47)
var/supplyData[0]
var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle
if (shuttle)
supplyData["shuttle_moving"] = shuttle.has_arrive_time()
supplyData["shuttle_eta"] = shuttle.eta_minutes()
supplyData["shuttle_loc"] = shuttle.at_station() ? "Station" : "Dock"
var/supplyOrderCount = 0
var/supplyOrderData[0]
for(var/S in SSsupply.shoppinglist)
var/datum/supply_order/SO = S
supplyOrderData[++supplyOrderData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "ApprovedBy" = SO.ordered_by, "Comment" = html_encode(SO.comment))
if(!supplyOrderData.len)
supplyOrderData[++supplyOrderData.len] = list("Number" = null, "Name" = null, "OrderedBy"=null)
supplyData["approved"] = supplyOrderData
supplyData["approved_count"] = supplyOrderCount
var/requestCount = 0
var/requestData[0]
for(var/S in SSsupply.order_history)
var/datum/supply_order/SO = S
if(SO.status != SUP_ORDER_REQUESTED)
continue
requestCount++
requestData[++requestData.len] = list("Number" = SO.ordernum, "Name" = html_encode(SO.object.name), "OrderedBy" = SO.ordered_by, "Comment" = html_encode(SO.comment))
if(!requestData.len)
requestData[++requestData.len] = list("Number" = null, "Name" = null, "orderedBy" = null, "Comment" = null)
supplyData["requests"] = requestData
supplyData["requests_count"] = requestCount
values["supply"] = supplyData
/* Janitor Supplies Locator (Mode: 49) */
if(mode==49)
var/JaniData[0]
var/turf/cl = get_turf(src)
if(cl)
JaniData["user_loc"] = list("x" = cl.x, "y" = cl.y)
else
JaniData["user_loc"] = list("x" = 0, "y" = 0)
var/MopData[0]
for(var/obj/item/weapon/mop/M in all_mops)
var/turf/ml = get_turf(M)
if(ml)
if(ml.z != cl.z)
continue
var/direction = get_dir(src, M)
MopData[++MopData.len] = list ("x" = ml.x, "y" = ml.y, "dir" = uppertext(dir2text(direction)), "status" = M.reagents.total_volume ? "Wet" : "Dry")
if(!MopData.len)
MopData[++MopData.len] = list("x" = 0, "y" = 0, dir=null, status = null)
var/BucketData[0]
for(var/obj/structure/mopbucket/B in all_mopbuckets)
var/turf/bl = get_turf(B)
if(bl)
if(bl.z != cl.z)
continue
var/direction = get_dir(src,B)
BucketData[++BucketData.len] = list ("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100)
if(!BucketData.len)
BucketData[++BucketData.len] = list("x" = 0, "y" = 0, dir=null, status = null)
var/CbotData[0]
for(var/mob/living/bot/cleanbot/B in mob_list)
var/turf/bl = get_turf(B)
if(bl)
if(bl.z != cl.z)
continue
var/direction = get_dir(src,B)
CbotData[++CbotData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.on ? "Online" : "Offline")
if(!CbotData.len)
CbotData[++CbotData.len] = list("x" = 0, "y" = 0, dir=null, status = null)
var/CartData[0]
for(var/obj/structure/janitorialcart/B in all_janitorial_carts)
var/turf/bl = get_turf(B)
if(bl)
if(bl.z != cl.z)
continue
var/direction = get_dir(src,B)
var/status = "No Bucket"
if(B.mybucket)
status = B.mybucket.reagents.total_volume / 100
CartData[++CartData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = status)
if(!CartData.len)
CartData[++CartData.len] = list("x" = 0, "y" = 0, dir=null, status = null)
JaniData["mops"] = MopData
JaniData["buckets"] = BucketData
JaniData["cleanbots"] = CbotData
JaniData["carts"] = CartData
values["janitor"] = JaniData
return values
/obj/item/weapon/cartridge/Topic(href, href_list)
..()
if (!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
usr.unset_machine()
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")
if(is_jammed(src))
return
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 = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", message1) as text|null, 40), 40)
updateSelfDialog()
if("setmsg2")
message2 = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", message2) as text|null, 40), 40)
updateSelfDialog()
else
post_status(href_list["statdisp"])
if("Power Select")
selected_sensor = href_list["target"]
loc:mode = 433
mode = 433
if("Power Clear")
selected_sensor = null
loc:mode = 43
mode = 43
if("MULEbot")
var/mob/living/bot/mulebot/M = locate(href_list["ref"])
if(istype(M))
M.obeyCommand(href_list["command"])
return 1

View File

@@ -1,17 +0,0 @@
var/list/exploration_cartridges = list(
/obj/item/weapon/cartridge/explorer,
/obj/item/weapon/cartridge/sar
)
/obj/item/weapon/cartridge/explorer
name = "\improper Explorator cartridge"
icon_state = "cart-e"
access_reagent_scanner = 1
access_atmos = 1
/obj/item/weapon/cartridge/sar
name = "\improper Med-Exp cartridge"
icon_state = "cart-m"
access_medical = 1
access_reagent_scanner = 1
access_atmos = 1

View File

@@ -1,16 +0,0 @@
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

View File

@@ -1,153 +0,0 @@
/obj/item/radio/integrated
name = "\improper PDA radio module"
desc = "An electronic radio system."
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)
//to_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 = TRANSMISSION_RADIO
signal.data[key] = value
if(key2)
signal.data[key2] = value2
if(key3)
signal.data[key3] = value3
frequency.post_signal(src, signal, radio_filter = s_filter)
return
proc/generate_menu()
/obj/item/radio/integrated/beepsky
var/list/botlist = null // list of bots
var/mob/living/bot/secbot/active // the active bot; if null, show bot list
var/list/botstatus // the status signal sent by the bot
var/control_freq = BOT_FREQ
// 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, radio_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
/*
to_world("recvd:[P] : [signal.source]")
for(var/d in signal.data)
to_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)
/obj/item/radio/integrated/beepsky/Destroy()
if(radio_controller)
radio_controller.remove_object(src, control_freq)
return ..()
/*
* 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
/obj/item/radio/integrated/signal/Initialize()
if(!radio_controller)
return
if (src.frequency < PUBLIC_LOW_FREQ || src.frequency > PUBLIC_HIGH_FREQ)
src.frequency = sanitize_frequency(src.frequency)
set_frequency(frequency)
/obj/item/radio/integrated/signal/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency)
/obj/item/radio/integrated/signal/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)
/obj/item/radio/integrated/signal/Destroy()
if(radio_controller)
radio_controller.remove_object(src, frequency)
return ..()

View File

@@ -1,292 +0,0 @@
// Proc: ui_interact()
// Parameters: 4 (standard NanoUI arguments)
// Description: Uses a bunch of for loops to turn lists into lists of lists, so they can be displayed in nanoUI, then displays various buttons to the user.
/obj/item/device/communicator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/key_state = null)
// this is the data which will be sent to the ui
var/data[0] //General nanoUI information
var/communicators[0] //List of communicators
var/invites[0] //Communicators and ghosts we've invited to our communicator.
var/requests[0] //Communicators and ghosts wanting to go in our communicator.
var/voices[0] //Current /mob/living/voice s inside the device.
var/connected_communicators[0] //Current communicators connected to the device.
var/im_contacts_ui[0] //List of communicators that have been messaged.
var/im_list_ui[0] //List of messages.
var/weather[0]
var/modules_ui[0] //Home screen info.
//First we add other 'local' communicators.
for(var/obj/item/device/communicator/comm in known_devices)
if(comm.network_visibility && comm.exonet)
communicators[++communicators.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address)
//Now for ghosts who we pretend have communicators.
for(var/mob/observer/dead/O in known_devices)
if(O.client && O.client.prefs.communicator_visibility == 1 && O.exonet)
communicators[++communicators.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]")
//Lists all the other communicators that we invited.
for(var/obj/item/device/communicator/comm in voice_invites)
if(comm.exonet)
invites[++invites.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
//Ghosts we invited.
for(var/mob/observer/dead/O in voice_invites)
if(O.exonet && O.client)
invites[++invites.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]")
//Communicators that want to talk to us.
for(var/obj/item/device/communicator/comm in voice_requests)
if(comm.exonet)
requests[++requests.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
//Ghosts that want to talk to us.
for(var/mob/observer/dead/O in voice_requests)
if(O.exonet && O.client)
requests[++requests.len] = list("name" = sanitize("[O.client.prefs.real_name]'s communicator"), "address" = O.exonet.address, "ref" = "\ref[O]")
//Now for all the voice mobs inside the communicator.
for(var/mob/living/voice/voice in contents)
voices[++voices.len] = list("name" = sanitize("[voice.name]'s communicator"), "true_name" = sanitize(voice.name))
//Finally, all the communicators linked to this one.
for(var/obj/item/device/communicator/comm in communicating)
connected_communicators[++connected_communicators.len] = list("name" = sanitize(comm.name), "true_name" = sanitize(comm.name), "ref" = "\ref[comm]")
//Devices that have been messaged or recieved messages from.
for(var/obj/item/device/communicator/comm in im_contacts)
if(comm.exonet)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(comm.name), "address" = comm.exonet.address, "ref" = "\ref[comm]")
for(var/mob/observer/dead/ghost in im_contacts)
if(ghost.exonet)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(ghost.name), "address" = ghost.exonet.address, "ref" = "\ref[ghost]")
for(var/obj/item/integrated_circuit/input/EPv2/CIRC in im_contacts)
if(CIRC.exonet && CIRC.assembly)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(CIRC.assembly.name), "address" = CIRC.exonet.address, "ref" = "\ref[CIRC]")
//Actual messages.
for(var/I in im_list)
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
//Weather reports.
for(var/datum/planet/planet in SSplanets.planets)
if(planet.weather_holder && planet.weather_holder.current_weather)
var/list/W = list(
"Planet" = planet.name,
"Time" = planet.current_time.show_time("hh:mm"),
"Weather" = planet.weather_holder.current_weather.name,
"Temperature" = planet.weather_holder.temperature - T0C,
"High" = planet.weather_holder.current_weather.temp_high - T0C,
"Low" = planet.weather_holder.current_weather.temp_low - T0C,
"WindDir" = planet.weather_holder.wind_dir ? dir2text(planet.weather_holder.wind_dir) : "None",
"WindSpeed" = planet.weather_holder.wind_speed ? "[planet.weather_holder.wind_speed > 2 ? "Severe" : "Normal"]" : "None",
"Forecast" = english_list(planet.weather_holder.forecast, and_text = "&#8594;", comma_text = "&#8594;", final_comma_text = "&#8594;") // Unicode RIGHTWARDS ARROW.
)
weather[++weather.len] = W
// Update manifest
data_core.get_manifest_list()
//Modules for homescreen.
for(var/list/R in modules)
modules_ui[++modules_ui.len] = R
data["user"] = "\ref[user]" // For receiving input() via topic, because input(usr,...) wasn't working on cartridges
data["owner"] = owner ? owner : "Unset"
data["occupation"] = occupation ? occupation : "Swipe ID to set."
data["connectionStatus"] = get_connection_to_tcomms()
data["visible"] = network_visibility
data["address"] = exonet.address ? exonet.address : "Unallocated"
data["targetAddress"] = target_address
data["targetAddressName"] = target_address_name
data["currentTab"] = selected_tab
data["knownDevices"] = communicators
data["invitesSent"] = invites
data["requestsReceived"] = requests
data["voice_mobs"] = voices
data["communicating"] = connected_communicators
data["video_comm"] = video_source ? "\ref[video_source.loc]" : null
data["imContacts"] = im_contacts_ui
data["imList"] = im_list_ui
data["time"] = stationtime2text()
data["ring"] = ringer
data["homeScreen"] = modules_ui
data["note"] = note // current notes
data["weather"] = weather
data["aircontents"] = src.analyze_air()
data["flashlight"] = fon
data["manifest"] = PDA_Manifest
data["feeds"] = compile_news()
data["latest_news"] = get_recent_news()
if(newsfeed_channel)
data["target_feed"] = data["feeds"][newsfeed_channel]
if(cartridge) // If there's a cartridge, we need to grab the information from it
data["cart_devices"] = cartridge.get_device_status()
data["cart_templates"] = cartridge.ui_templates
for(var/list/L in cartridge.get_data())
data[L["field"]] = L["value"]
// cartridge.get_data() returns a list of tuples:
// The field element is the tag used to access the information by the template
// The value element is the actual data, and can take any form necessary for the template
// update the ui if it exists, returns null if no ui is passed/found
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
data["currentTab"] = 1 // Reset the current tab, because we're going to home page
ui = new(user, src, ui_key, "communicator_header.tmpl", "Communicator", 475, 700, state = key_state)
// add templates for screens in common with communicator.
ui.add_template("atmosphericScan", "atmospheric_scan.tmpl")
ui.add_template("crewManifest", "crew_manifest.tmpl")
ui.add_template("Body", "communicator.tmpl") // Main body
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
// open the new ui window
ui.open()
// auto update every five Master Controller tick
ui.set_auto_update(5)
// Proc: Topic()
// Parameters: 2 (standard Topic arguments)
// Description: Responds to NanoUI button presses.
/obj/item/device/communicator/Topic(href, href_list)
if(..())
return 1
if(href_list["rename"])
var/new_name = sanitizeSafe(input(usr,"Please enter your name.","Communicator",usr.name) )
if(new_name)
register_device(new_name)
if(href_list["toggle_visibility"])
switch(network_visibility)
if(1) //Visible, becoming invisbile
network_visibility = 0
if(camera)
camera.remove_network(NETWORK_COMMUNICATORS)
if(0) //Invisible, becoming visible
network_visibility = 1
if(camera)
camera.add_network(NETWORK_COMMUNICATORS)
if(href_list["toggle_ringer"])
ringer = !ringer
if(href_list["add_hex"])
var/hex = href_list["add_hex"]
add_to_EPv2(hex)
if(href_list["write_target_address"])
var/new_address = sanitizeSafe(input(usr,"Please enter the desired target EPv2 address. Note that you must write the colons \
yourself.","Communicator",src.target_address) )
if(new_address)
target_address = new_address
if(href_list["clear_target_address"])
target_address = ""
if(href_list["dial"])
if(!get_connection_to_tcomms())
to_chat(usr, "<span class='danger'>Error: Cannot connect to Exonet node.</span>")
return
var/their_address = href_list["dial"]
exonet.send_message(their_address, "voice")
if(href_list["decline"])
var/ref_to_remove = href_list["decline"]
var/atom/decline = locate(ref_to_remove)
if(decline)
del_request(decline)
if(href_list["message"])
if(!get_connection_to_tcomms())
to_chat(usr, "<span class='danger'>Error: Cannot connect to Exonet node.</span>")
return
var/their_address = href_list["message"]
var/text = sanitizeSafe(input(usr,"Enter your message.","Text Message"))
if(text)
exonet.send_message(their_address, "text", text)
im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text))
log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr)
for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
continue
if(exonet.get_atom_from_address(their_address) == M)
continue
M.show_message("Comm IM - [src] -> [exonet.get_atom_from_address(their_address)]: [text]")
if(href_list["disconnect"])
var/name_to_disconnect = href_list["disconnect"]
for(var/mob/living/voice/V in contents)
if(name_to_disconnect == V.name)
close_connection(usr, V, "[usr] hung up")
for(var/obj/item/device/communicator/comm in communicating)
if(name_to_disconnect == comm.name)
close_connection(usr, comm, "[usr] hung up")
if(href_list["startvideo"])
var/ref_to_video = href_list["startvideo"]
var/obj/item/device/communicator/comm = locate(ref_to_video)
if(comm)
connect_video(usr, comm)
if(href_list["endvideo"])
if(video_source)
end_video()
if(href_list["watchvideo"])
if(video_source)
watch_video(usr,video_source.loc)
if(href_list["copy"])
target_address = href_list["copy"]
if(href_list["copy_name"])
target_address_name = href_list["copy_name"]
if(href_list["hang_up"])
for(var/mob/living/voice/V in contents)
close_connection(usr, V, "[usr] hung up")
for(var/obj/item/device/communicator/comm in communicating)
close_connection(usr, comm, "[usr] hung up")
if(href_list["switch_tab"])
selected_tab = href_list["switch_tab"]
if(href_list["edit"])
var/n = input(usr, "Please enter message", name, notehtml)
n = sanitizeSafe(n, extra = 0)
if(n)
note = html_decode(n)
notehtml = note
note = replacetext(note, "\n", "<br>")
else
note = ""
notehtml = note
if(href_list["switch_template"])
var/datum/nanoui/ui = SSnanoui.get_open_ui(usr, src, "main")
if(ui)
ui.add_template("Body", href_list["switch_template"])
if(href_list["Light"])
fon = !fon
set_light(fon * flum)
if(href_list["toggle_device"])
var/obj/O = cartridge.internal_devices[text2num(href_list["toggle_device"])]
cartridge.active_devices ^= list(O) // Exclusive or, will toggle its presence
if(href_list["newsfeed"])
newsfeed_channel = text2num(href_list["newsfeed"])
if(href_list["cartridge_topic"] && cartridge) // Has to have a cartridge to perform these functions
cartridge.Topic(href, href_list)
SSnanoui.update_uis(src)
add_fingerprint(usr)

View File

@@ -0,0 +1,326 @@
// Proc: tgui_state()
// Parameters: User
// Description: This tells TGUI to only allow us to be interacted with while in a mob inventory.
/obj/item/device/communicator/tgui_state(mob/user)
return GLOB.tgui_inventory_state
// Proc: tgui_interact()
// Parameters: User, UI, Parent UI
// Description: This proc handles opening the UI. It's basically just a standard stub.
/obj/item/device/communicator/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Communicator", name)
if(custom_state)
ui.set_state(custom_state)
ui.open()
if(custom_state) // Just in case
ui.set_state(custom_state)
// Proc: tgui_data()
// Parameters: User, UI, State
// Description: Uses a bunch of for loops to turn lists into lists of lists, so they can be displayed in nanoUI, then displays various buttons to the user.
/obj/item/device/communicator/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
// this is the data which will be sent to the ui
var/list/data = list() //General nanoUI information
var/list/communicators = list() //List of communicators
var/list/invites = list() //Communicators and ghosts we've invited to our communicator.
var/list/requests = list() //Communicators and ghosts wanting to go in our communicator.
var/list/voices = list() //Current /mob/living/voice s inside the device.
var/list/connected_communicators = list() //Current communicators connected to the device.
var/list/im_contacts_ui = list() //List of communicators that have been messaged.
var/list/im_list_ui = list() //List of messages.
var/list/weather = list()
var/list/modules_ui = list() //Home screen info.
//First we add other 'local' communicators.
for(var/obj/item/device/communicator/comm in known_devices)
if(comm.network_visibility && comm.exonet)
communicators.Add(list(list(
"name" = sanitize(comm.name),
"address" = comm.exonet.address
)))
//Now for ghosts who we pretend have communicators.
for(var/mob/observer/dead/O in known_devices)
if(O.client && O.client.prefs.communicator_visibility == 1 && O.exonet)
communicators.Add(list(list(
"name" = sanitize("[O.client.prefs.real_name]'s communicator"),
"address" = O.exonet.address,
"ref" = "\ref[O]"
)))
//Lists all the other communicators that we invited.
for(var/obj/item/device/communicator/comm in voice_invites)
if(comm.exonet)
invites.Add(list(list(
"name" = sanitize(comm.name),
"address" = comm.exonet.address,
"ref" = "\ref[comm]"
)))
//Ghosts we invited.
for(var/mob/observer/dead/O in voice_invites)
if(O.exonet && O.client)
invites.Add(list(list(
"name" = sanitize("[O.client.prefs.real_name]'s communicator"),
"address" = O.exonet.address,
"ref" = "\ref[O]"
)))
//Communicators that want to talk to us.
for(var/obj/item/device/communicator/comm in voice_requests)
if(comm.exonet)
requests.Add(list(list(
"name" = sanitize(comm.name),
"address" = comm.exonet.address,
"ref" = "\ref[comm]"
)))
//Ghosts that want to talk to us.
for(var/mob/observer/dead/O in voice_requests)
if(O.exonet && O.client)
requests.Add(list(list(
"name" = sanitize("[O.client.prefs.real_name]'s communicator"),
"address" = O.exonet.address,
"ref" = "\ref[O]"
)))
//Now for all the voice mobs inside the communicator.
for(var/mob/living/voice/voice in contents)
voices.Add(list(list(
"name" = sanitize("[voice.name]'s communicator"),
"true_name" = sanitize(voice.name),
)))
//Finally, all the communicators linked to this one.
for(var/obj/item/device/communicator/comm in communicating)
connected_communicators.Add(list(list(
"name" = sanitize(comm.name),
"true_name" = sanitize(comm.name),
"ref" = "\ref[comm]",
)))
//Devices that have been messaged or recieved messages from.
for(var/obj/item/device/communicator/comm in im_contacts)
if(comm.exonet)
im_contacts_ui.Add(list(list(
"name" = sanitize(comm.name),
"address" = comm.exonet.address,
"ref" = "\ref[comm]"
)))
for(var/mob/observer/dead/ghost in im_contacts)
if(ghost.exonet)
im_contacts_ui.Add(list(list(
"name" = sanitize(ghost.name),
"address" = ghost.exonet.address,
"ref" = "\ref[ghost]"
)))
for(var/obj/item/integrated_circuit/input/EPv2/CIRC in im_contacts)
if(CIRC.exonet && CIRC.assembly)
im_contacts_ui.Add(list(list(
"name" = sanitize(CIRC.assembly.name),
"address" = CIRC.exonet.address,
"ref" = "\ref[CIRC]"
)))
//Actual messages.
for(var/I in im_list)
im_list_ui.Add(list(list(
"address" = I["address"],
"to_address" = I["to_address"],
"im" = I["im"]
)))
//Weather reports.
for(var/datum/planet/planet in SSplanets.planets)
if(planet.weather_holder && planet.weather_holder.current_weather)
var/list/W = list(
"Planet" = planet.name,
"Time" = planet.current_time.show_time("hh:mm"),
"Weather" = planet.weather_holder.current_weather.name,
"Temperature" = planet.weather_holder.temperature - T0C,
"High" = planet.weather_holder.current_weather.temp_high - T0C,
"Low" = planet.weather_holder.current_weather.temp_low - T0C,
"WindDir" = planet.weather_holder.wind_dir ? dir2text(planet.weather_holder.wind_dir) : "None",
"WindSpeed" = planet.weather_holder.wind_speed ? "[planet.weather_holder.wind_speed > 2 ? "Severe" : "Normal"]" : "None",
"Forecast" = english_list(planet.weather_holder.forecast, and_text = "&#8594;", comma_text = "&#8594;", final_comma_text = "&#8594;") // Unicode RIGHTWARDS ARROW.
)
weather.Add(list(W))
//Modules for homescreen.
for(var/list/R in modules)
modules_ui.Add(list(R))
data["user"] = "\ref[user]" // For receiving input() via topic, because input(usr,...) wasn't working on cartridges
data["owner"] = owner ? owner : "Unset"
data["occupation"] = occupation ? occupation : "Swipe ID to set."
data["connectionStatus"] = get_connection_to_tcomms()
data["visible"] = network_visibility
data["address"] = exonet.address ? exonet.address : "Unallocated"
data["targetAddress"] = target_address
data["targetAddressName"] = target_address_name
data["currentTab"] = selected_tab
data["knownDevices"] = communicators
data["invitesSent"] = invites
data["requestsReceived"] = requests
data["voice_mobs"] = voices
data["communicating"] = connected_communicators
data["video_comm"] = video_source ? "\ref[video_source.loc]" : null
data["imContacts"] = im_contacts_ui
data["imList"] = im_list_ui
data["time"] = stationtime2text()
data["ring"] = ringer
data["homeScreen"] = modules_ui
data["note"] = note // current notes
data["weather"] = weather
data["aircontents"] = src.analyze_air()
data["flashlight"] = fon
data["feeds"] = compile_news()
data["latest_news"] = get_recent_news()
if(newsfeed_channel)
data["target_feed"] = data["feeds"][newsfeed_channel]
else
data["target_feed"] = null
return data
// Proc: tgui_static_data()
// Parameters: User, UI, State
// Description: Just like tgui_data, except it only gets called once when the user opens the UI, not every tick.
/obj/item/device/communicator/tgui_static_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
// Update manifest'
if(data_core)
data_core.get_manifest_list()
data["manifest"] = PDA_Manifest
return data
// Proc: tgui-act()
// Parameters: 4 (standard tgui_act arguments)
// Description: Responds to UI button presses.
/obj/item/device/communicator/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
add_fingerprint(usr)
. = TRUE
switch(action)
if("rename")
var/new_name = sanitizeSafe(input(usr,"Please enter your name.","Communicator",usr.name) )
if(new_name)
register_device(new_name)
if("toggle_visibility")
switch(network_visibility)
if(1) //Visible, becoming invisbile
network_visibility = 0
if(camera)
camera.remove_network(NETWORK_COMMUNICATORS)
if(0) //Invisible, becoming visible
network_visibility = 1
if(camera)
camera.add_network(NETWORK_COMMUNICATORS)
if("toggle_ringer")
ringer = !ringer
if("add_hex")
var/hex = params["add_hex"]
add_to_EPv2(hex)
if("write_target_address")
target_address = sanitizeSafe(params["val"])
if("clear_target_address")
target_address = ""
if("dial")
if(!get_connection_to_tcomms())
to_chat(usr, "<span class='danger'>Error: Cannot connect to Exonet node.</span>")
return FALSE
var/their_address = params["dial"]
exonet.send_message(their_address, "voice")
if("decline")
var/ref_to_remove = params["decline"]
var/atom/decline = locate(ref_to_remove)
if(decline)
del_request(decline)
if("message")
if(!get_connection_to_tcomms())
to_chat(usr, "<span class='danger'>Error: Cannot connect to Exonet node.</span>")
return FALSE
var/their_address = params["message"]
var/text = sanitizeSafe(input(usr,"Enter your message.","Text Message"))
if(text)
exonet.send_message(their_address, "text", text)
im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text))
log_pda("(COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]", usr)
for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
continue
if(exonet.get_atom_from_address(their_address) == M)
continue
M.show_message("Comm IM - [src] -> [exonet.get_atom_from_address(their_address)]: [text]")
if("disconnect")
var/name_to_disconnect = params["disconnect"]
for(var/mob/living/voice/V in contents)
if(name_to_disconnect == sanitize(V.name))
close_connection(usr, V, "[usr] hung up")
for(var/obj/item/device/communicator/comm in communicating)
if(name_to_disconnect == sanitize(comm.name))
close_connection(usr, comm, "[usr] hung up")
if("startvideo")
var/ref_to_video = params["startvideo"]
var/obj/item/device/communicator/comm = locate(ref_to_video)
if(comm)
connect_video(usr, comm)
if("endvideo")
if(video_source)
end_video()
if("copy")
target_address = params["copy"]
if("copy_name")
target_address_name = params["copy_name"]
if("hang_up")
for(var/mob/living/voice/V in contents)
close_connection(usr, V, "[usr] hung up")
for(var/obj/item/device/communicator/comm in communicating)
close_connection(usr, comm, "[usr] hung up")
if("switch_tab")
selected_tab = params["switch_tab"]
if("edit")
var/n = input(usr, "Please enter message", name, notehtml) as message|null
n = sanitizeSafe(n, extra = 0)
if(n)
note = html_decode(n)
notehtml = note
note = replacetext(note, "\n", "<br>")
else
note = ""
notehtml = note
if("Light")
fon = !fon
set_light(fon * flum)
if("newsfeed")
newsfeed_channel = text2num(params["newsfeed"])

View File

@@ -1,952 +0,0 @@
// Communicator peripheral devices
// Internal devices that attack() can be relayed to
// Additional UI menus for added functionality
/obj/item/weapon/commcard
name = "generic commcard"
desc = "A peripheral plug-in for personal communicators."
icon = 'icons/obj/pda.dmi'
icon_state = "cart"
item_state = "electronic"
w_class = ITEMSIZE_TINY
var/list/internal_devices = list() // Devices that can be toggled on to trigger on attack()
var/list/active_devices = list() // Devices that will be triggered on attack()
var/list/ui_templates = list() // List of ui templates the commcard can access
var/list/internal_data = list() // Data that shouldn't be updated every time nanoUI updates, or needs to persist between updates
/obj/item/weapon/commcard/proc/get_device_status()
var/list/L = list()
var/i = 1
for(var/obj/I in internal_devices)
if(I in active_devices)
L[++L.len] = list("name" = "\proper[I.name]", "active" = 1, "index" = i++)
else
L[++L.len] = list("name" = I.name, "active" = 0, "index" = i++)
return L
// cartridge.get_data() returns a list of tuples:
// The field element is the tag used to access the information by the template
// The value element is the actual data, and can take any form necessary for the template
/obj/item/weapon/commcard/proc/get_data()
return list()
// Handles cartridge-specific functions
// The helper.link() MUST HAVE 'cartridge_topic' passed into the href in order for cartridge functions to be processed.
// Doesn't matter what the value of it is for now, it's just a flag to say, "Hey, there's cartridge data to change!"
/obj/item/weapon/commcard/Topic(href, href_list)
// Signalers
if(href_list["signaler_target"])
var/obj/item/device/assembly/signaler/S = locate(href_list["signaler_target"]) // Should locate the correct signaler
if(!istype(S)) // Ref is no longer valid
return
if(S.loc != src) // No longer within the cartridge
return
switch(href_list["signaler_action"])
if("Pulse")
S.activate()
if("Edit")
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Ref no longer valid
return
var/newVal = input(user, "Input a new [href_list["signaler_value"]].", href_list["signaler_value"], (href_list["signaler_value"] == "Code" ? S.code : S.frequency)) as num|null
if(newVal)
switch(href_list["signaler_value"])
if("Code")
S.code = newVal
if("Frequency")
S.frequency = newVal
// Refresh list of powernet sensors
if(href_list["powernet_refresh"])
internal_data["grid_sensors"] = find_powernet_sensors()
// Load apc's on targeted powernet
if(href_list["powernet_target"])
internal_data["powernet_target"] = href_list["powernet_target"]
// GPS units
if(href_list["gps_target"])
var/obj/item/device/gps/G = locate(href_list["gps_target"])
if(!istype(G)) // Ref is no longer valid
return
if(G.loc != src) // No longer within the cartridge
return
switch(href_list["gps_action"])
if("Power")
G.tracking = text2num(href_list["value"])
if("Long_Range")
G.local_mode = text2num(href_list["value"])
if("Hide_Signal")
G.hide_signal = text2num(href_list["value"])
if("Tag")
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Ref no longer valid
return
var/newTag = input(user, "Please enter desired tag.", G.tag) as text|null
if(newTag)
G.tag = newTag
if(href_list["active_category"])
internal_data["supply_category"] = href_list["active_category"]
// Supply topic
// Copied from /obj/machinery/computer/supplycomp/Topic()
// code\game\machinery\computer\supply.dm, line 188
// Unfortunately, in order to support complete functionality, the whole thing is necessary
if(href_list["pack_ref"])
var/datum/supply_pack/S = locate(href_list["pack_ref"])
// Invalid ref
if(!istype(S))
return
// Expand the supply pack's contents
if(href_list["expand"])
internal_data["supply_pack_expanded"] ^= S
// Make a request for the pack
if(href_list["request"])
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Invalid ref
return
if(world.time < internal_data["supply_reqtime"])
visible_message("<span class='warning'>[src] flashes, \"[internal_data["supply_reqtime"] - world.time] seconds remaining until another requisition form may be printed.\"</span>")
return
var/timeout = world.time + 600
var/reason = sanitize(input(user, "Reason:","Why do you require this item?","") as null|text)
if(world.time > timeout)
to_chat(user, "<span class='warning'>Error. Request timed out.</span>")
return
if(!reason)
return
SSsupply.create_order(S, user, reason)
internal_data["supply_reqtime"] = (world.time + 5) % 1e5
if(href_list["order_ref"])
var/datum/supply_order/O = locate(href_list["order_ref"])
// Invalid ref
if(!istype(O))
return
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Invalid ref
return
if(href_list["edit"])
var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text)
if(!new_val)
return
switch(href_list["edit"])
if("Supply Pack")
O.name = new_val
if("Cost")
var/num = text2num(new_val)
if(num)
O.cost = num
if("Index")
var/num = text2num(new_val)
if(num)
O.index = num
if("Reason")
O.comment = new_val
if("Ordered by")
O.ordered_by = new_val
if("Ordered at")
O.ordered_at = new_val
if("Approved by")
O.approved_by = new_val
if("Approved at")
O.approved_at = new_val
if(href_list["approve"])
SSsupply.approve_order(O, user)
if(href_list["deny"])
SSsupply.deny_order(O, user)
if(href_list["delete"])
SSsupply.delete_order(O, user)
if(href_list["clear_all_requests"])
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Invalid ref
return
SSsupply.deny_all_pending(user)
if(href_list["export_ref"])
var/datum/exported_crate/E = locate(href_list["export_ref"])
// Invalid ref
if(!istype(E))
return
var/mob/user = locate(href_list["user"])
if(!istype(user)) // Invalid ref
return
if(href_list["index"])
var/list/L = E.contents[href_list["index"]]
if(href_list["edit"])
var/field = alert(user, "Select which field to edit", , "Name", "Quantity", "Value")
var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text)
if(!new_val)
return
switch(field)
if("Name")
L["object"] = new_val
if("Quantity")
var/num = text2num(new_val)
if(num)
L["quantity"] = num
if("Value")
var/num = text2num(new_val)
if(num)
L["value"] = num
if(href_list["delete"])
E.contents.Cut(href_list["index"], href_list["index"] + 1)
// Else clause means they're editing/deleting the whole export report, rather than a specific item in it
else if(href_list["edit"])
var/new_val = sanitize(input(user, href_list["edit"], "Enter the new value for this field:", href_list["default"]) as null|text)
if(!new_val)
return
switch(href_list["edit"])
if("Name")
E.name = new_val
if("Value")
var/num = text2num(new_val)
if(num)
E.value = num
else if(href_list["delete"])
SSsupply.delete_export(E, user)
else if(href_list["add_item"])
SSsupply.add_export_item(E, user)
if(SSsupply && SSsupply.shuttle)
switch(href_list["send_shuttle"])
if("send_away")
if(SSsupply.shuttle.forbidden_atoms_check())
to_chat(usr, "<span class='warning'>For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.</span>")
else
SSsupply.shuttle.launch(src)
to_chat(usr, "<span class='notice'>Initiating launch sequence.</span>")
if("send_to_station")
SSsupply.shuttle.launch(src)
to_chat(usr, "<span class='notice'>The supply shuttle has been called and will arrive in approximately [round(SSsupply.movetime/600,1)] minutes.</span>")
if("cancel_shuttle")
SSsupply.shuttle.cancel_launch(src)
if("force_shuttle")
SSsupply.shuttle.force_launch(src)
// Status display
switch(href_list["stat_display"])
if("message")
post_status("message", internal_data["stat_display_line1"], internal_data["stat_display_line2"])
internal_data["stat_display_special"] = "message"
if("alert")
post_status("alert", href_list["alert"])
internal_data["stat_display_special"] = href_list["alert"]
if("setmsg")
internal_data["stat_display_line[href_list["line"]]"] = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", internal_data["stat_display_line[href_list["line"]]"]) as text|null, 40), 40)
else
post_status(href_list["stat_display"])
internal_data["stat_display_special"] = href_list["stat_display"]
// Merc shuttle blast door controls
switch(href_list["all_blast_doors"])
if("open")
for(var/obj/machinery/door/blast/B in internal_data["shuttle_doors"])
B.open()
if("close")
for(var/obj/machinery/door/blast/B in internal_data["shuttle_doors"])
B.close()
if(href_list["scan_blast_doors"])
internal_data["shuttle_doors"] = find_blast_doors()
if(href_list["toggle_blast_door"])
var/obj/machinery/door/blast/B = locate(href_list["toggle_blast_door"])
if(!B)
return
spawn(0)
if(B.density)
B.open()
else
B.close()
// Updates status displays with a new message
// Copied from /obj/item/weapon/cartridge/proc/post_status(),
// code/game/objects/items/devices/PDA/cart.dm, line 251
/obj/item/weapon/commcard/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 = TRANSMISSION_RADIO
status_signal.data["command"] = command
switch(command)
if("message")
status_signal.data["msg1"] = data1
status_signal.data["msg2"] = data2
internal_data["stat_display_active1"] = data1 // Update the internally stored message, we won't get receive_signal if we're the sender
internal_data["stat_display_active2"] = data2
if(loc)
var/obj/item/PDA = loc
var/mob/user = PDA.fingerprintslast
log_admin("STATUS: [user] set status screen with [src]. Message: [data1] [data2]")
message_admins("STATUS: [user] set status screen with [src]. Message: [data1] [data2]")
if("alert")
status_signal.data["picture_state"] = data1
frequency.post_signal(src, status_signal)
// Receives updates by external devices to the status displays
/obj/item/weapon/commcard/receive_signal(var/datum/signal/signal, var/receive_method, var/receive_param)
internal_data["stat_display_special"] = signal.data["command"]
switch(signal.data["command"])
if("message")
internal_data["stat_display_active1"] = signal.data["msg1"]
internal_data["stat_display_active2"] = signal.data["msg2"]
if("alert")
internal_data["stat_display_special"] = signal.data["picture_state"]
///////////////////////////
// SUBTYPES
///////////////////////////
// Engineering Cartridge:
// Devices
// *- Halogen Counter
// Templates
// *- Power Monitor
/obj/item/weapon/commcard/engineering
name = "\improper Power-ON cartridge"
icon_state = "cart-e"
ui_templates = list(list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl"))
/obj/item/weapon/commcard/engineering/New()
..()
internal_devices |= new /obj/item/device/halogen_counter(src)
/obj/item/weapon/commcard/engineering/Initialize()
internal_data["grid_sensors"] = find_powernet_sensors()
internal_data["powernet_target"] = ""
/obj/item/weapon/commcard/engineering/get_data()
return list(
list("field" = "powernet_monitoring", "value" = get_powernet_monitoring_list()),
list("field" = "powernet_target", "value" = get_powernet_target(internal_data["powernet_target"]))
)
// Atmospherics Cartridge:
// Devices
// *- Gas scanner
/obj/item/weapon/commcard/atmos
name = "\improper BreatheDeep cartridge"
icon_state = "cart-a"
/obj/item/weapon/commcard/atmos/New()
..()
internal_devices |= new /obj/item/device/analyzer(src)
// Medical Cartridge:
// Devices
// *- Halogen Counter
// *- Health Analyzer
// Templates
// *- Medical Records
/obj/item/weapon/commcard/medical
name = "\improper Med-U cartridge"
icon_state = "cart-m"
ui_templates = list(list("name" = "Medical Records", "template" = "med_records.tmpl"))
/obj/item/weapon/commcard/medical/New()
..()
internal_devices |= new /obj/item/device/healthanalyzer(src)
internal_devices |= new /obj/item/device/halogen_counter(src)
/obj/item/weapon/commcard/medical/get_data()
return list(list("field" = "med_records", "value" = get_med_records()))
// Chemistry Cartridge:
// Devices
// *- Halogen Counter
// *- Health Analyzer
// *- Reagent Scanner
// Templates
// *- Medical Records
/obj/item/weapon/commcard/medical/chemistry
name = "\improper ChemWhiz cartridge"
icon_state = "cart-chem"
/obj/item/weapon/commcard/medical/chemistry/New()
..()
internal_devices |= new /obj/item/device/reagent_scanner(src)
// Detective Cartridge:
// Devices
// *- Halogen Counter
// *- Health Analyzer
// Templates
// *- Medical Records
// *- Security Records
/obj/item/weapon/commcard/medical/detective
name = "\improper D.E.T.E.C.T. cartridge"
icon_state = "cart-s"
ui_templates = list(
list("name" = "Medical Records", "template" = "med_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl")
)
/obj/item/weapon/commcard/medical/detective/get_data()
var/list/data = ..()
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
return data
// Internal Affairs Cartridge:
// Templates
// *- Security Records
// *- Employment Records
/obj/item/weapon/commcard/int_aff
name = "\improper P.R.O.V.E. cartridge"
icon_state = "cart-s"
ui_templates = list(
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl")
)
/obj/item/weapon/commcard/int_aff/get_data()
return list(
list("field" = "emp_records", "value" = get_emp_records()),
list("field" = "sec_records", "value" = get_sec_records())
)
// Security Cartridge:
// Templates
// *- Security Records
// *- Security Bot Access
/obj/item/weapon/commcard/security
name = "\improper R.O.B.U.S.T. cartridge"
icon_state = "cart-s"
ui_templates = list(
list("name" = "Security Records", "template" = "sec_records.tmpl"),
list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl")
)
/obj/item/weapon/commcard/security/get_data()
return list(
list("field" = "sec_records", "value" = get_sec_records()),
list("field" = "sec_bot_access", "value" = get_sec_bot_access())
)
// Janitor Cartridge:
// Templates
// *- Janitorial Locator Magicbox
/obj/item/weapon/commcard/janitor
name = "\improper CustodiPRO cartridge"
desc = "The ultimate in clean-room design."
ui_templates = list(
list("name" = "Janitorial Supply Locator", "template" = "janitorialLocator.tmpl")
)
/obj/item/weapon/commcard/janitor/get_data()
return list(
list("field" = "janidata", "value" = get_janitorial_locations())
)
// Signal Cartridge:
// Devices
// *- Signaler
// Templates
// *- Signaler Access
/obj/item/weapon/commcard/signal
name = "generic signaler cartridge"
desc = "A data cartridge with an integrated radio signaler module."
ui_templates = list(
list("name" = "Integrated Signaler Control", "template" = "signaler_access.tmpl")
)
/obj/item/weapon/commcard/signal/New()
..()
internal_devices |= new /obj/item/device/assembly/signaler(src)
/obj/item/weapon/commcard/signal/get_data()
return list(
list("field" = "signaler_access", "value" = get_int_signalers())
)
// Science Cartridge:
// Devices
// *- Signaler
// *- Reagent Scanner
// *- Gas Scanner
// Templates
// *- Signaler Access
/obj/item/weapon/commcard/signal/science
name = "\improper Signal Ace 2 cartridge"
desc = "Complete with integrated radio signaler!"
icon_state = "cart-tox"
// UI templates inherited
/obj/item/weapon/commcard/signal/science/New()
..()
internal_devices |= new /obj/item/device/reagent_scanner(src)
internal_devices |= new /obj/item/device/analyzer(src)
// Supply Cartridge:
// Templates
// *- Supply Records
/obj/item/weapon/commcard/supply
name = "\improper Space Parts & Space Vendors cartridge"
desc = "Perfect for the Quartermaster on the go!"
icon_state = "cart-q"
ui_templates = list(
list("name" = "Supply Records", "template" = "supply_records.tmpl")
)
/obj/item/weapon/commcard/supply/New()
..()
internal_data["supply_category"] = null
internal_data["supply_controls"] = FALSE // Cannot control the supply shuttle, cannot accept orders
internal_data["supply_pack_expanded"] = list()
internal_data["supply_reqtime"] = -1
/obj/item/weapon/commcard/supply/get_data()
// Supply records data
var/list/shuttle_status = get_supply_shuttle_status()
var/list/orders = get_supply_orders()
var/list/receipts = get_supply_receipts()
var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge
var/list/pack_list = list() // List of supply packs within the currently selected category
if(internal_data["supply_category"])
pack_list = get_supply_pack_list()
return list(
list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"]),
list("field" = "order_auth", "value" = misc_supply_data["order_auth"]),
list("field" = "supply_points", "value" = misc_supply_data["supply_points"]),
list("field" = "categories", "value" = misc_supply_data["supply_categories"]),
list("field" = "contraband", "value" = misc_supply_data["contraband"]),
list("field" = "active_category", "value" = internal_data["supply_category"]),
list("field" = "shuttle", "value" = shuttle_status),
list("field" = "orders", "value" = orders),
list("field" = "receipts", "value" = receipts),
list("field" = "supply_packs", "value" = pack_list)
)
// Command Cartridge:
// Templates
// *- Status Display Access
// *- Employment Records
/obj/item/weapon/commcard/head
name = "\improper Easy-Record DELUXE"
icon_state = "cart-h"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl")
)
/obj/item/weapon/commcard/head/New()
..()
internal_data["stat_display_line1"] = null
internal_data["stat_display_line2"] = null
internal_data["stat_display_active1"] = null
internal_data["stat_display_active2"] = null
internal_data["stat_display_special"] = null
/obj/item/weapon/commcard/head/Initialize()
// Have to register the commcard with the Radio controller to receive updates to the status displays
radio_controller.add_object(src, 1435)
..()
/obj/item/weapon/commcard/head/Destroy()
// Have to unregister the commcard for proper bookkeeping
radio_controller.remove_object(src, 1435)
..()
/obj/item/weapon/commcard/head/get_data()
return list(
list("field" = "emp_records", "value" = get_emp_records()),
list("field" = "stat_display", "value" = get_status_display())
)
// Head of Personnel Cartridge:
// Templates
// *- Status Display Access
// *- Employment Records
// *- Security Records
// *- Supply Records
// ?- Supply Bot Access
// *- Janitorial Locator Magicbox
/obj/item/weapon/commcard/head/hop
name = "\improper HumanResources9001 cartridge"
icon_state = "cart-h"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl"),
list("name" = "Supply Records", "template" = "supply_records.tmpl"),
list("name" = "Janitorial Supply Locator", "template" = "janitorialLocator.tmpl")
)
/obj/item/weapon/commcard/head/hop/get_data()
var/list/data = ..()
// Sec records
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
// Supply records data
var/list/shuttle_status = get_supply_shuttle_status()
var/list/orders = get_supply_orders()
var/list/receipts = get_supply_receipts()
var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge
var/list/pack_list = list() // List of supply packs within the currently selected category
if(internal_data["supply_category"])
pack_list = get_supply_pack_list()
data[++data.len] = list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"])
data[++data.len] = list("field" = "order_auth", "value" = misc_supply_data["order_auth"])
data[++data.len] = list("field" = "supply_points", "value" = misc_supply_data["supply_points"])
data[++data.len] = list("field" = "categories", "value" = misc_supply_data["supply_categories"])
data[++data.len] = list("field" = "contraband", "value" = misc_supply_data["contraband"])
data[++data.len] = list("field" = "active_category", "value" = internal_data["supply_category"])
data[++data.len] = list("field" = "shuttle", "value" = shuttle_status)
data[++data.len] = list("field" = "orders", "value" = orders)
data[++data.len] = list("field" = "receipts", "value" = receipts)
data[++data.len] = list("field" = "supply_packs", "value" = pack_list)
// Janitorial locator magicbox
data[++data.len] = list("field" = "janidata", "value" = get_janitorial_locations())
return data
// Head of Security Cartridge:
// Templates
// *- Status Display Access
// *- Employment Records
// *- Security Records
// *- Security Bot Access
/obj/item/weapon/commcard/head/hos
name = "\improper R.O.B.U.S.T. DELUXE"
icon_state = "cart-hos"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl"),
list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl")
)
/obj/item/weapon/commcard/head/hos/get_data()
var/list/data = ..()
// Sec records
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
// Sec bot access
data[++data.len] = list("field" = "sec_bot_access", "value" = get_sec_bot_access())
return data
// Research Director Cartridge:
// Devices
// *- Signaler
// *- Gas Scanner
// *- Reagent Scanner
// Templates
// *- Status Display Access
// *- Employment Records
// *- Signaler Access
/obj/item/weapon/commcard/head/rd
name = "\improper Signal Ace DELUXE"
icon_state = "cart-rd"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Integrated Signaler Control", "template" = "signaler_access.tmpl")
)
/obj/item/weapon/commcard/head/rd/New()
..()
internal_devices |= new /obj/item/device/analyzer(src)
internal_devices |= new /obj/item/device/reagent_scanner(src)
internal_devices |= new /obj/item/device/assembly/signaler(src)
/obj/item/weapon/commcard/head/rd/get_data()
var/list/data = ..()
// Signaler access
data[++data.len] = list("field" = "signaler_access", "value" = get_int_signalers())
return data
// Chief Medical Officer Cartridge:
// Devices
// *- Health Analyzer
// *- Reagent Scanner
// *- Halogen Counter
// Templates
// *- Status Display Access
// *- Employment Records
// *- Medical Records
/obj/item/weapon/commcard/head/cmo
name = "\improper Med-U DELUXE"
icon_state = "cart-cmo"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Medical Records", "template" = "med_records.tmpl")
)
/obj/item/weapon/commcard/head/cmo/New()
..()
internal_devices |= new /obj/item/device/healthanalyzer(src)
internal_devices |= new /obj/item/device/reagent_scanner(src)
internal_devices |= new /obj/item/device/halogen_counter(src)
/obj/item/weapon/commcard/head/cmo/get_data()
var/list/data = ..()
// Med records
data[++data.len] = list("field" = "med_records", "value" = get_med_records())
return data
// Chief Engineer Cartridge:
// Devices
// *- Gas Scanner
// *- Halogen Counter
// Templates
// *- Status Display Access
// *- Employment Records
// *- Power Monitoring
/obj/item/weapon/commcard/head/ce
name = "\improper Power-On DELUXE"
icon_state = "cart-ce"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl")
)
/obj/item/weapon/commcard/head/ce/New()
..()
internal_devices |= new /obj.item/device/analyzer(src)
internal_devices |= new /obj/item/device/halogen_counter(src)
/obj/item/weapon/commcard/head/ce/Initialize()
internal_data["grid_sensors"] = find_powernet_sensors()
internal_data["powernet_target"] = ""
/obj/item/weapon/commcard/head/ce/get_data()
var/list/data = ..()
// Add power monitoring data
data[++data.len] = list("field" = "powernet_monitoring", "value" = get_powernet_monitoring_list())
data[++data.len] = list("field" = "powernet_target", "value" = get_powernet_target(internal_data["powernet_target"]))
return data
// Captain Cartridge:
// Devices
// *- Health analyzer
// *- Gas Scanner
// *- Reagent Scanner
// *- Halogen Counter
// X- GPS - Balance
// *- Signaler
// Templates
// *- Status Display Access
// *- Employment Records
// *- Medical Records
// *- Security Records
// *- Power Monitoring
// *- Supply Records
// X- Supply Bot Access - Mulebots usually break when used
// *- Security Bot Access
// *- Janitorial Locator Magicbox
// X- GPS Access - Balance
// *- Signaler Access
/obj/item/weapon/commcard/head/captain
name = "\improper Value-PAK cartridge"
desc = "Now with 200% more value!"
icon_state = "cart-c"
ui_templates = list(
list("name" = "Status Display Access", "template" = "stat_display_access.tmpl"),
list("name" = "Employment Records", "template" = "emp_records.tmpl"),
list("name" = "Medical Records", "template" = "med_records.tmpl"),
list("name" = "Security Records", "template" = "sec_records.tmpl"),
list("name" = "Security Bot Control", "template" = "sec_bot_access.tmpl"),
list("name" = "Power Monitor", "template" = "comm_power_monitor.tmpl"),
list("name" = "Supply Records", "template" = "supply_records.tmpl"),
list("name" = "Janitorial Supply Locator", "template" = "janitorialLocator.tmpl"),
list("name" = "Integrated Signaler Control", "template" = "signaler_access.tmpl")
)
/obj/item/weapon/commcard/head/captain/New()
..()
internal_devices |= new /obj.item/device/analyzer(src)
internal_devices |= new /obj/item/device/healthanalyzer(src)
internal_devices |= new /obj/item/device/reagent_scanner(src)
internal_devices |= new /obj/item/device/halogen_counter(src)
internal_devices |= new /obj/item/device/assembly/signaler(src)
/obj/item/weapon/commcard/head/captain/get_data()
var/list/data = ..()
//Med records
data[++data.len] = list("field" = "med_records", "value" = get_med_records())
// Sec records
data[++data.len] = list("field" = "sec_records", "value" = get_sec_records())
// Sec bot access
data[++data.len] = list("field" = "sec_bot_access", "value" = get_sec_bot_access())
// Power Monitoring
data[++data.len] = list("field" = "powernet_monitoring", "value" = get_powernet_monitoring_list())
data[++data.len] = list("field" = "powernet_target", "value" = get_powernet_target(internal_data["powernet_target"]))
// Supply records data
var/list/shuttle_status = get_supply_shuttle_status()
var/list/orders = get_supply_orders()
var/list/receipts = get_supply_receipts()
var/list/misc_supply_data = get_misc_supply_data() // Packaging this stuff externally so it's less hardcoded into the specific cartridge
var/list/pack_list = list() // List of supply packs within the currently selected category
if(internal_data["supply_category"])
pack_list = get_supply_pack_list()
data[++data.len] = list("field" = "shuttle_auth", "value" = misc_supply_data["shuttle_auth"])
data[++data.len] = list("field" = "order_auth", "value" = misc_supply_data["order_auth"])
data[++data.len] = list("field" = "supply_points", "value" = misc_supply_data["supply_points"])
data[++data.len] = list("field" = "categories", "value" = misc_supply_data["supply_categories"])
data[++data.len] = list("field" = "contraband", "value" = misc_supply_data["contraband"])
data[++data.len] = list("field" = "active_category", "value" = internal_data["supply_category"])
data[++data.len] = list("field" = "shuttle", "value" = shuttle_status)
data[++data.len] = list("field" = "orders", "value" = orders)
data[++data.len] = list("field" = "receipts", "value" = receipts)
data[++data.len] = list("field" = "supply_packs", "value" = pack_list)
// Janitorial locator magicbox
data[++data.len] = list("field" = "janidata", "value" = get_janitorial_locations())
// Signaler access
data[++data.len] = list("field" = "signaler_access", "value" = get_int_signalers())
return data
// Mercenary Cartridge
// Templates
// *- Merc Shuttle Door Controller
/obj/item/weapon/commcard/mercenary
name = "\improper Detomatix cartridge"
icon_state = "cart"
ui_templates = list(
list("name" = "Shuttle Blast Door Control", "template" = "merc_blast_door_control.tmpl")
)
/obj/item/weapon/commcard/mercenary/Initialize()
internal_data["shuttle_door_code"] = "smindicate" // Copied from PDA code
internal_data["shuttle_doors"] = find_blast_doors()
/obj/item/weapon/commcard/mercenary/get_data()
var/door_status[0]
for(var/obj/machinery/door/blast/B in internal_data["shuttle_doors"])
door_status[++door_status.len] += list(
"open" = B.density,
"name" = B.name,
"ref" = "\ref[B]"
)
return list(
list("field" = "blast_door", "value" = door_status)
)
// Explorer Cartridge
// Devices
// *- GPS
// Templates
// *- GPS Access
// IMPORTANT: NOT MAPPED IN DUE TO BALANCE CONCERNS RE: FINDING THE VICTIMS OF ANTAGS.
// See suit sensors, specifically ease of turning them off, and variable level of settings which may or may not give location
// A GPS in your phone that is either broadcasting position or totally off, and can be hidden in pockets, coats, bags, boxes, etc, is much harder to disable
/obj/item/weapon/commcard/explorer
name = "\improper Explorator cartridge"
icon_state = "cart-tox"
ui_templates = list(
list("name" = "Integrated GPS", "template" = "gps_access.tmpl")
)
/obj/item/weapon/commcard/explorer/New()
..()
internal_devices |= new /obj/item/device/gps/explorer(src)
/obj/item/weapon/commcard/explorer/get_data()
var/list/GPS = get_GPS_lists()
return list(
list("field" = "gps_access", "value" = GPS[1]),
list("field" = "gps_signal", "value" = GPS[2]),
list("field" = "gps_status", "value" = GPS[3])
)

View File

@@ -14,7 +14,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
#define WTHRTAB 7 #define WTHRTAB 7
#define MANITAB 8 #define MANITAB 8
#define SETTTAB 9 #define SETTTAB 9
#define EXTRTAB 10
/obj/item/device/communicator /obj/item/device/communicator
name = "communicator" name = "communicator"
@@ -43,19 +42,18 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
var/note = "Thank you for choosing the T-14.2 Communicator, this is your notepad!" //Current note in the notepad function var/note = "Thank you for choosing the T-14.2 Communicator, this is your notepad!" //Current note in the notepad function
var/notehtml = "" var/notehtml = ""
var/obj/item/weapon/commcard/cartridge = null //current cartridge
var/fon = 0 // Internal light var/fon = 0 // Internal light
var/flum = 2 // Brightness var/flum = 2 // Brightness
var/list/modules = list( var/list/modules = list(
list("module" = "Phone", "icon" = "phone64", "number" = PHONTAB), list("module" = "Phone", "icon" = "phone", "number" = PHONTAB),
list("module" = "Contacts", "icon" = "person64", "number" = CONTTAB), list("module" = "Contacts", "icon" = "user", "number" = CONTTAB),
list("module" = "Messaging", "icon" = "comment64", "number" = MESSTAB), list("module" = "Messaging", "icon" = "comment-alt", "number" = MESSTAB),
list("module" = "News", "icon" = "note64", "number" = NEWSTAB), // Need a different icon, list("module" = "News", "icon" = "newspaper", "number" = NEWSTAB), // Need a different icon,
list("module" = "Note", "icon" = "note64", "number" = NOTETAB), list("module" = "Note", "icon" = "sticky-note", "number" = NOTETAB),
list("module" = "Weather", "icon" = "sun64", "number" = WTHRTAB), list("module" = "Weather", "icon" = "sun", "number" = WTHRTAB),
list("module" = "Crew Manifest", "icon" = "note64", "number" = MANITAB), // Need a different icon, list("module" = "Crew Manifest", "icon" = "crown", "number" = MANITAB), // Need a different icon,
list("module" = "Settings", "icon" = "gear64", "number" = SETTTAB), list("module" = "Settings", "icon" = "cog", "number" = SETTTAB),
) //list("module" = "Name of Module", "icon" = "icon name64", "number" = "what tab is the module") ) //list("module" = "Name of Module", "icon" = "icon name64", "number" = "what tab is the module")
var/selected_tab = HOMETAB var/selected_tab = HOMETAB
@@ -104,13 +102,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
register_device(S.loc.name) register_device(S.loc.name)
initialize_exonet(S.loc) initialize_exonet(S.loc)
// Proc: examine()
// Parameters: user - the user doing the examining
// Description: Allows the user to click a link when examining to look at video if one is going.
/obj/item/device/communicator/examine(mob/user)
. = ..()
if(Adjacent(user) && video_source)
. += "<span class='notice'>It looks like it's on a video call: <a href='?src=\ref[src];watchvideo=1'>\[view\]</a></span>"
// Proc: initialize_exonet() // Proc: initialize_exonet()
// Parameters: 1 (user - the person the communicator belongs to) // Parameters: 1 (user - the person the communicator belongs to)
@@ -132,6 +123,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
// Description: Shows all the voice mobs inside the device, and their status. // Description: Shows all the voice mobs inside the device, and their status.
/obj/item/device/communicator/examine(mob/user) /obj/item/device/communicator/examine(mob/user)
. = ..() . = ..()
if(Adjacent(user) && video_source)
. += "<span class='notice'>It looks like it's on a video call: <a href='?src=\ref[src];watchvideo=1'>\[view\]</a></span>"
for(var/mob/living/voice/voice in contents) for(var/mob/living/voice/voice in contents)
. += "<span class='notice'>On the screen, you can see a image feed of [voice].</span>" . += "<span class='notice'>On the screen, you can see a image feed of [voice].</span>"
@@ -148,6 +142,17 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
else else
. += "<span class='notice'>The device doesn't appear to be transmitting any data.</span>" . += "<span class='notice'>The device doesn't appear to be transmitting any data.</span>"
// Proc: Topic()
// Parameters: href, href_list - Data from a link
// Description: Used by the above examine.
/obj/item/device/communicator/Topic(href, href_list)
if(..())
return 1
if(href_list["watchvideo"])
if(video_source)
watch_video(usr)
// Proc: emp_act() // Proc: emp_act()
// Parameters: None // Parameters: None
// Description: Drops all calls when EMPed, so the holder can then get murdered by the antagonist. // Description: Drops all calls when EMPed, so the holder can then get murdered by the antagonist.
@@ -203,17 +208,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
if(!get_connection_to_tcomms()) if(!get_connection_to_tcomms())
close_connection(reason = "Connection timed out") close_connection(reason = "Connection timed out")
// Proc: attack()
// Parameters: 2 (M - what is being attacked. user - the mob that has the communicator)
// Description: When the communicator has an attached commcard with internal devices, relay the attack() through to those devices.
// Contents of the for loop are copied from gripper code, because that does approximately what we want to do.
/obj/item/device/communicator/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(cartridge && cartridge.active_devices)
for(var/obj/item/wrapped in cartridge.active_devices)
if(wrapped) //The force of the wrapped obj gets set to zero during the attack() and afterattack().
wrapped.attack(M,user)
return 0
// Proc: attackby() // Proc: attackby()
// Parameters: 2 (C - what is used on the communicator. user - the mob that has the communicator) // Parameters: 2 (C - what is used on the communicator. user - the mob that has the communicator)
// Description: When an ID is swiped on the communicator, the communicator reads the job and checks it against the Owner name, if success, the occupation is added. // Description: When an ID is swiped on the communicator, the communicator reads the job and checks it against the Owner name, if success, the occupation is added.
@@ -229,13 +223,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
occupation = idcard.assignment occupation = idcard.assignment
to_chat(user, "<span class='notice'>Occupation updated.</span>") to_chat(user, "<span class='notice'>Occupation updated.</span>")
if(istype(C, /obj/item/weapon/commcard) && !cartridge)
cartridge = C
user.drop_item()
cartridge.forceMove(src)
to_chat(usr, "<span class='notice'>You slot \the [cartridge] into \the [src].</span>")
modules[++modules.len] = list("module" = "External Device", "icon" = "external64", "number" = EXTRTAB)
SSnanoui.update_uis(src) // update all UIs attached to src
return return
// Proc: attack_self() // Proc: attack_self()
@@ -246,7 +233,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
initialize_exonet(user) initialize_exonet(user)
alert_called = 0 alert_called = 0
update_icon() update_icon()
ui_interact(user) tgui_interact(user)
if(video_source) if(video_source)
watch_video(user) watch_video(user)
@@ -358,38 +345,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
client_huds |= global_hud.whitense client_huds |= global_hud.whitense
client_huds |= global_hud.darkMask client_huds |= global_hud.darkMask
/obj/item/device/communicator/verb/verb_remove_cartridge()
set category = "Object"
set name = "Remove commcard"
set src in usr
// Can't remove what isn't there
if(!cartridge)
to_chat(usr, "<span class='notice'>There isn't a commcard to remove!</span>")
return
// Can't remove if you're physically unable to
if(usr.stat || usr.restrained() || usr.paralysis || usr.stunned || usr.weakened)
to_chat(usr, "<span class='notice'>You cannot do this while restrained.</span>")
return
var/turf/T = get_turf(src)
cartridge.loc = T
// If it's in someone, put the cartridge in their hands
if (ismob(loc))
var/mob/M = loc
M.put_in_hands(cartridge)
// Else just set it on the ground
else
cartridge.loc = get_turf(src)
cartridge = null
// We have to iterate through the modules to find EXTRTAB, because list procs don't play nice with a list of lists
for(var/i = 1, i <= modules.len, i++)
if(modules[i]["number"] == EXTRTAB)
modules.Cut(i, i+1)
break
to_chat(usr, "<span class='notice'>You remove \the [cartridge] from the [name].</span>")
//It's the 26th century. We should have smart watches by now. //It's the 26th century. We should have smart watches by now.
/obj/item/device/communicator/watch /obj/item/device/communicator/watch
name = "communicator watch" name = "communicator watch"

View File

@@ -20,7 +20,7 @@
// Values were extracted from the template itself // Values were extracted from the template itself
results = list( results = list(
list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80), list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80),
list("entry" = "Temperature", "units" = "&degC", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5), list("entry" = "Temperature", "units" = "&deg;C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17), list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17),
list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40), list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40),
list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0), list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0),
@@ -44,19 +44,18 @@
var/index = 0 var/index = 0
for(var/datum/feed_message/FM in channel.messages) for(var/datum/feed_message/FM in channel.messages)
index++ index++
var/list/msgdata = list(
"author" = FM.author,
"body" = FM.body,
"img" = null,
"message_type" = FM.message_type,
"time_stamp" = FM.time_stamp,
"caption" = FM.caption,
"index" = index
)
if(FM.img) if(FM.img)
usr << browse_rsc(FM.img, "pda_news_tmp_photo_[feeds["channel"]]_[index].png") msgdata["img"] = icon2base64(FM.img)
// News stories are HTML-stripped but require newline replacement to be properly displayed in NanoUI messages[++messages.len] = msgdata
var/body = replacetext(FM.body, "\n", "<br>")
messages[++messages.len] = list(
"author" = FM.author,
"body" = body,
"message_type" = FM.message_type,
"time_stamp" = FM.time_stamp,
"has_image" = (FM.img != null),
"caption" = FM.caption,
"index" = index
)
feeds[++feeds.len] = list( feeds[++feeds.len] = list(
"name" = channel.channel_name, "name" = channel.channel_name,
@@ -96,448 +95,3 @@
news.Swap(1, 3) // List is sorted in ascending order of timestamp, we want descending news.Swap(1, 3) // List is sorted in ascending order of timestamp, we want descending
return news return news
// Putting the commcard data harvesting helpers here
// Not ideal to put all the procs on the base type
// but it may open options for adminbus,
// And it saves duplicated code
// Medical records
/obj/item/weapon/commcard/proc/get_med_records()
var/med_records[0]
for(var/datum/data/record/M in sortRecord(data_core.medical))
var/record[0]
record[++record.len] = list("tab" = "Name", "val" = M.fields["name"])
record[++record.len] = list("tab" = "ID", "val" = M.fields["id"])
record[++record.len] = list("tab" = "Blood Type", "val" = M.fields["b_type"])
record[++record.len] = list("tab" = "DNA #", "val" = M.fields["b_dna"])
record[++record.len] = list("tab" = "Gender", "val" = M.fields["id_gender"])
record[++record.len] = list("tab" = "Entity Classification", "val" = M.fields["brain_type"])
record[++record.len] = list("tab" = "Minor Disorders", "val" = M.fields["mi_dis"])
record[++record.len] = list("tab" = "Major Disorders", "val" = M.fields["ma_dis"])
record[++record.len] = list("tab" = "Allergies", "val" = M.fields["alg"])
record[++record.len] = list("tab" = "Condition", "val" = M.fields["cdi"])
record[++record.len] = list("tab" = "Notes", "val" = M.fields["notes"])
med_records[++med_records.len] = list("name" = M.fields["name"], "record" = record)
return med_records
// Employment records
/obj/item/weapon/commcard/proc/get_emp_records()
var/emp_records[0]
for(var/datum/data/record/G in sortRecord(data_core.general))
var/record[0]
record[++record.len] = list("tab" = "Name", "val" = G.fields["name"])
record[++record.len] = list("tab" = "ID", "val" = G.fields["id"])
record[++record.len] = list("tab" = "Rank", "val" = G.fields["rank"])
record[++record.len] = list("tab" = "Fingerprint", "val" = G.fields["fingerprint"])
record[++record.len] = list("tab" = "Entity Classification", "val" = G.fields["brain_type"])
record[++record.len] = list("tab" = "Sex", "val" = G.fields["sex"])
record[++record.len] = list("tab" = "Species", "val" = G.fields["species"])
record[++record.len] = list("tab" = "Age", "val" = G.fields["age"])
record[++record.len] = list("tab" = "Notes", "val" = G.fields["notes"])
emp_records[++emp_records.len] = list("name" = G.fields["name"], "record" = record)
return emp_records
// Security records
/obj/item/weapon/commcard/proc/get_sec_records()
var/sec_records[0]
for(var/datum/data/record/G in sortRecord(data_core.general))
var/record[0]
record[++record.len] = list("tab" = "Name", "val" = G.fields[""])
record[++record.len] = list("tab" = "Sex", "val" = G.fields[""])
record[++record.len] = list("tab" = "Species", "val" = G.fields[""])
record[++record.len] = list("tab" = "Age", "val" = G.fields[""])
record[++record.len] = list("tab" = "Rank", "val" = G.fields[""])
record[++record.len] = list("tab" = "Fingerprint", "val" = G.fields[""])
record[++record.len] = list("tab" = "Physical Status", "val" = G.fields[""])
record[++record.len] = list("tab" = "Mental Status", "val" = G.fields[""])
record[++record.len] = list("tab" = "Criminal Status", "val" = G.fields[""])
record[++record.len] = list("tab" = "Major Crimes", "val" = G.fields[""])
record[++record.len] = list("tab" = "Minor Crimes", "val" = G.fields[""])
record[++record.len] = list("tab" = "Notes", "val" = G.fields["notes"])
sec_records[++sec_records.len] = list("name" = G.fields["name"], "record" = record)
return sec_records
// Status of all secbots
// Weaker than what PDAs appear to do, but as of 7/1/2018 PDA secbot access is nonfunctional
/obj/item/weapon/commcard/proc/get_sec_bot_access()
var/sec_bots[0]
for(var/mob/living/bot/secbot/S in mob_list)
// Get new bot
var/status[0]
status[++status.len] = list("tab" = "Name", "val" = sanitize(S.name))
// If it's turned off, then it shouldn't be broadcasting any further info
if(!S.on)
status[++status.len] = list("tab" = "Power", "val" = "<span class='bad'>Off</span>") // Encoding the span classes here so I don't have to do complicated switches in the ui template
continue
status[++status.len] = list("tab" = "Power", "val" = "<span class='good'>On</span>")
// -- What it's doing
// If it's engaged, then say who it thinks it's engaging
if(S.target)
status[++status.len] = list("tab" = "Status", "val" = "<span class='bad'>Apprehending Target</span>")
status[++status.len] = list("tab" = "Target", "val" = S.target_name(S.target))
// Else if it's patrolling
else if(S.will_patrol)
status[++status.len] = list("tab" = "Status", "val" = "<span class='good'>Patrolling</span>")
// Otherwise we don't know what it's doing
else
status[++status.len] = list("tab" = "Status", "val" = "<span class='average'>Idle</span>")
// Where it is
status[++status.len] = list("tab" = "Location", "val" = sanitize("[get_area(S.loc)]"))
// Append bot to the list
sec_bots[++sec_bots.len] = list("bot" = S.name, "status" = status)
return sec_bots
// Code and frequency of stored signalers
// Supports multiple signalers within the device
/obj/item/weapon/commcard/proc/get_int_signalers()
var/signalers[0]
for(var/obj/item/device/assembly/signaler/S in internal_devices)
var/unit[0]
unit[++unit.len] = list("tab" = "Code", "val" = S.code)
unit[++unit.len] = list("tab" = "Frequency", "val" = S.frequency)
signalers[++signalers.len] = list("ref" = "\ref[S]", "status" = unit)
return signalers
// Returns list of all powernet sensors currently visible to the commcard
/obj/item/weapon/commcard/proc/find_powernet_sensors()
var/grid_sensors[0]
// Find all the powernet sensors we need to pull data from
// Copied from /datum/nano_module/power_monitor/proc/refresh_sensors(),
// located in '/code/modules/nano/modules/power_monitor.dm'
// Minor tweaks for efficiency and cleanliness
var/turf/T = get_turf(src)
if(T)
var/list/levels = using_map.get_map_levels(T.z, FALSE)
for(var/obj/machinery/power/sensor/S in machines)
if((S.long_range) || (S.loc.z in levels) || (S.loc.z == T.z)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels.
if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen!
warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z")
else
grid_sensors += S
return grid_sensors
// List of powernets
/obj/item/weapon/commcard/proc/get_powernet_monitoring_list()
// Fetch power monitor data
var/sensors[0]
for(var/obj/machinery/power/sensor/S in internal_data["grid_sensors"])
var/list/focus = S.return_reading_data()
sensors[++sensors.len] = list(
"name" = S.name_tag,
"alarm" = focus["alarm"]
)
return sensors
// Information about the targeted powernet
/obj/item/weapon/commcard/proc/get_powernet_target(var/target_sensor)
if(!target_sensor)
return
var/powernet_target[0]
for(var/obj/machinery/power/sensor/S in internal_data["grid_sensors"])
var/list/focus = S.return_reading_data()
// Packages the span class here so it doesn't need to be interpreted w/in the for loop in the ui template
var/load_stat = "<span class='good'>Optimal</span>"
if(focus["load_percentage"] >= 95)
load_stat = "<span class='bad'>DANGER: Overload</span>"
else if(focus["load_percentage"] >= 85)
load_stat = "<span class='average'>WARNING: High Load</span>"
var/alarm_stat = focus["alarm"] ? "<span class='bad'>WARNING: Abnormal activity detected!</span>" : "<span class='good'>Secure</span>"
if(target_sensor == S.name_tag)
powernet_target = list(
"name" = S.name_tag,
"alarm" = focus["alarm"],
"error" = focus["error"],
"apc_data" = focus["apc_data"],
"status" = list(
list("field" = "Network Load Status", "statval" = load_stat),
list("field" = "Network Security Status", "statval" = alarm_stat),
list("field" = "Load Percentage", "statval" = focus["load_percentage"]),
list("field" = "Available Power", "statval" = focus["total_avail"]),
list("field" = "APC Power Usage", "statval" = focus["total_used_apc"]),
list("field" = "Other Power Usage", "statval" = focus["total_used_other"]),
list("field" = "Total Usage", "statval" = focus["total_used_all"])
)
)
return powernet_target
// Compiles the locations of all janitorial paraphernalia, as used by janitorialLocator.tmpl
/obj/item/weapon/commcard/proc/get_janitorial_locations()
// Fetch janitorial locator
var/janidata[0]
var/list/cleaningList = list()
cleaningList += all_mops + all_mopbuckets + all_janitorial_carts
// User's location
var/turf/userloc = get_turf(src)
if(isturf(userloc))
janidata[++janidata.len] = list("field" = "Current Location", "val" = "<span class='good'>[userloc.x], [userloc.y], [using_map.get_zlevel_name(userloc.z)]</span>")
else
janidata[++janidata.len] = list("field" = "Current Location", "val" = "<span class='bad'>Unknown</span>")
return janidata // If the user isn't on a valid turf, then it shouldn't be able to find anything anyways
// Mops, mop buckets, janitorial carts.
for(var/obj/C in cleaningList)
var/turf/T = get_turf(C)
if(isturf(T) )//&& T.z in using_map.get_map_levels(userloc, FALSE))
if(T.z == userloc.z)
janidata[++janidata.len] = list("field" = apply_text_macros("\proper [C.name]"), "val" = "<span class='good'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>")
else
janidata[++janidata.len] = list("field" = apply_text_macros("\proper [C.name]"), "val" = "<span class='average'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>")
// Cleanbots
for(var/mob/living/bot/cleanbot/B in living_mob_list)
var/turf/T = get_turf(B)
if(isturf(T) )//&& T.z in using_map.get_map_levels(userloc, FALSE))
var/textout = ""
if(B.on)
textout += "Status: <span class='good'>Online</span><br>"
if(T.z == userloc.z)
textout += "<span class='good'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>"
else
textout += "<span class='average'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>"
else
textout += "Status: <span class='bad'>Offline</span>"
janidata[++janidata.len] = list("field" = "[B.name]", "val" = textout)
return janidata
// Compiles the three lists used by GPS_access.tmpl
// The contents of the three lists are inherently related, so separating them into different procs would be largely redundant
/obj/item/weapon/commcard/proc/get_GPS_lists()
// GPS Access
var/intgps[0] // Gps devices within the commcard -- Allow tag edits, turning on/off, etc
var/extgps[0] // Gps devices not inside the commcard -- Print locations if a gps is on
var/stagps[0] // Gps net status, location, whether it's on, if it's got long range
var/obj/item/device/gps/cumulative = new(src)
cumulative.tracking = FALSE
cumulative.local_mode = TRUE // Won't detect long-range signals automatically
cumulative.long_range = FALSE
var/list/toggled_gps = list() // List of GPS units that are turned off before display_list() is called
for(var/obj/item/device/gps/G in internal_devices)
var/gpsdata[0]
if(G.tracking && !G.emped)
cumulative.tracking = TRUE // Turn it on
if(G.long_range)
cumulative.long_range = TRUE // It can detect long-range
if(!G.local_mode)
cumulative.local_mode = FALSE // It is detecting long-range
gpsdata["ref"] = "\ref[G]"
gpsdata["tag"] = G.gps_tag
gpsdata["power"] = G.tracking
gpsdata["local_mode"] = G.local_mode
gpsdata["long_range"] = G.long_range
gpsdata["hide_signal"] = G.hide_signal
gpsdata["can_hide"] = G.can_hide_signal
intgps[++intgps.len] = gpsdata // Add it to the list
if(G.tracking)
G.tracking = FALSE // Disable the internal gps units so they don't show up in the report
toggled_gps += G
var/list/remote_gps = cumulative.display_list() // Fetch information for all units except the ones inside of this device
for(var/obj/item/device/gps/G in toggled_gps) // Reenable any internal GPS units
G.tracking = TRUE
stagps["enabled"] = cumulative.tracking
stagps["long_range_en"] = (cumulative.long_range && !cumulative.local_mode)
stagps["my_area_name"] = remote_gps["my_area_name"]
stagps["curr_x"] = remote_gps["curr_x"]
stagps["curr_y"] = remote_gps["curr_y"]
stagps["curr_z"] = remote_gps["curr_z"]
stagps["curr_z_name"] = remote_gps["curr_z_name"]
extgps = remote_gps["gps_list"] // Compiled by the GPS
qdel(cumulative) // Don't want spare GPS units building up in the contents
return list(
intgps,
extgps,
stagps
)
// Collects the current status of the supply shuttle
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
// code\game\machinery\computer\supply.dm, starting at line 55
/obj/item/weapon/commcard/proc/get_supply_shuttle_status()
var/shuttle_status[0]
var/datum/shuttle/autodock/ferry/supply/shuttle = SSsupply.shuttle
if(shuttle)
if(shuttle.has_arrive_time())
shuttle_status["location"] = "In transit"
shuttle_status["mode"] = SUP_SHUTTLE_TRANSIT
shuttle_status["time"] = shuttle.eta_minutes()
else
shuttle_status["time"] = 0
if(shuttle.at_station())
if(shuttle.shuttle_docking_controller)
switch(shuttle.shuttle_docking_controller.get_docking_status())
if("docked")
shuttle_status["location"] = "Docked"
shuttle_status["mode"] = SUP_SHUTTLE_DOCKED
if("undocked")
shuttle_status["location"] = "Undocked"
shuttle_status["mode"] = SUP_SHUTTLE_UNDOCKED
if("docking")
shuttle_status["location"] = "Docking"
shuttle_status["mode"] = SUP_SHUTTLE_DOCKING
shuttle_status["force"] = shuttle.can_force()
if("undocking")
shuttle_status["location"] = "Undocking"
shuttle_status["mode"] = SUP_SHUTTLE_UNDOCKING
shuttle_status["force"] = shuttle.can_force()
else
shuttle_status["location"] = "Station"
shuttle_status["mode"] = SUP_SHUTTLE_DOCKED
else
shuttle_status["location"] = "Away"
shuttle_status["mode"] = SUP_SHUTTLE_AWAY
if(shuttle.can_launch())
shuttle_status["launch"] = 1
else if(shuttle.can_cancel())
shuttle_status["launch"] = 2
else
shuttle_status["launch"] = 0
switch(shuttle.moving_status)
if(SHUTTLE_IDLE)
shuttle_status["engine"] = "Idle"
if(SHUTTLE_WARMUP)
shuttle_status["engine"] = "Warming up"
if(SHUTTLE_INTRANSIT)
shuttle_status["engine"] = "Engaged"
else
shuttle["mode"] = SUP_SHUTTLE_ERROR
return shuttle_status
// Compiles the list of supply orders
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
// code\game\machinery\computer\supply.dm, starting at line 130
/obj/item/weapon/commcard/proc/get_supply_orders()
var/orders[0]
for(var/datum/supply_order/S in SSsupply.order_history)
orders[++orders.len] = list(
"ref" = "\ref[S]",
"status" = S.status,
"entries" = list(
list("field" = "Supply Pack", "entry" = S.name),
list("field" = "Cost", "entry" = S.cost),
list("field" = "Index", "entry" = S.index),
list("field" = "Reason", "entry" = S.comment),
list("field" = "Ordered by", "entry" = S.ordered_by),
list("field" = "Ordered at", "entry" = S.ordered_at),
list("field" = "Approved by", "entry" = S.approved_by),
list("field" = "Approved at", "entry" = S.approved_at)
)
)
return orders
// Compiles the list of supply export receipts
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
// code\game\machinery\computer\supply.dm, starting at line 147
/obj/item/weapon/commcard/proc/get_supply_receipts()
var/receipts[0]
for(var/datum/exported_crate/E in SSsupply.exported_crates)
receipts[++receipts.len] = list(
"ref" = "\ref[E]",
"contents" = E.contents,
"error" = E.contents["error"],
"title" = list(
list("field" = "Name", "entry" = E.name),
list("field" = "Value", "entry" = E.value)
)
)
return receipts
// Compiles the list of supply packs for the category currently stored in internal_data["supply_category"]
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
// code\game\machinery\computer\supply.dm, starting at line 147
/obj/item/weapon/commcard/proc/get_supply_pack_list()
var/supply_packs[0]
for(var/pack_name in SSsupply.supply_pack)
var/datum/supply_pack/P = SSsupply.supply_pack[pack_name]
if(P.group == internal_data["supply_category"])
var/list/pack = list(
"name" = P.name,
"cost" = P.cost,
"contraband" = P.contraband,
"manifest" = uniquelist(P.manifest),
"random" = P.num_contained,
"expand" = 0,
"ref" = "\ref[P]"
)
if(P in internal_data["supply_pack_expanded"])
pack["expand"] = 1
supply_packs[++supply_packs.len] = pack
return supply_packs
// Compiles miscellaneous data and permissions used by the supply template
/obj/item/weapon/commcard/proc/get_misc_supply_data()
return list(
"shuttle_auth" = (internal_data["supply_controls"] & SUP_SEND_SHUTTLE),
"order_auth" = (internal_data["supply_controls"] & SUP_ACCEPT_ORDERS),
"supply_points" = SSsupply.points,
"supply_categories" = all_supply_groups
)
/obj/item/weapon/commcard/proc/get_status_display()
return list(
"line1" = internal_data["stat_display_line1"],
"line2" = internal_data["stat_display_line2"],
"active_line1" = internal_data["stat_display_active1"],
"active_line2" = internal_data["stat_display_active2"],
"active" = internal_data["stat_display_special"]
)
/obj/item/weapon/commcard/proc/find_blast_doors()
var/target_doors[0]
for(var/obj/machinery/door/blast/B in machines)
if(B.id == internal_data["shuttle_door_code"])
target_doors += B
return target_doors

View File

@@ -5,7 +5,7 @@
var/in_hack_mode = 0 var/in_hack_mode = 0
var/list/known_targets var/list/known_targets
var/list/supported_types var/list/supported_types
var/datum/topic_state/default/must_hack/hack_state var/datum/tgui_state/default/must_hack/hack_state
/obj/item/device/multitool/hacktool/New() /obj/item/device/multitool/hacktool/New()
..() ..()
@@ -30,7 +30,7 @@
else else
..() ..()
/obj/item/device/multitool/hacktool/resolve_attackby(atom/A, mob/user) /obj/item/device/multitool/hacktool/afterattack(atom/A, mob/user)
sanity_check() sanity_check()
if(!in_hack_mode) if(!in_hack_mode)
@@ -39,7 +39,8 @@
if(!attempt_hack(user, A)) if(!attempt_hack(user, A))
return 0 return 0
A.ui_interact(user, state = hack_state) // Note, if you ever want to expand supported_types, you must manually add the custom state argument to their tgui_interact
A.tgui_interact(user, custom_state = hack_state)
return 1 return 1
/obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target) /obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target)
@@ -83,18 +84,18 @@
/obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target) /obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target)
known_targets -= target known_targets -= target
/datum/topic_state/default/must_hack /datum/tgui_state/default/must_hack
var/obj/item/device/multitool/hacktool/hacktool var/obj/item/device/multitool/hacktool/hacktool
/datum/topic_state/default/must_hack/New(var/hacktool) /datum/tgui_state/default/must_hack/New(var/hacktool)
src.hacktool = hacktool src.hacktool = hacktool
..() ..()
/datum/topic_state/default/must_hack/Destroy() /datum/tgui_state/default/must_hack/Destroy()
hacktool = null hacktool = null
return ..() return ..()
/datum/topic_state/default/must_hack/can_use_topic(var/src_object, var/mob/user) /datum/tgui_state/default/must_hack/can_use_topic(src_object, mob/user)
if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets)) if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets))
return STATUS_CLOSE return STATUS_CLOSE
return ..() return ..()

View File

@@ -33,6 +33,24 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
QDEL_NULL(radio) QDEL_NULL(radio)
return ..() return ..()
/obj/item/device/paicard/attack_ghost(mob/observer/dead/user)
if(istype(user) && user.can_admin_interact())
switch(alert(user, "Would you like to become a pAI by force? (Admin)", "pAI Creation", "Yes", "No"))
if("Yes")
// Copied from paiController/Topic
var/mob/living/silicon/pai/pai = new(src)
pai.name = user.name
pai.real_name = pai.name
pai.key = user.key
setPersonality(pai)
looking_for_personality = FALSE
if(pai.mind)
update_antag_icons(pai.mind)
return ..()
/obj/item/device/paicard/attack_self(mob/user) /obj/item/device/paicard/attack_self(mob/user)
if (!in_range(src, user)) if (!in_range(src, user))
return return

View File

@@ -151,18 +151,10 @@ var/global/list/default_medbay_channels = list(
return tgui_interact(user) return tgui_interact(user)
/obj/item/device/radio/ui_interact(mob/user, ui_key, datum/nanoui/ui, force_open, datum/nano_ui/master_ui, datum/topic_state/state) /obj/item/device/radio/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
log_runtime(EXCEPTION("Warning: [user] attempted to call ui_interact on radio [src] [type]. This is deprecated. Please update the caller to tgui_interact."))
/obj/item/device/radio/Topic(href, href_list)
if(href_list["track"])
log_runtime(EXCEPTION("Warning: Topic() was improperly called on radio [src] [type], with the track href and \[[href] [json_encode(href_list)]]. Please update the caller to use tgui_act."))
. = ..()
/obj/item/device/radio/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
ui = new(user, src, "Radio", name) ui = new(user, src, "Radio", name, parent_ui)
ui.open() ui.open()
/obj/item/device/radio/tgui_data(mob/user) /obj/item/device/radio/tgui_data(mob/user)

View File

@@ -54,7 +54,7 @@
popup.set_content(jointext(dat,null)) popup.set_content(jointext(dat,null))
popup.open() popup.open()
/obj/item/device/tvcamera/Topic(bred, href_list, state = physical_state) /obj/item/device/tvcamera/Topic(bred, href_list, state = GLOB.tgui_physical_state)
if(..()) if(..())
return 1 return 1
if(href_list["channel"]) if(href_list["channel"])

View File

@@ -1,13 +1,23 @@
GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink) GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
// 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(hidden_uplink)
if(hidden_uplink.active)
hidden_uplink.trigger(user)
return TRUE
return FALSE
/obj/item/device/uplink /obj/item/device/uplink
var/welcome = "Welcome, Operative" // Welcoming menu message var/welcome = "Welcome, Operative" // Welcoming menu message
var/uses // Numbers of crystals var/uses // Numbers of crystals
var/list/ItemsCategory // List of categories with lists of items var/list/ItemsCategory // List of categories with lists of items
var/list/ItemsReference // List of references with an associated item var/list/ItemsReference // List of references with an associated item
var/list/nanoui_items // List of items for NanoUI use var/list/nanoui_items // List of items for NanoUI use
var/nanoui_menu = 0 // The current menu we are in
var/list/nanoui_data = new // Additional data for NanoUI use
var/faction = "" //Antag faction holder. var/faction = "" //Antag faction holder.
var/list/purchase_log = new var/list/purchase_log = new
@@ -17,9 +27,7 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
var/next_offer_time var/next_offer_time
var/datum/uplink_item/discount_item //The item to be discounted var/datum/uplink_item/discount_item //The item to be discounted
var/discount_amount //The amount as a percent the item will be discounted by var/discount_amount //The amount as a percent the item will be discounted by
var/compact_mode = FALSE
/obj/item/device/uplink/nano_host()
return loc
/obj/item/device/uplink/Initialize(var/mapload, var/datum/mind/owner = null, var/telecrystals = DEFAULT_TELECRYSTAL_AMOUNT) /obj/item/device/uplink/Initialize(var/mapload, var/datum/mind/owner = null, var/telecrystals = DEFAULT_TELECRYSTAL_AMOUNT)
. = ..() . = ..()
@@ -53,23 +61,20 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
name = "hidden uplink" name = "hidden uplink"
desc = "There is something wrong if you're examining this." desc = "There is something wrong if you're examining this."
var/active = 0 var/active = 0
var/datum/uplink_category/category = 0 // The current category we are in
var/exploit_id // Id of the current exploit record we are viewing var/exploit_id // Id of the current exploit record we are viewing
var/selected_cat
// The hidden uplink MUST be inside an obj/item's contents. // The hidden uplink MUST be inside an obj/item's contents.
/obj/item/device/uplink/hidden/Initialize() /obj/item/device/uplink/hidden/Initialize()
. = ..() . = ..()
if(!isitem(loc)) if(!isitem(loc))
return INITIALIZE_HINT_QDEL return INITIALIZE_HINT_QDEL
nanoui_data = list()
update_nano_data()
/obj/item/device/uplink/hidden/next_offer() /obj/item/device/uplink/hidden/next_offer()
discount_item = default_uplink_selection.get_random_item(INFINITY) discount_item = default_uplink_selection.get_random_item(INFINITY)
discount_amount = pick(90;0.9, 80;0.8, 70;0.7, 60;0.6, 50;0.5, 40;0.4, 30;0.3, 20;0.2, 10;0.1) discount_amount = pick(90;0.9, 80;0.8, 70;0.7, 60;0.6, 50;0.5, 40;0.4, 30;0.3, 20;0.2, 10;0.1)
update_nano_data()
SSnanoui.update_uis(src)
next_offer_time = world.time + offer_time next_offer_time = world.time + offer_time
SStgui.update_uis(src)
addtimer(CALLBACK(src, .proc/next_offer), offer_time) addtimer(CALLBACK(src, .proc/next_offer), offer_time)
// Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated. // Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated.
@@ -91,136 +96,137 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
return 1 return 1
return 0 return 0
/* // Legacy
NANO UI FOR UPLINK WOOP WOOP /obj/item/device/uplink/hidden/interact(mob/user)
*/ tgui_interact(user)
/obj/item/device/uplink/hidden/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/title = "Remote Uplink"
var/data[0]
uses = user.mind.tcrystals
if(ishuman(user))
var/mob/living/carbon/human/H = user
faction = H.antag_faction
data["welcome"] = welcome /*****************
data["crystals"] = uses * Uplink TGUI
data["menu"] = nanoui_menu *****************/
data += nanoui_data /obj/item/device/uplink/tgui_host()
return loc
// update the ui if it exists, returns null if no ui is passed/found /obj/item/device/uplink/hidden/tgui_state(mob/user)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) return GLOB.tgui_inventory_state
if (!ui) // No auto-refresh
ui = new(user, src, ui_key, "uplink.tmpl", title, 630, 700, state = inventory_state) /obj/item/device/uplink/hidden/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
data["menu"] = 0 if(!active)
ui.set_initial_data(data) toggle()
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Uplink", "Remote Uplink")
// This UI is only ever opened by one person,
// and never is updated outside of user input.
ui.set_autoupdate(FALSE)
ui.open() ui.open()
/obj/item/device/uplink/hidden/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
if(!user.mind)
return
// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button. var/list/data = ..()
/obj/item/device/uplink/hidden/interact(mob/user)
ui_interact(user)
/obj/item/device/uplink/hidden/CanUseTopic() data["telecrystals"] = uses
data["lockable"] = TRUE
data["compactMode"] = compact_mode
data["discount_name"] = discount_item ? discount_item.name : ""
data["discount_amount"] = (1-discount_amount)*100
data["offer_expiry"] = worldtime2stationtime(next_offer_time)
data["exploit"] = null
data["locked_records"] = null
if(exploit_id)
for(var/datum/data/record/L in data_core.locked)
if(L.fields["id"] == exploit_id)
data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value.
// We trade off being able to automatically add shit for more control over what gets passed to json
// and if it's sanitized for html.
data["exploit"]["nanoui_exploit_record"] = html_encode(L.fields["exploit_record"]) // Change stuff into html
data["exploit"]["nanoui_exploit_record"] = replacetext(data["exploit"]["nanoui_exploit_record"], "\n", "<br>") // change line breaks into <br>
data["exploit"]["name"] = html_encode(L.fields["name"])
data["exploit"]["sex"] = html_encode(L.fields["sex"])
data["exploit"]["age"] = html_encode(L.fields["age"])
data["exploit"]["species"] = html_encode(L.fields["species"])
data["exploit"]["rank"] = html_encode(L.fields["rank"])
data["exploit"]["home_system"] = html_encode(L.fields["home_system"])
data["exploit"]["citizenship"] = html_encode(L.fields["citizenship"])
data["exploit"]["faction"] = html_encode(L.fields["faction"])
data["exploit"]["religion"] = html_encode(L.fields["religion"])
data["exploit"]["fingerprint"] = html_encode(L.fields["fingerprint"])
if(L.fields["antagvis"] == ANTAG_KNOWN || (faction == L.fields["antagfac"] && (L.fields["antagvis"] == ANTAG_SHARED)))
data["exploit"]["antagfaction"] = html_encode(L.fields["antagfac"])
else
data["exploit"]["antagfaction"] = html_encode("None")
break
else
var/list/permanentData = list()
for(var/datum/data/record/L in sortRecord(data_core.locked))
permanentData.Add(list(list(
"name" = L.fields["name"],
"id" = L.fields["id"]
)))
data["locked_records"] = permanentData
return data
/obj/item/device/uplink/hidden/tgui_static_data(mob/user)
var/list/data = ..()
data["categories"] = list()
for(var/datum/uplink_category/category in uplink.categories)
if(category.can_view(src))
var/list/cat = list(
"name" = category.name,
"items" = (category == selected_cat ? list() : null)
)
for(var/datum/uplink_item/item in category.items)
if(!item.can_view(src))
continue
var/cost = item.cost(uses, src) || "???"
cat["items"] += list(list(
"name" = item.name,
"cost" = cost,
"desc" = item.description(),
"ref" = REF(item),
))
data["categories"] += list(cat)
return data
/obj/item/device/uplink/hidden/tgui_status(mob/user, datum/tgui_state/state)
if(!active) if(!active)
return STATUS_CLOSE return STATUS_CLOSE
return ..() return ..()
// The purchasing code. /obj/item/device/uplink/hidden/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
/obj/item/device/uplink/hidden/Topic(href, href_list)
if(..()) if(..())
return 1 return TRUE
var/mob/user = usr switch(action)
if(href_list["buy_item"]) if("buy")
var/datum/uplink_item/UI = (locate(href_list["buy_item"]) in uplink.items) var/datum/uplink_item/UI = (locate(params["ref"]) in uplink.items)
UI.buy(src, usr) UI.buy(src, usr)
else if(href_list["lock"]) return TRUE
toggle() if("lock")
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") toggle()
ui.close() SStgui.close_uis(src)
else if(href_list["return"]) if("select")
nanoui_menu = round(nanoui_menu/10) selected_cat = params["category"]
else if(href_list["menu"]) return TRUE
nanoui_menu = text2num(href_list["menu"]) if("compact_toggle")
if(href_list["id"]) compact_mode = !compact_mode
exploit_id = href_list["id"] return TRUE
else if(href_list["category"]) if("view_exploits")
category = locate(href_list["category"]) in uplink.categories exploit_id = params["id"]
return TRUE
update_nano_data()
return 1
/obj/item/device/uplink/hidden/proc/update_nano_data()
if(nanoui_menu == 0)
var/categories[0]
for(var/datum/uplink_category/category in uplink.categories)
if(category.can_view(src))
categories[++categories.len] = list("name" = category.name, "ref" = "\ref[category]")
nanoui_data["categories"] = categories
nanoui_data["discount_name"] = discount_item ? discount_item.name : ""
nanoui_data["discount_amount"] = (1-discount_amount)*100
nanoui_data["offer_expiry"] = worldtime2stationtime(next_offer_time)
if(category)
nanoui_data["current_category"] = category.name
var/items[0]
for(var/datum/uplink_item/item in category.items)
if(item.can_view(src))
var/cost = item.cost(uses, src)
if(!cost) cost = "???"
items[++items.len] = list("name" = item.name, "description" = replacetext(item.description(), "\n", "<br>"), "can_buy" = item.can_buy(src), "cost" = cost, "ref" = "\ref[item]")
nanoui_data["items"] = items
else if(nanoui_menu == 2)
var/permanentData[0]
for(var/datum/data/record/L in sortRecord(data_core.locked))
permanentData[++permanentData.len] = list(Name = L.fields["name"],"id" = L.fields["id"])
nanoui_data["exploit_records"] = permanentData
else if(nanoui_menu == 21)
nanoui_data["exploit_exists"] = 0
for(var/datum/data/record/L in data_core.locked)
if(L.fields["id"] == exploit_id)
nanoui_data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value.
// We trade off being able to automatically add shit for more control over what gets passed to json
// and if it's sanitized for html.
nanoui_data["exploit"]["nanoui_exploit_record"] = html_encode(L.fields["exploit_record"]) // Change stuff into html
nanoui_data["exploit"]["nanoui_exploit_record"] = replacetext(nanoui_data["exploit"]["nanoui_exploit_record"], "\n", "<br>") // change line breaks into <br>
nanoui_data["exploit"]["name"] = html_encode(L.fields["name"])
nanoui_data["exploit"]["sex"] = html_encode(L.fields["sex"])
nanoui_data["exploit"]["age"] = html_encode(L.fields["age"])
nanoui_data["exploit"]["species"] = html_encode(L.fields["species"])
nanoui_data["exploit"]["rank"] = html_encode(L.fields["rank"])
nanoui_data["exploit"]["home_system"] = html_encode(L.fields["home_system"])
nanoui_data["exploit"]["citizenship"] = html_encode(L.fields["citizenship"])
nanoui_data["exploit"]["faction"] = html_encode(L.fields["faction"])
nanoui_data["exploit"]["religion"] = html_encode(L.fields["religion"])
nanoui_data["exploit"]["fingerprint"] = html_encode(L.fields["fingerprint"])
if(L.fields["antagvis"] == ANTAG_KNOWN || (faction == L.fields["antagfac"] && (L.fields["antagvis"] == ANTAG_SHARED)))
nanoui_data["exploit"]["antagfaction"] = html_encode(L.fields["antagfac"])
else
nanoui_data["exploit"]["antagfaction"] = html_encode("None")
nanoui_data["exploit_exists"] = 1
break
// 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 // PRESET UPLINKS
// A collection of preset uplinks. // A collection of preset uplinks.
// //
// Includes normal radio uplink, multitool uplink, // Includes normal radio uplink, multitool uplink,
// implant uplink (not the implant tool) and a preset headset uplink. // implant uplink (not the implant tool) and a preset headset uplink.
/obj/item/device/radio/uplink/New(atom/loc, datum/mind/target_mind, telecrystals) /obj/item/device/radio/uplink/New(atom/loc, datum/mind/target_mind, telecrystals)
..(loc) ..(loc)
hidden_uplink = new(src, target_mind, telecrystals) hidden_uplink = new(src, target_mind, telecrystals)

View File

@@ -4,8 +4,8 @@
singular_name = "human skin piece" singular_name = "human skin piece"
icon_state = "sheet-hide" icon_state = "sheet-hide"
no_variants = FALSE no_variants = FALSE
drop_sound = 'sound/items/drop/cloth.ogg' drop_sound = 'sound/items/drop/leather.ogg'
pickup_sound = 'sound/items/pickup/cloth.ogg' pickup_sound = 'sound/items/pickup/leather.ogg'
/obj/item/stack/animalhide/human /obj/item/stack/animalhide/human
amount = 50 amount = 50

View File

@@ -66,63 +66,81 @@
else else
. += "There is enough charge for [get_amount()]." . += "There is enough charge for [get_amount()]."
/obj/item/stack/attack_self(mob/user as mob) /obj/item/stack/attack_self(mob/user)
list_recipes(user) tgui_interact(user)
/obj/item/stack/proc/list_recipes(mob/user as mob, recipes_sublist) /obj/item/stack/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
if (!recipes) ui = SStgui.try_update_ui(user, src, ui)
return if(!ui)
if (!src || get_amount() <= 0) ui = new(user, src, "Stack", name)
user << browse(null, "window=stack") ui.open()
user.set_machine(src) //for correct work of onclose
var/list/recipe_list = recipes
if (recipes_sublist && recipe_list[recipes_sublist] && istype(recipe_list[recipes_sublist], /datum/stack_recipe_list))
var/datum/stack_recipe_list/srl = recipe_list[recipes_sublist]
recipe_list = srl.recipes
var/t1 = text("<HTML><HEAD><title>Constructions from []</title></HEAD><body><TT>Amount Left: []<br>", src, src.get_amount())
for(var/i=1;i<=recipe_list.len,i++)
var/E = recipe_list[i]
if (isnull(E))
t1 += "<hr>"
continue
if (i>1 && !isnull(recipe_list[i-1])) /obj/item/stack/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
t1+="<br>" var/list/data = ..()
data["amount"] = get_amount()
if (istype(E, /datum/stack_recipe_list)) return data
var/datum/stack_recipe_list/srl = E
t1 += "<a href='?src=\ref[src];sublist=[i]'>[srl.title]</a>"
if (istype(E, /datum/stack_recipe)) /obj/item/stack/tgui_static_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/datum/stack_recipe/R = E var/list/data = ..()
var/max_multiplier = round(src.get_amount() / R.req_amount)
var/title as text
var/can_build = 1
can_build = can_build && (max_multiplier>0)
if (R.res_amount>1)
title+= "[R.res_amount]x [R.title]\s"
else
title+= "[R.title]"
title+= " ([R.req_amount] [src.singular_name]\s)"
if (can_build)
t1 += text("<A href='?src=\ref[src];sublist=[recipes_sublist];make=[i];multiplier=1'>[title]</A> ")
else
t1 += text("[]", title)
continue
if (R.max_res_amount>1 && max_multiplier>1)
max_multiplier = min(max_multiplier, round(R.max_res_amount/R.res_amount))
t1 += " |"
var/list/multipliers = list(5,10,25)
for (var/n in multipliers)
if (max_multiplier>=n)
t1 += " <A href='?src=\ref[src];make=[i];multiplier=[n]'>[n*R.res_amount]x</A>"
if (!(max_multiplier in multipliers))
t1 += " <A href='?src=\ref[src];make=[i];multiplier=[max_multiplier]'>[max_multiplier*R.res_amount]x</A>"
t1 += "</TT></body></HTML>" data["recipes"] = recursively_build_recipes(recipes)
user << browse(t1, "window=stack")
onclose(user, "stack") return data
return
/obj/item/stack/proc/recursively_build_recipes(list/recipe_to_iterate)
var/list/L = list()
for(var/recipe in recipe_to_iterate)
if(istype(recipe, /datum/stack_recipe_list))
var/datum/stack_recipe_list/R = recipe
L["[R.title]"] = recursively_build_recipes(R.recipes)
if(istype(recipe, /datum/stack_recipe))
var/datum/stack_recipe/R = recipe
L["[R.title]"] = build_recipe(R)
return L
/obj/item/stack/proc/build_recipe(datum/stack_recipe/R)
return list(
"res_amount" = R.res_amount,
"max_res_amount" = R.max_res_amount,
"req_amount" = R.req_amount,
"ref" = "\ref[R]",
)
/obj/item/stack/tgui_state(mob/user)
return GLOB.tgui_hands_state
/obj/item/stack/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("make")
if(get_amount() < 1)
qdel(src)
return
var/datum/stack_recipe/R = locate(params["ref"])
if(!is_valid_recipe(R, recipes)) //href exploit protection
return FALSE
var/multiplier = text2num(params["multiplier"])
if(!multiplier || (multiplier <= 0)) //href exploit protection
return
produce_recipe(R, multiplier, usr)
return TRUE
/obj/item/stack/proc/is_valid_recipe(datum/stack_recipe/R, list/recipe_list)
for(var/S in recipe_list)
if(S == R)
return TRUE
if(istype(S, /datum/stack_recipe_list))
var/datum/stack_recipe_list/L = S
if(is_valid_recipe(R, L.recipes))
return TRUE
return FALSE
/obj/item/stack/proc/produce_recipe(datum/stack_recipe/recipe, var/quantity, mob/user) /obj/item/stack/proc/produce_recipe(datum/stack_recipe/recipe, var/quantity, mob/user)
var/required = quantity*recipe.req_amount var/required = quantity*recipe.req_amount
@@ -177,35 +195,6 @@
else else
O.color = color O.color = color
/obj/item/stack/Topic(href, href_list)
..()
if ((usr.restrained() || usr.stat || usr.get_active_hand() != src))
return
if (href_list["sublist"] && !href_list["make"])
list_recipes(usr, text2num(href_list["sublist"]))
if (href_list["make"])
if (src.get_amount() < 1) qdel(src) //Never should happen
var/list/recipes_list = recipes
if (href_list["sublist"])
var/datum/stack_recipe_list/srl = recipes_list[text2num(href_list["sublist"])]
recipes_list = srl.recipes
var/datum/stack_recipe/R = recipes_list[text2num(href_list["make"])]
var/multiplier = text2num(href_list["multiplier"])
if (!multiplier || (multiplier <= 0)) //href exploit protection
return
src.produce_recipe(R, multiplier, usr)
if (src && usr.machine==src) //do not reopen closed window
spawn( 0 )
src.interact(usr)
return
return
//Return 1 if an immediate subsequent call to use() would succeed. //Return 1 if an immediate subsequent call to use() would succeed.
//Ensures that code dealing with stacks uses the same logic //Ensures that code dealing with stacks uses the same logic
/obj/item/stack/proc/can_use(var/used) /obj/item/stack/proc/can_use(var/used)

View File

@@ -0,0 +1,32 @@
/obj/item/stack/arcadeticket
name = "arcade tickets"
desc = "Wow! With enough of these, you could buy a bike! ...Pssh, yeah right."
singular_name = "arcade ticket"
icon_state = "arcade-ticket"
item_state = "tickets"
w_class = ITEMSIZE_TINY
max_amount = 30
/obj/item/stack/arcadeticket/New(loc, amount = null)
. = ..()
update_icon()
/obj/item/stack/arcadeticket/update_icon()
var/amount = get_amount()
switch(amount)
if(12 to INFINITY)
icon_state = "arcade-ticket_4"
if(6 to 12)
icon_state = "arcade-ticket_3"
if(2 to 6)
icon_state = "arcade-ticket_2"
else
icon_state = "arcade-ticket"
/obj/item/stack/arcadeticket/proc/pay_tickets()
amount -= 2
if(amount == 0)
qdel(src)
/obj/item/stack/arcadeticket/thirty
amount = 30

View File

@@ -126,11 +126,13 @@
name = "empty cup" name = "empty cup"
icon_state = "coffee_vended" icon_state = "coffee_vended"
drop_sound = 'sound/items/drop/papercup.ogg' drop_sound = 'sound/items/drop/papercup.ogg'
pickup_sound = 'sound/items/pickup/papercup.ogg'
/obj/item/trash/ramen /obj/item/trash/ramen
name = "cup ramen" name = "cup ramen"
icon_state = "ramen" icon_state = "ramen"
drop_sound = 'sound/items/drop/papercup.ogg' drop_sound = 'sound/items/drop/papercup.ogg'
pickup_sound = 'sound/items/pickup/papercup.ogg'
/obj/item/trash/tray /obj/item/trash/tray
name = "tray" name = "tray"
@@ -141,6 +143,8 @@
name = "candle" name = "candle"
icon = 'icons/obj/candle.dmi' icon = 'icons/obj/candle.dmi'
icon_state = "candle4" icon_state = "candle4"
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
/obj/item/trash/liquidfood /obj/item/trash/liquidfood
name = "\improper \"LiquidFood\" ration packet" name = "\improper \"LiquidFood\" ration packet"
@@ -162,18 +166,26 @@
/obj/item/trash/brownies /obj/item/trash/brownies
name = "brownie tray" name = "brownie tray"
icon_state = "brownies" icon_state = "brownies"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/snacktray /obj/item/trash/snacktray
name = "snacktray" name = "snacktray"
icon_state = "snacktray" icon_state = "snacktray"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/dipbowl /obj/item/trash/dipbowl
name = "dip bowl" name = "dip bowl"
icon_state = "dipbowl" icon_state = "dipbowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/chipbasket /obj/item/trash/chipbasket
name = "empty basket" name = "empty basket"
icon_state = "chipbasket_empty" icon_state = "chipbasket_empty"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/spitgum /obj/item/trash/spitgum
name = "old gum" name = "old gum"
@@ -181,12 +193,15 @@
icon = 'icons/obj/clothing/masks.dmi' icon = 'icons/obj/clothing/masks.dmi'
icon_state = "spit-gum" icon_state = "spit-gum"
drop_sound = 'sound/items/drop/flesh.ogg' drop_sound = 'sound/items/drop/flesh.ogg'
pickup_sound = 'sound/items/pickup/flesh.ogg'
/obj/item/trash/lollibutt /obj/item/trash/lollibutt
name = "lollipop stick" name = "lollipop stick"
desc = "A lollipop stick devoid of pop." desc = "A lollipop stick devoid of pop."
icon = 'icons/obj/clothing/masks.dmi' icon = 'icons/obj/clothing/masks.dmi'
icon_state = "pop-stick" icon_state = "pop-stick"
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
/obj/item/trash/spitwad /obj/item/trash/spitwad
name = "spit wad" name = "spit wad"
@@ -194,6 +209,7 @@
icon = 'icons/obj/clothing/masks.dmi' icon = 'icons/obj/clothing/masks.dmi'
icon_state = "spit-chew" icon_state = "spit-chew"
drop_sound = 'sound/items/drop/flesh.ogg' drop_sound = 'sound/items/drop/flesh.ogg'
pickup_sound = 'sound/items/pickup/flesh.ogg'
slot_flags = SLOT_EARS | SLOT_MASK slot_flags = SLOT_EARS | SLOT_MASK
/obj/item/trash/attack(mob/M as mob, mob/living/user as mob) /obj/item/trash/attack(mob/M as mob, mob/living/user as mob)

View File

@@ -0,0 +1,37 @@
// **For augment items that aren't subtypes of other things.**
/obj/item/weapon/melee/augment
name = "integrated item"
desc = "A surprisingly non-descript item, integrated into its user. You probably shouldn't be seeing this."
icon = 'icons/obj/surgery.dmi'
icon_state = "augment_box"
/obj/item/weapon/melee/augment/blade
name = "handblade"
desc = "A sleek-looking telescopic blade that fits inside the hand. Favored by infiltration specialists and assassins."
icon_state = "augment_handblade"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
w_class = ITEMSIZE_SMALL
force = 15
armor_penetration = 25
sharp = 1
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
defend_chance = 10
projectile_parry_chance = 5
hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/weapon/melee/augment/blade/arm
name = "armblade"
desc = "A sleek-looking cybernetic blade that cleaves through people like butter. Favored by psychopaths and assassins."
icon_state = "augment_armblade"
w_class = ITEMSIZE_HUGE
force = 30
armor_penetration = 15
edge = 1
pry = 1
defend_chance = 40
projectile_parry_chance = 20

View File

@@ -14,6 +14,8 @@
var/list/datum/autopsy_data_scanner/chemtraces = list() var/list/datum/autopsy_data_scanner/chemtraces = list()
var/target_name = null var/target_name = null
var/timeofdeath = null var/timeofdeath = null
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
/datum/autopsy_data_scanner /datum/autopsy_data_scanner
var/weapon = null // this is the DEFINITE weapon type that was used var/weapon = null // this is the DEFINITE weapon type that was used

View File

@@ -20,6 +20,8 @@
var/board_type = new /datum/frame/frame_types/computer var/board_type = new /datum/frame/frame_types/computer
var/list/req_components = null var/list/req_components = null
var/contain_parts = 1 var/contain_parts = 1
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
//Called when the circuitboard is used to contruct a new machine. //Called when the circuitboard is used to contruct a new machine.
/obj/item/weapon/circuitboard/proc/construct(var/obj/machinery/M) /obj/item/weapon/circuitboard/proc/construct(var/obj/machinery/M)

View File

@@ -110,10 +110,6 @@
update_icon() update_icon()
return return
if(istype(W, /obj/item/device/analyzer))
var/obj/item/device/analyzer/A = W
A.analyze_gases(src, user)
return
..() ..()
return return

View File

@@ -6,8 +6,11 @@
var/electronic_warfare = 1 var/electronic_warfare = 1
var/mob/registered_user = null var/mob/registered_user = null
var/datum/tgui_module/agentcard/agentcard_module
/obj/item/weapon/card/id/syndicate/Initialize() /obj/item/weapon/card/id/syndicate/Initialize()
. = ..() . = ..()
agentcard_module = new(src)
access = syndicate_access.Copy() access = syndicate_access.Copy()
/obj/item/weapon/card/id/syndicate/station_access/Initialize() /obj/item/weapon/card/id/syndicate/station_access/Initialize()
@@ -15,6 +18,7 @@
access |= get_all_station_access() access |= get_all_station_access()
/obj/item/weapon/card/id/syndicate/Destroy() /obj/item/weapon/card/id/syndicate/Destroy()
QDEL_NULL(agentcard_module)
unset_registered_user(registered_user) unset_registered_user(registered_user)
return ..() return ..()
@@ -36,33 +40,12 @@
if(registered_user == user) if(registered_user == user)
switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show")) switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show"))
if("Edit") if("Edit")
ui_interact(user) agentcard_module.tgui_interact(user)
if("Show") if("Show")
..() ..()
else else
..() ..()
/obj/item/weapon/card/id/syndicate/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
var/entries[0]
entries[++entries.len] = list("name" = "Age", "value" = age)
entries[++entries.len] = list("name" = "Appearance", "value" = "Set")
entries[++entries.len] = list("name" = "Assignment", "value" = assignment)
entries[++entries.len] = list("name" = "Blood Type", "value" = blood_type)
entries[++entries.len] = list("name" = "DNA Hash", "value" = dna_hash)
entries[++entries.len] = list("name" = "Fingerprint Hash", "value" = fingerprint_hash)
entries[++entries.len] = list("name" = "Name", "value" = registered_name)
entries[++entries.len] = list("name" = "Photo", "value" = "Update")
entries[++entries.len] = list("name" = "Sex", "value" = sex)
entries[++entries.len] = list("name" = "Factory Reset", "value" = "Use With Care")
data["electronic_warfare"] = electronic_warfare
data["entries"] = entries
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "agent_id_card.tmpl", "Fake ID", 600, 400)
ui.set_initial_data(data)
ui.open()
/obj/item/weapon/card/id/syndicate/proc/register_user(var/mob/user) /obj/item/weapon/card/id/syndicate/proc/register_user(var/mob/user)
if(!istype(user) || user == registered_user) if(!istype(user) || user == registered_user)
@@ -79,114 +62,6 @@
registered_user.unregister(OBSERVER_EVENT_DESTROY, src) registered_user.unregister(OBSERVER_EVENT_DESTROY, src)
registered_user = null registered_user = null
/obj/item/weapon/card/id/syndicate/CanUseTopic(mob/user)
if(user != registered_user)
return STATUS_CLOSE
return ..()
/obj/item/weapon/card/id/syndicate/Topic(href, href_list, var/datum/topic_state/state)
if(..())
return 1
var/user = usr
if(href_list["electronic_warfare"])
electronic_warfare = text2num(href_list["electronic_warfare"])
to_chat(user, "<span class='notice'>Electronic warfare [electronic_warfare ? "enabled" : "disabled"].</span>")
else if(href_list["set"])
switch(href_list["set"])
if("Age")
var/new_age = input(user,"What age would you like to put on this card?","Agent Card Age", age) as null|num
if(!isnull(new_age) && CanUseTopic(user, state))
if(new_age < 0)
age = initial(age)
else
age = new_age
to_chat(user, "<span class='notice'>Age has been set to '[age]'.</span>")
. = 1
if("Appearance")
var/datum/card_state/choice = input(user, "Select the appearance for this card.", "Agent Card Appearance") as null|anything in id_card_states()
if(choice && CanUseTopic(user, state))
src.icon_state = choice.icon_state
src.item_state = choice.item_state
to_chat(usr, "<span class='notice'>Appearance changed to [choice].</span>")
. = 1
if("Assignment")
var/new_job = sanitize(input(user,"What assignment would you like to put on this card?\nChanging assignment will not grant or remove any access levels.","Agent Card Assignment", assignment) as null|text)
if(!isnull(new_job) && CanUseTopic(user, state))
src.assignment = new_job
to_chat(user, "<span class='notice'>Occupation changed to '[new_job]'.</span>")
update_name()
. = 1
if("Blood Type")
var/default = blood_type
if(default == initial(blood_type) && ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna)
default = H.dna.b_type
var/new_blood_type = sanitize(input(user,"What blood type would you like to be written on this card?","Agent Card Blood Type",default) as null|text)
if(!isnull(new_blood_type) && CanUseTopic(user, state))
src.blood_type = new_blood_type
to_chat(user, "<span class='notice'>Blood type changed to '[new_blood_type]'.</span>")
. = 1
if("DNA Hash")
var/default = dna_hash
if(default == initial(dna_hash) && ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna)
default = H.dna.unique_enzymes
var/new_dna_hash = sanitize(input(user,"What DNA hash would you like to be written on this card?","Agent Card DNA Hash",default) as null|text)
if(!isnull(new_dna_hash) && CanUseTopic(user, state))
src.dna_hash = new_dna_hash
to_chat(user, "<span class='notice'>DNA hash changed to '[new_dna_hash]'.</span>")
. = 1
if("Fingerprint Hash")
var/default = fingerprint_hash
if(default == initial(fingerprint_hash) && ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna)
default = md5(H.dna.uni_identity)
var/new_fingerprint_hash = sanitize(input(user,"What fingerprint hash would you like to be written on this card?","Agent Card Fingerprint Hash",default) as null|text)
if(!isnull(new_fingerprint_hash) && CanUseTopic(user, state))
src.fingerprint_hash = new_fingerprint_hash
to_chat(user, "<span class='notice'>Fingerprint hash changed to '[new_fingerprint_hash]'.</span>")
. = 1
if("Name")
var/new_name = sanitizeName(input(user,"What name would you like to put on this card?","Agent Card Name", registered_name) as null|text)
if(!isnull(new_name) && CanUseTopic(user, state))
src.registered_name = new_name
update_name()
to_chat(user, "<span class='notice'>Name changed to '[new_name]'.</span>")
. = 1
if("Photo")
set_id_photo(user)
to_chat(user, "<span class='notice'>Photo changed.</span>")
. = 1
if("Sex")
var/new_sex = sanitize(input(user,"What sex would you like to put on this card?","Agent Card Sex", sex) as null|text)
if(!isnull(new_sex) && CanUseTopic(user, state))
src.sex = new_sex
to_chat(user, "<span class='notice'>Sex changed to '[new_sex]'.</span>")
. = 1
if("Factory Reset")
if(alert("This will factory reset the card, including access and owner. Continue?", "Factory Reset", "No", "Yes") == "Yes" && CanUseTopic(user, state))
age = initial(age)
access = syndicate_access.Copy()
assignment = initial(assignment)
blood_type = initial(blood_type)
dna_hash = initial(dna_hash)
electronic_warfare = initial(electronic_warfare)
fingerprint_hash = initial(fingerprint_hash)
icon_state = initial(icon_state)
name = initial(name)
registered_name = initial(registered_name)
unset_registered_user()
sex = initial(sex)
to_chat(user, "<span class='notice'>All information has been deleted from \the [src].</span>")
. = 1
// Always update the UI, or buttons will spin indefinitely
SSnanoui.update_uis(src)
/var/global/list/id_card_states /var/global/list/id_card_states
/proc/id_card_states() /proc/id_card_states()
if(!id_card_states) if(!id_card_states)

View File

@@ -169,6 +169,10 @@
organ_to_implant = /obj/item/organ/internal/augment/armmounted/hand/sword organ_to_implant = /obj/item/organ/internal/augment/armmounted/hand/sword
organ_display_name = "weapon augment" organ_display_name = "weapon augment"
/obj/item/weapon/implant/organ/limbaugment/wrist/blade
organ_to_implant = /obj/item/organ/internal/augment/armmounted/hand/blade
organ_display_name = "weapon augment"
// Fore-arm // Fore-arm
/obj/item/weapon/implant/organ/limbaugment/laser /obj/item/weapon/implant/organ/limbaugment/laser
organ_to_implant = /obj/item/organ/internal/augment/armmounted organ_to_implant = /obj/item/organ/internal/augment/armmounted
@@ -185,6 +189,10 @@
/obj/item/weapon/implant/organ/limbaugment/upperarm/surge /obj/item/weapon/implant/organ/limbaugment/upperarm/surge
organ_to_implant = /obj/item/organ/internal/augment/armmounted/shoulder/surge organ_to_implant = /obj/item/organ/internal/augment/armmounted/shoulder/surge
/obj/item/weapon/implant/organ/limbaugment/upperarm/blade
organ_to_implant = /obj/item/organ/internal/augment/armmounted/shoulder/blade
organ_display_name = "weapon augment"
/* /*
* Others * Others
*/ */

View File

@@ -279,3 +279,23 @@
src.imp = new /obj/item/weapon/implant/organ/pelvic( src ) src.imp = new /obj/item/weapon/implant/organ/pelvic( src )
..() ..()
return return
/obj/item/weapon/implantcase/armblade
name = "glass case - 'Armblade'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/armblade/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm/blade( src )
..()
return
/obj/item/weapon/implantcase/handblade
name = "glass case - 'Handblade'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/handblade/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/blade( src )
..()
return

View File

@@ -362,6 +362,8 @@
usr.client.screen -= W usr.client.screen -= W
W.dropped(usr) W.dropped(usr)
add_fingerprint(usr) add_fingerprint(usr)
if (use_sound)
playsound(src, src.use_sound, 50, 0, -5) //Something broke "add item to container" sounds, this is a hacky fix.
if(!prevent_warning) if(!prevent_warning)
for(var/mob/M in viewers(usr, null)) for(var/mob/M in viewers(usr, null))

View File

@@ -128,6 +128,12 @@
/obj/item/weapon/storage/box/syndie_kit/imp_aug/sprinter /obj/item/weapon/storage/box/syndie_kit/imp_aug/sprinter
case_type = /obj/item/weapon/implantcase/sprinter case_type = /obj/item/weapon/implantcase/sprinter
/obj/item/weapon/storage/box/syndie_kit/imp_aug/armblade
case_type = /obj/item/weapon/implantcase/armblade
/obj/item/weapon/storage/box/syndie_kit/imp_aug/handblade
case_type = /obj/item/weapon/implantcase/handblade
/obj/item/weapon/storage/box/syndie_kit/space /obj/item/weapon/storage/box/syndie_kit/space
name = "boxed space suit and helmet" name = "boxed space suit and helmet"

View File

@@ -42,9 +42,9 @@
slot_flags = SLOT_ID slot_flags = SLOT_ID
var/obj/item/weapon/card/id/front_id = null var/obj/item/weapon/card/id/front_id = null
drop_sound = 'sound/items/drop/cloth.ogg' drop_sound = 'sound/items/drop/leather.ogg'
pickup_sound = 'sound/items/pickup/cloth.ogg' pickup_sound = 'sound/items/pickup/leather.ogg'
/obj/item/weapon/storage/wallet/remove_from_storage(obj/item/W as obj, atom/new_location) /obj/item/weapon/storage/wallet/remove_from_storage(obj/item/W as obj, atom/new_location)
. = ..(W, new_location) . = ..(W, new_location)

View File

@@ -120,9 +120,6 @@ var/list/global/tank_gauge_cache = list()
if (istype(src.loc, /obj/item/assembly)) if (istype(src.loc, /obj/item/assembly))
icon = src.loc icon = src.loc
if ((istype(W, /obj/item/device/analyzer)) && get_dist(user, src) <= 1)
var/obj/item/device/analyzer/A = W
A.analyze_gases(src, user)
else if (istype(W,/obj/item/latexballon)) else if (istype(W,/obj/item/latexballon))
var/obj/item/latexballon/LB = W var/obj/item/latexballon/LB = W
LB.blow(src) LB.blow(src)

View File

@@ -42,7 +42,7 @@
old_turf.unregister_dangerous_object(src) old_turf.unregister_dangerous_object(src)
new_turf.register_dangerous_object(src) new_turf.register_dangerous_object(src)
/obj/Topic(href, href_list, var/datum/topic_state/state = default_state) /obj/Topic(href, href_list, var/datum/tgui_state/state = GLOB.tgui_default_state)
if(usr && ..()) if(usr && ..())
return 1 return 1
@@ -55,7 +55,7 @@
CouldNotUseTopic(usr) CouldNotUseTopic(usr)
return 1 return 1
/obj/CanUseTopic(var/mob/user, var/datum/topic_state/state = default_state) /obj/CanUseTopic(var/mob/user, var/datum/tgui_state/state = GLOB.tgui_default_state)
if(user.CanUseObjTopic(src)) if(user.CanUseObjTopic(src))
return ..() return ..()
to_chat(user, "<span class='danger'>[bicon(src)]Access Denied!</span>") to_chat(user, "<span class='danger'>[bicon(src)]Access Denied!</span>")
@@ -69,7 +69,7 @@
return 1 return 1
/obj/proc/CouldUseTopic(var/mob/user) /obj/proc/CouldUseTopic(var/mob/user)
var/atom/host = nano_host() var/atom/host = tgui_host()
host.add_hiddenprint(user) host.add_hiddenprint(user)
/obj/proc/CouldNotUseTopic(var/mob/user) /obj/proc/CouldNotUseTopic(var/mob/user)
@@ -135,7 +135,6 @@
in_use = 0 in_use = 0
/obj/attack_ghost(mob/user) /obj/attack_ghost(mob/user)
ui_interact(user)
tgui_interact(user) tgui_interact(user)
..() ..()

View File

@@ -153,6 +153,65 @@
prob(2);/obj/item/ammo_magazine/m9mmt, prob(2);/obj/item/ammo_magazine/m9mmt,
prob(6);/obj/item/ammo_magazine/m9mmt/rubber) prob(6);/obj/item/ammo_magazine/m9mmt/rubber)
/obj/random/grenade
name = "Random Grenade"
desc = "This is random thrown grenades (no C4/etc.)."
icon = 'icons/obj/grenade.dmi'
icon_state = "clusterbang_segment"
/obj/random/grenade/item_to_spawn()
return pick( prob(15);/obj/item/weapon/grenade/concussion,
prob(5);/obj/item/weapon/grenade/empgrenade,
prob(15);/obj/item/weapon/grenade/empgrenade/low_yield,
prob(5);/obj/item/weapon/grenade/chem_grenade/metalfoam,
prob(2);/obj/item/weapon/grenade/chem_grenade/incendiary,
prob(10);/obj/item/weapon/grenade/chem_grenade/antiweed,
prob(10);/obj/item/weapon/grenade/chem_grenade/cleaner,
prob(10);/obj/item/weapon/grenade/chem_grenade/teargas,
prob(5);/obj/item/weapon/grenade/explosive,
prob(10);/obj/item/weapon/grenade/explosive/mini,
prob(2);/obj/item/weapon/grenade/explosive/frag,
prob(15);/obj/item/weapon/grenade/flashbang,
prob(1);/obj/item/weapon/grenade/flashbang/clusterbang, //I can't not do this.
prob(15);/obj/item/weapon/grenade/shooter/rubber,
prob(10);/obj/item/weapon/grenade/shooter/energy/flash,
prob(15);/obj/item/weapon/grenade/smokebomb
)
/obj/random/grenade/less_lethal
name = "Random Security Grenade"
desc = "This is a random thrown grenade that shouldn't kill anyone."
icon = 'icons/obj/grenade.dmi'
icon_state = "clusterbang_segment"
/obj/random/grenade/less_lethal/item_to_spawn()
return pick( prob(20);/obj/item/weapon/grenade/concussion,
prob(15);/obj/item/weapon/grenade/empgrenade/low_yield,
prob(15);/obj/item/weapon/grenade/chem_grenade/metalfoam,
prob(20);/obj/item/weapon/grenade/chem_grenade/teargas,
prob(20);/obj/item/weapon/grenade/flashbang,
prob(1);/obj/item/weapon/grenade/flashbang/clusterbang, //I *still* can't not do this.
prob(15);/obj/item/weapon/grenade/shooter/rubber,
prob(10);/obj/item/weapon/grenade/shooter/energy/flash
)
/obj/random/grenade/box
name = "Random Grenade Box"
desc = "This is a random box of grenades. Not to be mistaken for a box of random grenades. Or a grenade of random boxes - but that would just be silly."
icon = 'icons/obj/grenade.dmi'
icon_state = "clusterbang_segment"
/obj/random/grenade/box/item_to_spawn()
return pick( prob(20);/obj/item/weapon/storage/box/flashbangs,
prob(10);/obj/item/weapon/storage/box/emps,
prob(20);/obj/item/weapon/storage/box/empslite,
prob(15);/obj/item/weapon/storage/box/smokes,
prob(5);/obj/item/weapon/storage/box/anti_photons,
prob(5);/obj/item/weapon/storage/box/frags,
prob(10);/obj/item/weapon/storage/box/metalfoam,
prob(15);/obj/item/weapon/storage/box/teargas
)
/obj/random/projectile/random /obj/random/projectile/random
name = "Random Projectile Weapon" name = "Random Projectile Weapon"
desc = "This is a random weapon." desc = "This is a random weapon."

View File

@@ -585,7 +585,7 @@
/obj/item/clothing/mask/breath, /obj/item/clothing/mask/breath,
/obj/structure/closet/crate/aether //AETHER AIRSUPPLY /obj/structure/closet/crate/aether //AETHER AIRSUPPLY
), ),
prob(10);list( prob(5);list(
/obj/random/multiple/voidsuit/vintage, /obj/random/multiple/voidsuit/vintage,
/obj/random/multiple/voidsuit/vintage, /obj/random/multiple/voidsuit/vintage,
/obj/random/tank, /obj/random/tank,
@@ -625,13 +625,20 @@
/obj/random/powercell, /obj/random/powercell,
/obj/structure/closet/crate/einstein //EINSTEIN BATTERYPACK /obj/structure/closet/crate/einstein //EINSTEIN BATTERYPACK
), ),
prob(10);list( prob(5);list(
/obj/item/weapon/circuitboard/smes, /obj/item/weapon/circuitboard/smes,
/obj/random/smes_coil, /obj/random/smes_coil,
/obj/random/smes_coil, /obj/random/smes_coil,
/obj/structure/closet/crate/focalpoint //FOCAL SMES /obj/structure/closet/crate/focalpoint //FOCAL SMES
), ),
prob(15);list( prob(10);list(
/obj/item/weapon/module/power_control,
/obj/item/stack/cable_coil,
/obj/item/frame/apc,
/obj/item/weapon/cell/apc,
/obj/structure/closet/crate/focalpoint //FOCAL APC
),
prob(5);list(
/obj/random/drinkbottle, /obj/random/drinkbottle,
/obj/random/drinkbottle, /obj/random/drinkbottle,
/obj/random/drinkbottle, /obj/random/drinkbottle,
@@ -640,7 +647,7 @@
/obj/random/cigarettes, /obj/random/cigarettes,
/obj/structure/closet/crate/gilthari //GILTHARI LUXURY /obj/structure/closet/crate/gilthari //GILTHARI LUXURY
), ),
prob(15);list( prob(10);list(
/obj/random/tech_supply/nofail, /obj/random/tech_supply/nofail,
/obj/random/tech_supply/component/nofail, /obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail, /obj/random/tech_supply/component/nofail,
@@ -655,7 +662,7 @@
/obj/random/multiple/ore_pile, /obj/random/multiple/ore_pile,
/obj/structure/closet/crate/grayson //GRAYSON ORES /obj/structure/closet/crate/grayson //GRAYSON ORES
), ),
prob(15);list( prob(10);list(
/obj/random/material/refined, /obj/random/material/refined,
/obj/random/material/refined, /obj/random/material/refined,
/obj/random/material/refined, /obj/random/material/refined,
@@ -671,24 +678,48 @@
/obj/item/weapon/cell/device/weapon, /obj/item/weapon/cell/device/weapon,
/obj/structure/closet/crate/secure/heph //HEPHAESTUS ENERGY /obj/structure/closet/crate/secure/heph //HEPHAESTUS ENERGY
), ),
prob(2);list( prob(1);list(
/obj/random/projectile/random, /obj/random/grenade/box,
/obj/random/projectile/random, /obj/random/grenade/box,
/obj/structure/closet/crate/secure/heph //HEPHAESTUS PROJECTILE /obj/structure/closet/crate/secure/heph //HEPHAESTUS GRENADES
), ),
prob(2);list( prob(2);list(
/obj/random/projectile/random,
/obj/random/projectile/random,
/obj/structure/closet/crate/secure/lawson //LAWSON PROJECTILE
),
prob(3);list(
/obj/random/grenade/less_lethal,
/obj/random/grenade/less_lethal,
/obj/random/grenade/less_lethal,
/obj/random/grenade/less_lethal,
/obj/structure/closet/crate/secure/nanotrasen //NTSEC CROWD GRENADES
),
prob(5);list(
/obj/random/multiple/voidsuit/security, /obj/random/multiple/voidsuit/security,
/obj/random/tank, /obj/random/tank,
/obj/item/clothing/mask/breath, /obj/item/clothing/mask/breath,
/obj/structure/closet/crate/secure/nanotrasen //NTSEC SUIT /obj/structure/closet/crate/secure/nanotrasen //NTSEC SUIT
), ),
prob(2);list( prob(5);list(
/obj/random/multiple/voidsuit/medical, /obj/random/multiple/voidsuit/medical,
/obj/random/tank, /obj/random/tank,
/obj/item/clothing/mask/breath, /obj/item/clothing/mask/breath,
/obj/structure/closet/crate/secure/veymed //VM SUIT /obj/structure/closet/crate/secure/veymed //VM SUIT
), ),
prob(5);list( prob(5);list(
/obj/random/multiple/voidsuit/mining,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/structure/closet/crate/grayson //GRAYSON SUIT
),
prob(5);list(
/obj/random/multiple/voidsuit/engineering,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/structure/closet/crate/xion //XION SUIT
),
prob(10);list(
/obj/random/firstaid, /obj/random/firstaid,
/obj/random/medical, /obj/random/medical,
/obj/random/medical, /obj/random/medical,
@@ -697,11 +728,13 @@
/obj/random/medical/lite, /obj/random/medical/lite,
/obj/structure/closet/crate/veymed //VM GRABBAG /obj/structure/closet/crate/veymed //VM GRABBAG
), ),
prob(5);list( prob(10);list(
/obj/random/firstaid, /obj/random/firstaid,
/obj/random/firstaid, /obj/random/firstaid,
/obj/random/firstaid, /obj/random/firstaid,
/obj/random/firstaid, /obj/random/firstaid,
/obj/random/unidentified_medicine/fresh_medicine,
/obj/random/unidentified_medicine/fresh_medicine,
/obj/structure/closet/crate/veymed //VM FAKS /obj/structure/closet/crate/veymed //VM FAKS
), ),
prob(10);list( prob(10);list(
@@ -726,19 +759,337 @@
/obj/random/medical/pillbottle, /obj/random/medical/pillbottle,
/obj/random/medical/pillbottle, /obj/random/medical/pillbottle,
/obj/random/medical/pillbottle, /obj/random/medical/pillbottle,
/obj/random/medical/pillbottle, /obj/random/unidentified_medicine/fresh_medicine,
/obj/random/unidentified_medicine/fresh_medicine,
/obj/structure/closet/crate/zenghu //ZENGHU PILLS /obj/structure/closet/crate/zenghu //ZENGHU PILLS
), ),
prob(10);list(
/obj/item/device/toner,
/obj/item/device/toner,
/obj/item/device/toner,
/obj/item/weapon/clipboard,
/obj/item/weapon/clipboard,
/obj/item/weapon/pen/red,
/obj/item/weapon/pen/blue,
/obj/item/weapon/pen/blue,
/obj/item/device/camera_film,
/obj/item/weapon/folder/blue,
/obj/item/weapon/folder/red,
/obj/item/weapon/folder/yellow,
/obj/item/weapon/hand_labeler,
/obj/item/weapon/tape_roll,
/obj/item/weapon/paper_bin,
/obj/item/sticky_pad/random,
/obj/structure/closet/crate/ummarcar //UMMARCAR OFFICE TRASH
),
prob(5);list(
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/structure/closet/crate/unathi //UNAJERKY
),
prob(10);list(
/obj/item/weapon/reagent_containers/glass/bucket,
/obj/item/weapon/mop,
/obj/item/clothing/under/rank/janitor,
/obj/item/weapon/cartridge/janitor,
/obj/item/clothing/gloves/black,
/obj/item/clothing/head/soft/purple,
/obj/item/weapon/storage/belt/janitor,
/obj/item/clothing/shoes/galoshes,
/obj/item/weapon/storage/bag/trash,
/obj/item/device/lightreplacer,
/obj/item/weapon/reagent_containers/spray/cleaner,
/obj/item/weapon/reagent_containers/glass/rag,
/obj/item/weapon/grenade/chem_grenade/cleaner,
/obj/item/weapon/grenade/chem_grenade/cleaner,
/obj/item/weapon/grenade/chem_grenade/cleaner,
/obj/structure/closet/crate/galaksi //GALAKSI JANITOR SUPPLIES
),
prob(5);list(
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/structure/closet/crate/allico //GUMMIES
),
prob(2);list( prob(2);list(
/obj/item/weapon/tank/phoron/pressurized,
/obj/item/weapon/tank/phoron/pressurized,
/obj/structure/closet/crate/secure/phoron //HQ FUEL TANKS
),
prob(1);list(
/obj/random/contraband/nofail, /obj/random/contraband/nofail,
/obj/random/contraband/nofail, /obj/random/contraband/nofail,
/obj/random/contraband/nofail, /obj/random/unidentified_medicine/combat_medicine,
/obj/random/unidentified_medicine/combat_medicine,
/obj/random/projectile/random, /obj/random/projectile/random,
/obj/random/projectile/random, /obj/random/projectile/random,
/obj/random/mre, /obj/random/mre,
/obj/random/mre, /obj/random/mre,
/obj/structure/closet/crate/secure/saare //SAARE GRAB BAG
),
prob(2);list(
/obj/random/grenade,
/obj/random/grenade,
/obj/random/grenade,
/obj/random/grenade,
/obj/random/grenade,
/obj/random/grenade,
/obj/structure/closet/crate/secure/saare //SAARE GRENADES
),
prob(1);list(
/obj/random/cash/big,
/obj/random/cash/big,
/obj/random/cash/big,
/obj/random/cash/huge,
/obj/random/cash/huge,
/obj/random/cash/huge,
/obj/structure/closet/crate/secure/saare //SAARE CASH CRATE
)
)
/obj/random/multiple/corp_crate/no_weapons
name = "random corporate crate (no weapons)"
desc = "A random corporate crate with thematic contents. No weapons."
icon = 'icons/obj/storage.dmi'
icon_state = "crate"
/obj/random/multiple/corp_crate/no_weapons/item_to_spawn()
return pick(
prob(10);list(
/obj/random/tank,
/obj/random/tank,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/item/clothing/mask/breath,
/obj/item/clothing/mask/breath,
/obj/structure/closet/crate/aether //AETHER AIRSUPPLY
),
prob(5);list(
/obj/random/multiple/voidsuit/vintage,
/obj/random/multiple/voidsuit/vintage,
/obj/random/tank,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/item/clothing/mask/breath,
/obj/structure/closet/crate/aether //AETHER OLDSUITS
),
prob(10);list(
/obj/random/mre, /obj/random/mre,
/obj/structure/closet/crate/secure/saare //SAARE GUNS /obj/random/mre,
/obj/random/mre,
/obj/random/mre,
/obj/random/mre,
/obj/structure/closet/crate/centauri //CENTAURI MRES
),
prob(10);list(
/obj/random/drinksoft,
/obj/random/drinksoft,
/obj/random/drinksoft,
/obj/random/drinksoft,
/obj/random/drinksoft,
/obj/structure/closet/crate/freezer/centauri //CENTAURI SODA
),
prob(10);list(
/obj/random/snack,
/obj/random/snack,
/obj/random/snack,
/obj/random/snack,
/obj/random/snack,
/obj/structure/closet/crate/freezer/centauri //CENTAURI SNACKS
),
prob(10);list(
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/structure/closet/crate/einstein //EINSTEIN BATTERYPACK
),
prob(5);list(
/obj/item/weapon/circuitboard/smes,
/obj/random/smes_coil,
/obj/random/smes_coil,
/obj/structure/closet/crate/focalpoint //FOCAL SMES
),
prob(10);list(
/obj/item/weapon/module/power_control,
/obj/item/stack/cable_coil,
/obj/item/frame/apc,
/obj/item/weapon/cell/apc,
/obj/structure/closet/crate/focalpoint //FOCAL APC
),
prob(5);list(
/obj/random/drinkbottle,
/obj/random/drinkbottle,
/obj/random/drinkbottle,
/obj/random/cigarettes,
/obj/random/cigarettes,
/obj/random/cigarettes,
/obj/structure/closet/crate/gilthari //GILTHARI LUXURY
),
prob(10);list(
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/structure/closet/crate/grayson //GRAYSON TECH
),
prob(15);list(
/obj/random/multiple/ore_pile,
/obj/random/multiple/ore_pile,
/obj/random/multiple/ore_pile,
/obj/random/multiple/ore_pile,
/obj/structure/closet/crate/grayson //GRAYSON ORES
),
prob(10);list(
/obj/random/material/refined,
/obj/random/material/refined,
/obj/random/material/refined,
/obj/random/material/refined,
/obj/structure/closet/crate/grayson //GRAYSON MATS
),
prob(5);list(
/obj/random/multiple/voidsuit/security,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/structure/closet/crate/secure/nanotrasen //NTSEC SUIT
),
prob(5);list(
/obj/random/multiple/voidsuit/medical,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/structure/closet/crate/secure/veymed //VM SUIT
),
prob(5);list(
/obj/random/multiple/voidsuit/mining,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/structure/closet/crate/grayson //GRAYSON SUIT
),
prob(5);list(
/obj/random/multiple/voidsuit/engineering,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/structure/closet/crate/xion //XION SUIT
),
prob(10);list(
/obj/random/firstaid,
/obj/random/medical,
/obj/random/medical,
/obj/random/medical,
/obj/random/medical/lite,
/obj/random/medical/lite,
/obj/structure/closet/crate/veymed //VM GRABBAG
),
prob(10);list(
/obj/random/firstaid,
/obj/random/firstaid,
/obj/random/firstaid,
/obj/random/firstaid,
/obj/random/unidentified_medicine/fresh_medicine,
/obj/random/unidentified_medicine/fresh_medicine,
/obj/structure/closet/crate/veymed //VM FAKS
),
prob(10);list(
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/structure/closet/crate/xion //XION SUPPLY
),
prob(10);list(
/obj/random/firstaid,
/obj/random/medical,
/obj/random/medical/pillbottle,
/obj/random/medical/pillbottle,
/obj/random/medical/lite,
/obj/random/medical/lite,
/obj/structure/closet/crate/zenghu //ZENGHU GRABBAG
),
prob(10);list(
/obj/random/medical/pillbottle,
/obj/random/medical/pillbottle,
/obj/random/medical/pillbottle,
/obj/random/medical/pillbottle,
/obj/random/unidentified_medicine/fresh_medicine,
/obj/random/unidentified_medicine/fresh_medicine,
/obj/structure/closet/crate/zenghu //ZENGHU PILLS
),
prob(10);list(
/obj/item/device/toner,
/obj/item/device/toner,
/obj/item/device/toner,
/obj/item/weapon/clipboard,
/obj/item/weapon/clipboard,
/obj/item/weapon/pen/red,
/obj/item/weapon/pen/blue,
/obj/item/weapon/pen/blue,
/obj/item/device/camera_film,
/obj/item/weapon/folder/blue,
/obj/item/weapon/folder/red,
/obj/item/weapon/folder/yellow,
/obj/item/weapon/hand_labeler,
/obj/item/weapon/tape_roll,
/obj/item/weapon/paper_bin,
/obj/item/sticky_pad/random,
/obj/structure/closet/crate/ummarcar //UMMARCAR OFFICE TRASH
),
prob(5);list(
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/item/weapon/reagent_containers/food/snacks/unajerky,
/obj/structure/closet/crate/unathi //UNAJERKY
),
prob(10);list(
/obj/item/weapon/reagent_containers/glass/bucket,
/obj/item/weapon/mop,
/obj/item/clothing/under/rank/janitor,
/obj/item/weapon/cartridge/janitor,
/obj/item/clothing/gloves/black,
/obj/item/clothing/head/soft/purple,
/obj/item/weapon/storage/belt/janitor,
/obj/item/clothing/shoes/galoshes,
/obj/item/weapon/storage/bag/trash,
/obj/item/device/lightreplacer,
/obj/item/weapon/reagent_containers/spray/cleaner,
/obj/item/weapon/reagent_containers/glass/rag,
/obj/item/weapon/grenade/chem_grenade/cleaner,
/obj/item/weapon/grenade/chem_grenade/cleaner,
/obj/item/weapon/grenade/chem_grenade/cleaner,
/obj/structure/closet/crate/galaksi //GALAKSI JANITOR SUPPLIES
),
prob(5);list(
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/item/weapon/reagent_containers/food/snacks/candy/gummy,
/obj/structure/closet/crate/allico //GUMMIES
),
prob(2);list(
/obj/item/weapon/tank/phoron/pressurized,
/obj/item/weapon/tank/phoron/pressurized,
/obj/structure/closet/crate/secure/phoron //HQ FUEL TANKS
), ),
prob(1);list( prob(1);list(
/obj/random/cash/big, /obj/random/cash/big,
@@ -849,6 +1200,100 @@
/obj/structure/closet/crate/large/secure/xion //XION TECH COMPS /obj/structure/closet/crate/large/secure/xion //XION TECH COMPS
) )
) )
/obj/random/multiple/large_corp_crate/no_weapons
name = "random large corporate crate (no weapons)"
desc = "A random large corporate crate with thematic contents. No weapons."
icon = 'icons/obj/storage.dmi'
icon_state = "largermetal"
/obj/random/multiple/large_corp_crate/no_weapons/item_to_spawn()
return pick(
prob(30);list(
/obj/random/multiple/voidsuit/vintage,
/obj/random/multiple/voidsuit/vintage,
/obj/random/tank,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/item/clothing/mask/breath,
/obj/random/multiple/voidsuit/vintage,
/obj/random/multiple/voidsuit/vintage,
/obj/random/tank,
/obj/random/tank,
/obj/item/clothing/mask/breath,
/obj/item/clothing/mask/breath,
/obj/structure/closet/crate/large/aether //AETHER SUITSBOX
),
prob(30);list(
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/random/powercell,
/obj/structure/closet/crate/large/einstein //EIN BATTERY MEGAPACK
),
prob(20);list(
/obj/item/weapon/circuitboard/smes,
/obj/item/weapon/circuitboard/smes,
/obj/random/smes_coil,
/obj/random/smes_coil,
/obj/random/smes_coil,
/obj/random/smes_coil,
/obj/random/smes_coil,
/obj/random/smes_coil,
/obj/structure/closet/crate/large/einstein //EIN SMESBOX
),
prob(20);list(
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/random/tech_supply/nofail,
/obj/structure/closet/crate/large/xion //XION TECH SUPPLY
),
prob(20);list(
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/random/tech_supply/component/nofail,
/obj/structure/closet/crate/large/secure/xion //XION TECH COMPS
)
)
//recursion crate!
/obj/random/multiple/random_size_crate
name = "random size corporate crate"
desc = "A random size corporate crate with thematic contents: prefers small crates."
icon = 'icons/obj/storage.dmi'
icon_state = "largermetal"
/obj/random/multiple/random_size_crate/item_to_spawn()
return pick(
prob(85);list(
/obj/random/multiple/corp_crate
),
prob(15);list(
/obj/random/multiple/large_corp_crate
)
)
/* /*
* Turf swappers. * Turf swappers.
*/ */

View File

@@ -0,0 +1,10 @@
/obj/random/empty_or_lootable_crate
name = "random crate"
desc = "Spawns a random crate which may or may not have contents. Sometimes spawns nothing."
icon = 'icons/obj/storage.dmi'
icon_state = "moneybag"
spawn_nothing_percentage = 20
/obj/random/empty_or_lootable_crate/item_to_spawn()
return pick(/obj/random/crate,
/obj/random/multiple/corp_crate)

View File

@@ -29,6 +29,10 @@
/obj/item/clothing/suit/space/void/engineering/alt, /obj/item/clothing/suit/space/void/engineering/alt,
/obj/item/clothing/head/helmet/space/void/engineering/alt /obj/item/clothing/head/helmet/space/void/engineering/alt
), ),
prob(5);list(
/obj/item/clothing/suit/space/void/engineering/hazmat,
/obj/item/clothing/head/helmet/space/void/engineering/hazmat
),
prob(5);list( prob(5);list(
/obj/item/clothing/suit/space/void/engineering/construction, /obj/item/clothing/suit/space/void/engineering/construction,
/obj/item/clothing/head/helmet/space/void/engineering/construction /obj/item/clothing/head/helmet/space/void/engineering/construction
@@ -109,7 +113,35 @@
) )
) )
/obj/random/multiple/voidsuit/engineering
name = "Random Engineering Voidsuit"
desc = "This is a random engineering voidsuit."
icon = 'icons/obj/clothing/spacesuits.dmi'
icon_state = "rig-engineering"
/obj/random/multiple/voidsuit/engineering/item_to_spawn()
return pick(
prob(35);list(
/obj/item/clothing/suit/space/void/engineering,
/obj/item/clothing/head/helmet/space/void/engineering
),
prob(5);list(
/obj/item/clothing/suit/space/void/engineering/alt,
/obj/item/clothing/head/helmet/space/void/engineering/alt
),
prob(15);list(
/obj/item/clothing/suit/space/void/engineering/hazmat,
/obj/item/clothing/head/helmet/space/void/engineering/hazmat
),
prob(15);list(
/obj/item/clothing/suit/space/void/engineering/construction,
/obj/item/clothing/head/helmet/space/void/engineering/construction
),
prob(5);list(
/obj/item/clothing/suit/space/void/engineering/salvage,
/obj/item/clothing/head/helmet/space/void/engineering/salvage
)
)
/obj/random/multiple/voidsuit/security /obj/random/multiple/voidsuit/security
name = "Random Security Voidsuit" name = "Random Security Voidsuit"

View File

@@ -16,8 +16,8 @@ LINEN BINS
throw_speed = 1 throw_speed = 1
throw_range = 2 throw_range = 2
w_class = ITEMSIZE_SMALL w_class = ITEMSIZE_SMALL
drop_sound = 'sound/items/drop/cloth.ogg' drop_sound = 'sound/items/drop/clothing.ogg'
pickup_sound = 'sound/items/pickup/cloth.ogg' pickup_sound = 'sound/items/pickup/clothing.ogg'
/obj/item/weapon/bedsheet/attack_self(mob/user as mob) /obj/item/weapon/bedsheet/attack_self(mob/user as mob)
user.drop_item() user.drop_item()

View File

@@ -20,8 +20,90 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
var/has_items = FALSE var/has_items = FALSE
var/dismantled = TRUE var/dismantled = TRUE
var/signs = 0 //maximum capacity hardcoded below var/signs = 0 //maximum capacity hardcoded below
var/list/tgui_icons = list()
var/static/list/equippable_item_whitelist
/obj/structure/janitorialcart/proc/equip_janicart_item(mob/user, obj/item/I)
if(!equippable_item_whitelist)
equippable_item_whitelist = typecacheof(list(
/obj/item/weapon/storage/bag/trash,
/obj/item/weapon/mop,
/obj/item/weapon/reagent_containers/spray,
/obj/item/device/lightreplacer,
/obj/item/clothing/suit/caution,
))
if(!is_type_in_typecache(I, equippable_item_whitelist))
to_chat(user, "<span class='warning'>There's no room in [src] for [I].</span>")
return FALSE
if(!user.unEquip(I, 0, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand.</span>")
return FALSE
if(istype(I, /obj/item/weapon/storage/bag/trash))
if(mybag)
to_chat(user, "<span class='warning'>[src] already has \an [I].</span>")
return FALSE
mybag = I
setTguiIcon("mybag", mybag)
else if(istype(I, /obj/item/weapon/mop))
if(mymop)
to_chat(user, "<span class='warning'>[src] already has \an [I].</span>")
return FALSE
mymop = I
setTguiIcon("mymop", mymop)
else if(istype(I, /obj/item/weapon/reagent_containers/spray))
if(myspray)
to_chat(user, "<span class='warning'>[src] already has \an [I].</span>")
return FALSE
myspray = I
setTguiIcon("myspray", myspray)
else if(istype(I, /obj/item/device/lightreplacer))
if(myreplacer)
to_chat(user, "<span class='warning'>[src] already has \an [I].</span>")
return FALSE
myreplacer = I
setTguiIcon("myreplacer", myreplacer)
else if(istype(I, /obj/item/clothing/suit/caution))
if(signs < 4)
signs++
setTguiIcon("signs", I)
else
to_chat(user, "<span class='notice'>[src] can't hold any more signs.</span>")
return FALSE
else
// This may look like duplicate code, but it's important that we don't call unEquip *and* warn the user if
// something horrible goes wrong. (this else is never supposed to happen)
to_chat(user, "<span class='warning'>There's no room in [src] for [I].</span>")
return FALSE
update_icon()
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
return TRUE
/obj/structure/janitorialcart/proc/setTguiIcon(key, atom/A)
if(!istype(A) || !key)
return
var/icon/F = getFlatIcon(A, defdir = SOUTH, no_anim = TRUE)
tgui_icons["[key]"] = "'data:image/png;base64,[icon2base64(F)]'"
SStgui.update_uis(src)
/obj/structure/janitorialcart/proc/nullTguiIcon(key)
if(!key)
return
tgui_icons.Remove(key)
SStgui.update_uis(src)
/obj/structure/janitorialcart/proc/clearTguiIcons()
tgui_icons.Cut()
SStgui.update_uis(src)
/obj/structure/janitorialcart/Destroy() /obj/structure/janitorialcart/Destroy()
QDEL_NULL(mybag) QDEL_NULL(mybag)
@@ -29,20 +111,22 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
QDEL_NULL(myspray) QDEL_NULL(myspray)
QDEL_NULL(myreplacer) QDEL_NULL(myreplacer)
QDEL_NULL(mybucket) QDEL_NULL(mybucket)
clearTguiIcons()
return ..() return ..()
/obj/structure/janitorialcart/examine(mob/user) /obj/structure/janitorialcart/examine(mob/user)
if(..(user, 1)) . = ..(user)
if (mybucket) if(istype(mybucket))
var/contains = mybucket.reagents.total_volume var/contains = mybucket.reagents.total_volume
to_chat(user, "\icon[src] The bucket contains [contains] unit\s of liquid!") . += "[bicon(src)] The bucket contains [contains] unit\s of liquid!"
else else
to_chat(user, "\icon[src] There is no bucket mounted on it!") . += "[bicon(src)] There is no bucket mounted on it!"
/obj/structure/janitorialcart/MouseDrop_T(atom/movable/O as mob|obj, mob/living/user as mob) /obj/structure/janitorialcart/MouseDrop_T(atom/movable/O as mob|obj, mob/living/user as mob)
if (istype(O, /obj/structure/mopbucket) && !mybucket) if (istype(O, /obj/structure/mopbucket) && !mybucket)
O.forceMove(src) O.forceMove(src)
mybucket = O mybucket = O
setTguiIcon("mybucket", mybucket)
to_chat(user, "You mount the [O] on the janicart.") to_chat(user, "You mount the [O] on the janicart.")
update_icon() update_icon()
else else
@@ -70,38 +154,19 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
return 1 return 1
else if(istype(I, /obj/item/weapon/reagent_containers/spray) && !myspray) else if(istype(I, /obj/item/weapon/reagent_containers/spray) && !myspray)
user.unEquip(I, 0, src) equip_janicart_item(user, I)
myspray = I
update_icon()
updateUsrDialog()
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
return 1 return 1
else if(istype(I, /obj/item/device/lightreplacer) && !myreplacer) else if(istype(I, /obj/item/device/lightreplacer) && !myreplacer)
user.unEquip(I, 0, src) equip_janicart_item(user, I)
myreplacer = I
update_icon()
updateUsrDialog()
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
return 1 return 1
else if(istype(I, /obj/item/weapon/storage/bag/trash) && !mybag) else if(istype(I, /obj/item/weapon/storage/bag/trash) && !mybag)
user.unEquip(I, 0, src) equip_janicart_item(user, I)
mybag = I
update_icon()
updateUsrDialog()
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
return 1 return 1
else if(istype(I, /obj/item/clothing/suit/caution)) else if(istype(I, /obj/item/clothing/suit/caution))
if(signs < 4) equip_janicart_item(user, I)
user.unEquip(I, 0, src)
signs++
update_icon()
updateUsrDialog()
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
else
to_chat(user, "<span class='notice'>[src] can't hold any more signs.</span>")
return 1 return 1
else if(mybag) else if(mybag)
@@ -124,16 +189,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
if(user.incapacitated() || !Adjacent(user)) return if(user.incapacitated() || !Adjacent(user)) return
var/obj/I = usr.get_active_hand() var/obj/I = usr.get_active_hand()
if(istype(I, /obj/item/weapon/mop)) if(istype(I, /obj/item/weapon/mop))
if(!mymop) equip_janicart_item(user, I)
usr.drop_from_inventory(I,src)
mymop = I
update_icon()
updateUsrDialog()
to_chat(usr, "<span class='notice'>You put [I] into [src].</span>")
update_icon()
else
to_chat(usr, "<span class='notice'>The cart already has a mop attached</span>")
return
else if(istype(I, /obj/item/weapon/reagent_containers) && mybucket) else if(istype(I, /obj/item/weapon/reagent_containers) && mybucket)
var/obj/item/weapon/reagent_containers/C = I var/obj/item/weapon/reagent_containers/C = I
C.afterattack(mybucket, usr, 1) C.afterattack(mybucket, usr, 1)
@@ -141,75 +197,95 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
/obj/structure/janitorialcart/attack_hand(mob/user) /obj/structure/janitorialcart/attack_hand(mob/user)
ui_interact(user) tgui_interact(user)
return return
/obj/structure/janitorialcart/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = TRUE) /obj/structure/janitorialcart/tgui_interact(mob/user, datum/tgui/ui)
var/data[0] ui = SStgui.try_update_ui(user, src, ui)
data["name"] = capitalize(name)
data["bag"] = mybag ? capitalize(mybag.name) : null
data["bucket"] = mybucket ? capitalize(mybucket.name) : null
data["mop"] = mymop ? capitalize(mymop.name) : null
data["spray"] = myspray ? capitalize(myspray.name) : null
data["replacer"] = myreplacer ? capitalize(myreplacer.name) : null
data["signs"] = signs ? "[signs] sign\s" : null
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "janitorcart.tmpl", "Janitorial cart", 240, 160) ui = new(user, src, "JanitorCart", name) // 240, 160
ui.set_initial_data(data) ui.set_autoupdate(FALSE)
ui.open() ui.open()
/obj/structure/janitorialcart/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
/obj/structure/janitorialcart/Topic(href, href_list) data["mybag"] = mybag ? capitalize(mybag.name) : null
if(!in_range(src, usr)) data["mybucket"] = mybucket ? capitalize(mybucket.name) : null
return data["mymop"] = mymop ? capitalize(mymop.name) : null
if(!isliving(usr)) data["myspray"] = myspray ? capitalize(myspray.name) : null
return data["myreplacer"] = myreplacer ? capitalize(myreplacer.name) : null
var/mob/living/user = usr data["signs"] = signs ? "[signs] sign\s" : null
if(href_list["take"]) data["icons"] = tgui_icons
switch(href_list["take"]) return data
if("garbage")
if(mybag) /obj/structure/janitorialcart/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
user.put_in_hands(mybag) if(..())
to_chat(user, "<span class='notice'>You take [mybag] from [src].</span>") return TRUE
mybag = null
if("mop") var/obj/item/I = usr.get_active_hand()
if(mymop)
user.put_in_hands(mymop) switch(action)
to_chat(user, "<span class='notice'>You take [mymop] from [src].</span>") if("bag")
mymop = null if(mybag)
if("spray") usr.put_in_hands(mybag)
if(myspray) to_chat(usr, "<span class='notice'>You take [mybag] from [src].</span>")
user.put_in_hands(myspray) mybag = null
to_chat(user, "<span class='notice'>You take [myspray] from [src].</span>") nullTguiIcon("mybag")
myspray = null else if(is_type_in_typecache(I, equippable_item_whitelist))
if("replacer") equip_janicart_item(usr, I)
if(myreplacer) if("mop")
user.put_in_hands(myreplacer) if(mymop)
to_chat(user, "<span class='notice'>You take [myreplacer] from [src].</span>") usr.put_in_hands(mymop)
myreplacer = null to_chat(usr, "<span class='notice'>You take [mymop] from [src].</span>")
if("sign") mymop = null
if(signs) nullTguiIcon("mymop")
var/obj/item/clothing/suit/caution/Sign = locate() in src else if(is_type_in_typecache(I, equippable_item_whitelist))
if(Sign) equip_janicart_item(usr, I)
user.put_in_hands(Sign) if("spray")
to_chat(user, "<span class='notice'>You take \a [Sign] from [src].</span>") if(myspray)
signs-- usr.put_in_hands(myspray)
else to_chat(usr, "<span class='notice'>You take [myspray] from [src].</span>")
warning("[src] signs ([signs]) didn't match contents") myspray = null
signs = 0 nullTguiIcon("myspray")
if("bucket") else if(is_type_in_typecache(I, equippable_item_whitelist))
if(mybucket) equip_janicart_item(usr, I)
mybucket.forceMove(get_turf(user)) if("replacer")
to_chat(user, "<span class='notice'>You unmount [mybucket] from [src].</span>") if(myreplacer)
mybucket = null usr.put_in_hands(myreplacer)
to_chat(usr, "<span class='notice'>You take [myreplacer] from [src].</span>")
myreplacer = null
nullTguiIcon("myreplacer")
else if(is_type_in_typecache(I, equippable_item_whitelist))
equip_janicart_item(usr, I)
if("sign")
if(istype(I, /obj/item/clothing/suit/caution) && signs < 4)
equip_janicart_item(usr, I)
else if(signs)
var/obj/item/clothing/suit/caution/sign = locate() in src
if(sign)
usr.put_in_hands(sign)
to_chat(usr, "<span class='notice'>You take \a [sign] from [src].</span>")
signs--
if(!signs)
nullTguiIcon("signs")
else
to_chat(usr, "<span class='notice'>[src] doesn't have any signs left.</span>")
if("bucket")
if(mybucket)
mybucket.forceMove(get_turf(usr))
to_chat(usr, "<span class='notice'>You unmount [mybucket] from [src].</span>")
mybucket = null
nullTguiIcon("mybucket")
else
to_chat(usr, "<span class='notice'>((Drag and drop a mop bucket onto [src] to equip it.))</span>")
return FALSE
else
return FALSE
update_icon() update_icon()
updateUsrDialog() return TRUE
/obj/structure/janitorialcart/update_icon() /obj/structure/janitorialcart/update_icon()
overlays.Cut() overlays.Cut()
@@ -229,11 +305,6 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
if(signs) if(signs)
overlays += "cart_sign[signs]" overlays += "cart_sign[signs]"
//This is called if the cart is caught in an explosion, or destroyed by weapon fire //This is called if the cart is caught in an explosion, or destroyed by weapon fire
/obj/structure/janitorialcart/proc/spill(var/chance = 100) /obj/structure/janitorialcart/proc/spill(var/chance = 100)
var/turf/dropspot = get_turf(src) var/turf/dropspot = get_turf(src)
@@ -275,6 +346,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
mybag = null mybag = null
update_icon() update_icon()
clearTguiIcons()

View File

@@ -172,7 +172,7 @@ obj/structure/safe/ex_act(severity)
icon_state = "floorsafe" icon_state = "floorsafe"
density = 0 density = 0
level = 1 //underfloor level = 1 //underfloor
plane = TURF_PLANE plane = PLATING_PLANE
layer = ABOVE_UTILITY layer = ABOVE_UTILITY
/obj/structure/safe/floor/Initialize() /obj/structure/safe/floor/Initialize()

View File

@@ -67,7 +67,7 @@
if(!UWC) if(!UWC)
return return
var/datum/category_item/underwear/selected_underwear = input(H, "Choose underwear:", "Choose underwear", H.all_underwear[UWC.name]) as null|anything in UWC.items var/datum/category_item/underwear/selected_underwear = input(H, "Choose underwear:", "Choose underwear", H.all_underwear[UWC.name]) as null|anything in UWC.items
if(selected_underwear && CanUseTopic(H, default_state)) if(selected_underwear && CanUseTopic(H, GLOB.tgui_default_state))
H.all_underwear[UWC.name] = selected_underwear H.all_underwear[UWC.name] = selected_underwear
H.hide_underwear[UWC.name] = FALSE H.hide_underwear[UWC.name] = FALSE
. = TRUE . = TRUE

View File

@@ -36,6 +36,8 @@
continue continue
if(!SM.Adjacent(user) || !SM.Adjacent(target)) // Cleaving only hits mobs near the target mob and user. if(!SM.Adjacent(user) || !SM.Adjacent(target)) // Cleaving only hits mobs near the target mob and user.
continue continue
if(!attack_can_reach(user, SM, 1))
continue
if(resolve_attackby(SM, user, attack_modifier = 0.5)) // Hit them with the weapon. This won't cause recursive cleaving due to the cleaving variable being set to true. if(resolve_attackby(SM, user, attack_modifier = 0.5)) // Hit them with the weapon. This won't cause recursive cleaving due to the cleaving variable being set to true.
hit_mobs++ hit_mobs++

View File

@@ -266,6 +266,15 @@
soundin = pick('sound/machines/sm/accent/normal/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg', 'sound/machines/sm/supermatter1.ogg', 'sound/machines/sm/supermatter2.ogg', 'sound/machines/sm/supermatter3.ogg') soundin = pick('sound/machines/sm/accent/normal/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg', 'sound/machines/sm/supermatter1.ogg', 'sound/machines/sm/supermatter2.ogg', 'sound/machines/sm/supermatter3.ogg')
if("smdelam") if("smdelam")
soundin = pick('sound/machines/sm/accent/delam/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg', 'sound/machines/sm/supermatter1.ogg', 'sound/machines/sm/supermatter2.ogg', 'sound/machines/sm/supermatter3.ogg') soundin = pick('sound/machines/sm/accent/delam/1.ogg', 'sound/machines/sm/accent/normal/2.ogg', 'sound/machines/sm/accent/normal/3.ogg', 'sound/machines/sm/accent/normal/4.ogg', 'sound/machines/sm/accent/normal/5.ogg', 'sound/machines/sm/accent/normal/6.ogg', 'sound/machines/sm/accent/normal/7.ogg', 'sound/machines/sm/accent/normal/8.ogg', 'sound/machines/sm/accent/normal/9.ogg', 'sound/machines/sm/accent/normal/10.ogg', 'sound/machines/sm/accent/normal/11.ogg', 'sound/machines/sm/accent/normal/12.ogg', 'sound/machines/sm/accent/normal/13.ogg', 'sound/machines/sm/accent/normal/14.ogg', 'sound/machines/sm/accent/normal/15.ogg', 'sound/machines/sm/accent/normal/16.ogg', 'sound/machines/sm/accent/normal/17.ogg', 'sound/machines/sm/accent/normal/18.ogg', 'sound/machines/sm/accent/normal/19.ogg', 'sound/machines/sm/accent/normal/20.ogg', 'sound/machines/sm/accent/normal/21.ogg', 'sound/machines/sm/accent/normal/22.ogg', 'sound/machines/sm/accent/normal/23.ogg', 'sound/machines/sm/accent/normal/24.ogg', 'sound/machines/sm/accent/normal/25.ogg', 'sound/machines/sm/accent/normal/26.ogg', 'sound/machines/sm/accent/normal/27.ogg', 'sound/machines/sm/accent/normal/28.ogg', 'sound/machines/sm/accent/normal/29.ogg', 'sound/machines/sm/accent/normal/30.ogg', 'sound/machines/sm/accent/normal/31.ogg', 'sound/machines/sm/accent/normal/32.ogg', 'sound/machines/sm/accent/normal/33.ogg', 'sound/machines/sm/supermatter1.ogg', 'sound/machines/sm/supermatter2.ogg', 'sound/machines/sm/supermatter3.ogg')
if ("generic_drop")
soundin = pick(
'sound/items/drop/generic1.ogg',
'sound/items/drop/generic2.ogg' )
if ("generic_pickup")
soundin = pick(
'sound/items/pickup/generic1.ogg',
'sound/items/pickup/generic2.ogg',
'sound/items/pickup/generic3.ogg')
return soundin return soundin
//Are these even used? //Are these even used?

View File

@@ -41,4 +41,16 @@
set_light(3,3,"#26c5a9") set_light(3,3,"#26c5a9")
spawn(5 SECONDS) spawn(5 SECONDS)
icon_state = "floor" icon_state = "floor"
set_light(0,0,"#ffffff") set_light(0,0,"#ffffff")
/turf/simulated/floor/gorefloor
name = "infected tile"
desc = "Slick, sickly-squirming meat has grown in and out of cracks once empty. It pulsates intermittently, and with every beat, blood seeps out of pores."
icon_state = "bloodfloor_1"
icon = 'icons/goonstation/turf/meatland.dmi'
/turf/simulated/floor/gorefloor2
name = "putrid mass"
desc = "It is entirely made of sick, gurgling flesh. It is releasing a sickly odour."
icon_state = "bloodfloor_2"
icon = 'icons/goonstation/turf/meatland.dmi'

View File

@@ -61,6 +61,24 @@ var/list/flesh_overlay_cache = list()
var/turf/simulated/flesh/F = get_step(src, direction) var/turf/simulated/flesh/F = get_step(src, direction)
F.update_icon() F.update_icon()
/turf/simulated/gore
name = "wall of viscera"
desc = "Its veins pulse in a sickeningly rapid fashion, while certain spots of the wall rise and fall gently, much like slow, deliberate breathing."
icon = 'icons/goonstation/turf/meatland.dmi'
icon_state = "bloodwall_2"
opacity = 1
density = 1
blocks_air = 1
/turf/simulated/goreeyes
name = "wall of viscera"
desc = "Strangely observant eyes dot the wall. Getting too close has the eyes fixate on you, while their pupils shake violently. Each socket is connected by a series of winding, writhing veins."
icon = 'icons/goonstation/turf/meatland.dmi'
icon_state = "bloodwall_4"
opacity = 1
density = 1
blocks_air = 1
/turf/simulated/shuttle/wall/flock /turf/simulated/shuttle/wall/flock
icon = 'icons/goonstation/featherzone.dmi' icon = 'icons/goonstation/featherzone.dmi'
icon_state = "flockwall0" icon_state = "flockwall0"
@@ -94,4 +112,4 @@ var/list/flesh_overlay_cache = list()
icon_state = "hull-plastitanium" icon_state = "hull-plastitanium"
icon = 'icons/turf/wall_masks_vr.dmi' icon = 'icons/turf/wall_masks_vr.dmi'
/turf/simulated/wall/plastihull/Initialize(mapload) /turf/simulated/wall/plastihull/Initialize(mapload)
. = ..(mapload, MAT_PLASTITANIUMHULL, null,MAT_PLASTITANIUMHULL) . = ..(mapload, MAT_PLASTITANIUMHULL, null,MAT_PLASTITANIUMHULL)

View File

@@ -181,7 +181,6 @@ var/list/admin_verbs_server = list(
/datum/admins/proc/toggle_space_ninja, /datum/admins/proc/toggle_space_ninja,
/client/proc/toggle_random_events, /client/proc/toggle_random_events,
/client/proc/check_customitem_activity, /client/proc/check_customitem_activity,
/client/proc/nanomapgen_DumpImage,
/client/proc/modify_server_news, /client/proc/modify_server_news,
/client/proc/recipe_dump, /client/proc/recipe_dump,
/client/proc/panicbunker, /client/proc/panicbunker,

View File

@@ -6,36 +6,36 @@
"tgui.bundle.css" = 'tgui/packages/tgui/public/tgui.bundle.css', "tgui.bundle.css" = 'tgui/packages/tgui/public/tgui.bundle.css',
) )
// /datum/asset/simple/headers /datum/asset/simple/headers
// assets = list( assets = list(
// "alarm_green.gif" = 'icons/program_icons/alarm_green.gif', "alarm_green.gif" = 'icons/program_icons/alarm_green.gif',
// "alarm_red.gif" = 'icons/program_icons/alarm_red.gif', "alarm_red.gif" = 'icons/program_icons/alarm_red.gif',
// "batt_5.gif" = 'icons/program_icons/batt_5.gif', "batt_5.gif" = 'icons/program_icons/batt_5.gif',
// "batt_20.gif" = 'icons/program_icons/batt_20.gif', "batt_20.gif" = 'icons/program_icons/batt_20.gif',
// "batt_40.gif" = 'icons/program_icons/batt_40.gif', "batt_40.gif" = 'icons/program_icons/batt_40.gif',
// "batt_60.gif" = 'icons/program_icons/batt_60.gif', "batt_60.gif" = 'icons/program_icons/batt_60.gif',
// "batt_80.gif" = 'icons/program_icons/batt_80.gif', "batt_80.gif" = 'icons/program_icons/batt_80.gif',
// "batt_100.gif" = 'icons/program_icons/batt_100.gif', "batt_100.gif" = 'icons/program_icons/batt_100.gif',
// "charging.gif" = 'icons/program_icons/charging.gif', "charging.gif" = 'icons/program_icons/charging.gif',
// "downloader_finished.gif" = 'icons/program_icons/downloader_finished.gif', "downloader_finished.gif" = 'icons/program_icons/downloader_finished.gif',
// "downloader_running.gif" = 'icons/program_icons/downloader_running.gif', "downloader_running.gif" = 'icons/program_icons/downloader_running.gif',
// "ntnrc_idle.gif" = 'icons/program_icons/ntnrc_idle.gif', "ntnrc_idle.gif" = 'icons/program_icons/ntnrc_idle.gif',
// "ntnrc_new.gif" = 'icons/program_icons/ntnrc_new.gif', "ntnrc_new.gif" = 'icons/program_icons/ntnrc_new.gif',
// "power_norm.gif" = 'icons/program_icons/power_norm.gif', "power_norm.gif" = 'icons/program_icons/power_norm.gif',
// "power_warn.gif" = 'icons/program_icons/power_warn.gif', "power_warn.gif" = 'icons/program_icons/power_warn.gif',
// "sig_high.gif" = 'icons/program_icons/sig_high.gif', "sig_high.gif" = 'icons/program_icons/sig_high.gif',
// "sig_low.gif" = 'icons/program_icons/sig_low.gif', "sig_low.gif" = 'icons/program_icons/sig_low.gif',
// "sig_lan.gif" = 'icons/program_icons/sig_lan.gif', "sig_lan.gif" = 'icons/program_icons/sig_lan.gif',
// "sig_none.gif" = 'icons/program_icons/sig_none.gif', "sig_none.gif" = 'icons/program_icons/sig_none.gif',
// "smmon_0.gif" = 'icons/program_icons/smmon_0.gif', "smmon_0.gif" = 'icons/program_icons/smmon_0.gif',
// "smmon_1.gif" = 'icons/program_icons/smmon_1.gif', "smmon_1.gif" = 'icons/program_icons/smmon_1.gif',
// "smmon_2.gif" = 'icons/program_icons/smmon_2.gif', "smmon_2.gif" = 'icons/program_icons/smmon_2.gif',
// "smmon_3.gif" = 'icons/program_icons/smmon_3.gif', "smmon_3.gif" = 'icons/program_icons/smmon_3.gif',
// "smmon_4.gif" = 'icons/program_icons/smmon_4.gif', "smmon_4.gif" = 'icons/program_icons/smmon_4.gif',
// "smmon_5.gif" = 'icons/program_icons/smmon_5.gif', "smmon_5.gif" = 'icons/program_icons/smmon_5.gif',
// "smmon_6.gif" = 'icons/program_icons/smmon_6.gif', "smmon_6.gif" = 'icons/program_icons/smmon_6.gif',
// "borg_mon.gif" = 'icons/program_icons/borg_mon.gif' // "borg_mon.gif" = 'icons/program_icons/borg_mon.gif'
// ) )
// /datum/asset/simple/radar_assets // /datum/asset/simple/radar_assets
// assets = list( // assets = list(
@@ -206,15 +206,15 @@
// "none_button.png" = 'html/none_button.png', // "none_button.png" = 'html/none_button.png',
// ) // )
// /datum/asset/simple/arcade /datum/asset/simple/arcade
// assets = list( assets = list(
// "boss1.gif" = 'icons/UI_Icons/Arcade/boss1.gif', "boss1.gif" = 'icons/UI_Icons/Arcade/boss1.gif',
// "boss2.gif" = 'icons/UI_Icons/Arcade/boss2.gif', "boss2.gif" = 'icons/UI_Icons/Arcade/boss2.gif',
// "boss3.gif" = 'icons/UI_Icons/Arcade/boss3.gif', "boss3.gif" = 'icons/UI_Icons/Arcade/boss3.gif',
// "boss4.gif" = 'icons/UI_Icons/Arcade/boss4.gif', "boss4.gif" = 'icons/UI_Icons/Arcade/boss4.gif',
// "boss5.gif" = 'icons/UI_Icons/Arcade/boss5.gif', "boss5.gif" = 'icons/UI_Icons/Arcade/boss5.gif',
// "boss6.gif" = 'icons/UI_Icons/Arcade/boss6.gif', "boss6.gif" = 'icons/UI_Icons/Arcade/boss6.gif',
// ) )
// /datum/asset/spritesheet/simple/achievements // /datum/asset/spritesheet/simple/achievements
// name ="achievements" // name ="achievements"
@@ -433,45 +433,6 @@
// Insert("polycrystal", 'icons/obj/telescience.dmi', "polycrystal") // Insert("polycrystal", 'icons/obj/telescience.dmi', "polycrystal")
// ..() // ..()
/datum/asset/nanoui
var/list/common = list()
var/list/common_dirs = list(
"nano/css/",
"nano/images/",
"nano/images/modular_computers/",
"nano/js/"
)
var/list/template_dirs = list(
"nano/templates/"
)
/datum/asset/nanoui/register()
// Crawl the directories to find files.
for(var/path in common_dirs)
var/list/filenames = flist(path)
for(var/filename in filenames)
if(copytext(filename, length(filename)) != "/") // Ignore directories.
if(fexists(path + filename))
common[filename] = fcopy_rsc(path + filename)
register_asset(filename, common[filename])
// Combine all templates into a single bundle.
var/list/template_data = list()
for(var/path in template_dirs)
var/list/filenames = flist(path)
for(var/filename in filenames)
if(copytext(filename, length(filename) - 4) == ".tmpl") // Ignore directories.
template_data[filename] = file2text(path + filename)
var/template_bundle = "function nanouiTemplateBundle(){return [json_encode(template_data)];}"
var/fname = "data/nano_templates_bundle.js"
fdel(fname)
text2file(template_bundle, fname)
register_asset("nano_templates_bundle.js", fcopy_rsc(fname))
fdel(fname)
/datum/asset/nanoui/send(client)
send_asset_list(client, common)
//Pill sprites for UIs //Pill sprites for UIs
/datum/asset/chem_master /datum/asset/chem_master
var/assets = list() var/assets = list()
@@ -522,4 +483,31 @@
/datum/asset/spritesheet/sheetmaterials/register() /datum/asset/spritesheet/sheetmaterials/register()
InsertAll("", 'icons/obj/stacks.dmi') InsertAll("", 'icons/obj/stacks.dmi')
..() ..()
// Nanomaps
/datum/asset/simple/nanomaps
// It REALLY doesnt matter too much if these arent up to date
// They are relatively big
assets = list(
// VOREStation Edit: We don't need Southern Cross
// "southern_cross_nanomap_z1.png" = 'icons/_nanomaps/southern_cross_nanomap_z1.png',
// "southern_cross_nanomap_z10.png" = 'icons/_nanomaps/southern_cross_nanomap_z10.png',
// "southern_cross_nanomap_z2.png" = 'icons/_nanomaps/southern_cross_nanomap_z2.png',
// "southern_cross_nanomap_z3.png" = 'icons/_nanomaps/southern_cross_nanomap_z3.png',
// "southern_cross_nanomap_z5.png" = 'icons/_nanomaps/southern_cross_nanomap_z5.png',
// "southern_cross_nanomap_z6.png" = 'icons/_nanomaps/southern_cross_nanomap_z6.png',
"tether_nanomap_z1.png" = 'icons/_nanomaps/tether_nanomap_z1.png',
"tether_nanomap_z2.png" = 'icons/_nanomaps/tether_nanomap_z2.png',
"tether_nanomap_z3.png" = 'icons/_nanomaps/tether_nanomap_z3.png',
"tether_nanomap_z4.png" = 'icons/_nanomaps/tether_nanomap_z4.png',
"tether_nanomap_z5.png" = 'icons/_nanomaps/tether_nanomap_z5.png',
"tether_nanomap_z6.png" = 'icons/_nanomaps/tether_nanomap_z6.png',
"tether_nanomap_z7.png" = 'icons/_nanomaps/tether_nanomap_z7.png',
"tether_nanomap_z8.png" = 'icons/_nanomaps/tether_nanomap_z8.png',
"tether_nanomap_z9.png" = 'icons/_nanomaps/tether_nanomap_z9.png',
"tether_nanomap_z10.png" = 'icons/_nanomaps/tether_nanomap_z10.png',
"tether_nanomap_z13.png" = 'icons/_nanomaps/tether_nanomap_z13.png',
"tether_nanomap_z14.png" = 'icons/_nanomaps/tether_nanomap_z14.png',
// VOREStation Edit End
)

Some files were not shown because too many files have changed in this diff Show More