mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-23 03:57:48 +01:00
Merge branch 'master' into kk-adminships
This commit is contained in:
@@ -91,16 +91,16 @@
|
||||
|
||||
var/icon/default_worn_icon //Default on-mob icon
|
||||
var/worn_layer //Default on-mob layer
|
||||
|
||||
|
||||
// Pickup/Drop/Equip/Throw Sounds
|
||||
///Used when thrown into a mob
|
||||
var/mob_throw_hit_sound
|
||||
// Sound used when equipping the items into a valid slot.
|
||||
var/equip_sound
|
||||
var/equip_sound
|
||||
// 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
|
||||
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
|
||||
|
||||
@@ -468,12 +468,12 @@ var/list/global/slot_flags_enumeration = list(
|
||||
|
||||
if(!canremove)
|
||||
return 0
|
||||
|
||||
|
||||
if(!slot)
|
||||
if(issilicon(M))
|
||||
return 1 // for stuff in grippers
|
||||
return 0
|
||||
|
||||
|
||||
if(!M.slot_is_accessible(slot, src, disable_warning? null : M))
|
||||
return 0
|
||||
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.
|
||||
/obj/item/device
|
||||
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
|
||||
/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
@@ -1,26 +0,0 @@
|
||||
/obj/item/device/pda
|
||||
var/delete_id = FALSE //Guaranteed deletion of ID upon deletion of PDA
|
||||
|
||||
/obj/item/device/pda/multicaster/exploration/New()
|
||||
..()
|
||||
owner = "Exploration Department"
|
||||
name = "Exploration Department (Relay)"
|
||||
cartridges_to_send_to = exploration_cartridges
|
||||
|
||||
/obj/item/device/pda/centcom
|
||||
default_cartridge = /obj/item/weapon/cartridge/captain
|
||||
icon_state = "pda-h"
|
||||
detonate = 0
|
||||
// hidden = 1
|
||||
|
||||
/obj/item/device/pda/pathfinder
|
||||
default_cartridge = /obj/item/weapon/cartridge/explorer
|
||||
icon_state = "pda-lawyer-old"
|
||||
|
||||
/obj/item/device/pda/explorer
|
||||
default_cartridge = /obj/item/weapon/cartridge/explorer
|
||||
icon_state = "pda-det"
|
||||
|
||||
/obj/item/device/pda/sar
|
||||
default_cartridge = /obj/item/weapon/cartridge/sar
|
||||
icon_state = "pda-h"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 ..()
|
||||
@@ -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 = "→", comma_text = "→", final_comma_text = "→") // 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)
|
||||
@@ -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 = "→", comma_text = "→", final_comma_text = "→") // 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"])
|
||||
|
||||
@@ -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])
|
||||
)
|
||||
@@ -14,7 +14,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
#define WTHRTAB 7
|
||||
#define MANITAB 8
|
||||
#define SETTTAB 9
|
||||
#define EXTRTAB 10
|
||||
|
||||
/obj/item/device/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/notehtml = ""
|
||||
|
||||
var/obj/item/weapon/commcard/cartridge = null //current cartridge
|
||||
var/fon = 0 // Internal light
|
||||
var/flum = 2 // Brightness
|
||||
|
||||
var/list/modules = list(
|
||||
list("module" = "Phone", "icon" = "phone64", "number" = PHONTAB),
|
||||
list("module" = "Contacts", "icon" = "person64", "number" = CONTTAB),
|
||||
list("module" = "Messaging", "icon" = "comment64", "number" = MESSTAB),
|
||||
list("module" = "News", "icon" = "note64", "number" = NEWSTAB), // Need a different icon,
|
||||
list("module" = "Note", "icon" = "note64", "number" = NOTETAB),
|
||||
list("module" = "Weather", "icon" = "sun64", "number" = WTHRTAB),
|
||||
list("module" = "Crew Manifest", "icon" = "note64", "number" = MANITAB), // Need a different icon,
|
||||
list("module" = "Settings", "icon" = "gear64", "number" = SETTTAB),
|
||||
list("module" = "Phone", "icon" = "phone", "number" = PHONTAB),
|
||||
list("module" = "Contacts", "icon" = "user", "number" = CONTTAB),
|
||||
list("module" = "Messaging", "icon" = "comment-alt", "number" = MESSTAB),
|
||||
list("module" = "News", "icon" = "newspaper", "number" = NEWSTAB), // Need a different icon,
|
||||
list("module" = "Note", "icon" = "sticky-note", "number" = NOTETAB),
|
||||
list("module" = "Weather", "icon" = "sun", "number" = WTHRTAB),
|
||||
list("module" = "Crew Manifest", "icon" = "crown", "number" = MANITAB), // Need a different icon,
|
||||
list("module" = "Settings", "icon" = "cog", "number" = SETTTAB),
|
||||
) //list("module" = "Name of Module", "icon" = "icon name64", "number" = "what tab is the module")
|
||||
|
||||
var/selected_tab = HOMETAB
|
||||
@@ -104,13 +102,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
register_device(S.loc.name)
|
||||
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()
|
||||
// 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.
|
||||
/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)
|
||||
. += "<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
|
||||
. += "<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()
|
||||
// Parameters: None
|
||||
// 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())
|
||||
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()
|
||||
// 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.
|
||||
@@ -229,13 +223,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
occupation = idcard.assignment
|
||||
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
|
||||
|
||||
// Proc: attack_self()
|
||||
@@ -246,7 +233,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
initialize_exonet(user)
|
||||
alert_called = 0
|
||||
update_icon()
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
if(video_source)
|
||||
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.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.
|
||||
/obj/item/device/communicator/watch
|
||||
name = "communicator watch"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// Values were extracted from the template itself
|
||||
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" = "Temperature", "units" = "°C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
|
||||
list("entry" = "Temperature", "units" = "°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" = "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),
|
||||
@@ -44,19 +44,18 @@
|
||||
var/index = 0
|
||||
for(var/datum/feed_message/FM in channel.messages)
|
||||
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)
|
||||
usr << browse_rsc(FM.img, "pda_news_tmp_photo_[feeds["channel"]]_[index].png")
|
||||
// News stories are HTML-stripped but require newline replacement to be properly displayed in NanoUI
|
||||
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
|
||||
)
|
||||
msgdata["img"] = icon2base64(FM.img)
|
||||
messages[++messages.len] = msgdata
|
||||
|
||||
feeds[++feeds.len] = list(
|
||||
"name" = channel.channel_name,
|
||||
@@ -96,448 +95,3 @@
|
||||
news.Swap(1, 3) // List is sorted in ascending order of timestamp, we want descending
|
||||
|
||||
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
|
||||
@@ -5,7 +5,7 @@
|
||||
var/in_hack_mode = 0
|
||||
var/list/known_targets
|
||||
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()
|
||||
..()
|
||||
@@ -30,7 +30,7 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/device/multitool/hacktool/resolve_attackby(atom/A, mob/user)
|
||||
/obj/item/device/multitool/hacktool/afterattack(atom/A, mob/user)
|
||||
sanity_check()
|
||||
|
||||
if(!in_hack_mode)
|
||||
@@ -39,7 +39,8 @@
|
||||
if(!attempt_hack(user, A))
|
||||
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
|
||||
|
||||
/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)
|
||||
known_targets -= target
|
||||
|
||||
/datum/topic_state/default/must_hack
|
||||
/datum/tgui_state/default/must_hack
|
||||
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
|
||||
..()
|
||||
|
||||
/datum/topic_state/default/must_hack/Destroy()
|
||||
/datum/tgui_state/default/must_hack/Destroy()
|
||||
hacktool = null
|
||||
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))
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
@@ -33,6 +33,24 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
|
||||
QDEL_NULL(radio)
|
||||
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)
|
||||
if (!in_range(src, user))
|
||||
return
|
||||
|
||||
@@ -151,18 +151,10 @@ var/global/list/default_medbay_channels = list(
|
||||
|
||||
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)
|
||||
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)
|
||||
/obj/item/device/radio/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Radio", name)
|
||||
ui = new(user, src, "Radio", name, parent_ui)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/radio/tgui_data(mob/user)
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
popup.set_content(jointext(dat,null))
|
||||
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(..())
|
||||
return 1
|
||||
if(href_list["channel"])
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
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
|
||||
var/welcome = "Welcome, Operative" // Welcoming menu message
|
||||
var/uses // Numbers of crystals
|
||||
var/list/ItemsCategory // List of categories with lists of items
|
||||
var/list/ItemsReference // List of references with an associated item
|
||||
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/list/purchase_log = new
|
||||
@@ -17,9 +27,7 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
|
||||
var/next_offer_time
|
||||
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
|
||||
|
||||
/obj/item/device/uplink/nano_host()
|
||||
return loc
|
||||
var/compact_mode = FALSE
|
||||
|
||||
/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"
|
||||
desc = "There is something wrong if you're examining this."
|
||||
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/selected_cat
|
||||
|
||||
// The hidden uplink MUST be inside an obj/item's contents.
|
||||
/obj/item/device/uplink/hidden/Initialize()
|
||||
. = ..()
|
||||
if(!isitem(loc))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
nanoui_data = list()
|
||||
update_nano_data()
|
||||
|
||||
/obj/item/device/uplink/hidden/next_offer()
|
||||
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)
|
||||
update_nano_data()
|
||||
SSnanoui.update_uis(src)
|
||||
next_offer_time = world.time + offer_time
|
||||
SStgui.update_uis(src)
|
||||
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.
|
||||
@@ -91,136 +96,137 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/*
|
||||
NANO UI FOR UPLINK WOOP WOOP
|
||||
*/
|
||||
/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
|
||||
// Legacy
|
||||
/obj/item/device/uplink/hidden/interact(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
data["welcome"] = welcome
|
||||
data["crystals"] = uses
|
||||
data["menu"] = nanoui_menu
|
||||
data += nanoui_data
|
||||
/*****************
|
||||
* Uplink TGUI
|
||||
*****************/
|
||||
/obj/item/device/uplink/tgui_host()
|
||||
return loc
|
||||
|
||||
// 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) // No auto-refresh
|
||||
ui = new(user, src, ui_key, "uplink.tmpl", title, 630, 700, state = inventory_state)
|
||||
data["menu"] = 0
|
||||
ui.set_initial_data(data)
|
||||
/obj/item/device/uplink/hidden/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
/obj/item/device/uplink/hidden/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
if(!active)
|
||||
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()
|
||||
|
||||
/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.
|
||||
/obj/item/device/uplink/hidden/interact(mob/user)
|
||||
ui_interact(user)
|
||||
var/list/data = ..()
|
||||
|
||||
/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)
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
// The purchasing code.
|
||||
/obj/item/device/uplink/hidden/Topic(href, href_list)
|
||||
/obj/item/device/uplink/hidden/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/mob/user = usr
|
||||
if(href_list["buy_item"])
|
||||
var/datum/uplink_item/UI = (locate(href_list["buy_item"]) in uplink.items)
|
||||
UI.buy(src, usr)
|
||||
else if(href_list["lock"])
|
||||
toggle()
|
||||
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
|
||||
ui.close()
|
||||
else if(href_list["return"])
|
||||
nanoui_menu = round(nanoui_menu/10)
|
||||
else if(href_list["menu"])
|
||||
nanoui_menu = text2num(href_list["menu"])
|
||||
if(href_list["id"])
|
||||
exploit_id = href_list["id"]
|
||||
else if(href_list["category"])
|
||||
category = locate(href_list["category"]) in uplink.categories
|
||||
|
||||
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
|
||||
switch(action)
|
||||
if("buy")
|
||||
var/datum/uplink_item/UI = (locate(params["ref"]) in uplink.items)
|
||||
UI.buy(src, usr)
|
||||
return TRUE
|
||||
if("lock")
|
||||
toggle()
|
||||
SStgui.close_uis(src)
|
||||
if("select")
|
||||
selected_cat = params["category"]
|
||||
return TRUE
|
||||
if("compact_toggle")
|
||||
compact_mode = !compact_mode
|
||||
return TRUE
|
||||
if("view_exploits")
|
||||
exploit_id = params["id"]
|
||||
return TRUE
|
||||
|
||||
// PRESET UPLINKS
|
||||
// A collection of preset uplinks.
|
||||
//
|
||||
// Includes normal radio uplink, multitool uplink,
|
||||
// implant uplink (not the implant tool) and a preset headset uplink.
|
||||
|
||||
/obj/item/device/radio/uplink/New(atom/loc, datum/mind/target_mind, telecrystals)
|
||||
..(loc)
|
||||
hidden_uplink = new(src, target_mind, telecrystals)
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
singular_name = "human skin piece"
|
||||
icon_state = "sheet-hide"
|
||||
no_variants = FALSE
|
||||
drop_sound = 'sound/items/drop/cloth.ogg'
|
||||
pickup_sound = 'sound/items/pickup/cloth.ogg'
|
||||
drop_sound = 'sound/items/drop/leather.ogg'
|
||||
pickup_sound = 'sound/items/pickup/leather.ogg'
|
||||
|
||||
/obj/item/stack/animalhide/human
|
||||
amount = 50
|
||||
|
||||
@@ -66,63 +66,81 @@
|
||||
else
|
||||
. += "There is enough charge for [get_amount()]."
|
||||
|
||||
/obj/item/stack/attack_self(mob/user as mob)
|
||||
list_recipes(user)
|
||||
/obj/item/stack/attack_self(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/stack/proc/list_recipes(mob/user as mob, recipes_sublist)
|
||||
if (!recipes)
|
||||
return
|
||||
if (!src || get_amount() <= 0)
|
||||
user << browse(null, "window=stack")
|
||||
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
|
||||
/obj/item/stack/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Stack", name)
|
||||
ui.open()
|
||||
|
||||
if (i>1 && !isnull(recipe_list[i-1]))
|
||||
t1+="<br>"
|
||||
/obj/item/stack/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["amount"] = get_amount()
|
||||
|
||||
if (istype(E, /datum/stack_recipe_list))
|
||||
var/datum/stack_recipe_list/srl = E
|
||||
t1 += "<a href='?src=\ref[src];sublist=[i]'>[srl.title]</a>"
|
||||
return data
|
||||
|
||||
if (istype(E, /datum/stack_recipe))
|
||||
var/datum/stack_recipe/R = E
|
||||
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>"
|
||||
/obj/item/stack/tgui_static_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
t1 += "</TT></body></HTML>"
|
||||
user << browse(t1, "window=stack")
|
||||
onclose(user, "stack")
|
||||
return
|
||||
data["recipes"] = recursively_build_recipes(recipes)
|
||||
|
||||
return data
|
||||
|
||||
/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)
|
||||
var/required = quantity*recipe.req_amount
|
||||
@@ -177,35 +195,6 @@
|
||||
else
|
||||
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.
|
||||
//Ensures that code dealing with stacks uses the same logic
|
||||
/obj/item/stack/proc/can_use(var/used)
|
||||
|
||||
@@ -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
|
||||
@@ -126,11 +126,13 @@
|
||||
name = "empty cup"
|
||||
icon_state = "coffee_vended"
|
||||
drop_sound = 'sound/items/drop/papercup.ogg'
|
||||
pickup_sound = 'sound/items/pickup/papercup.ogg'
|
||||
|
||||
/obj/item/trash/ramen
|
||||
name = "cup ramen"
|
||||
icon_state = "ramen"
|
||||
drop_sound = 'sound/items/drop/papercup.ogg'
|
||||
pickup_sound = 'sound/items/pickup/papercup.ogg'
|
||||
|
||||
/obj/item/trash/tray
|
||||
name = "tray"
|
||||
@@ -141,6 +143,8 @@
|
||||
name = "candle"
|
||||
icon = 'icons/obj/candle.dmi'
|
||||
icon_state = "candle4"
|
||||
drop_sound = 'sound/items/drop/gloves.ogg'
|
||||
pickup_sound = 'sound/items/pickup/gloves.ogg'
|
||||
|
||||
/obj/item/trash/liquidfood
|
||||
name = "\improper \"LiquidFood\" ration packet"
|
||||
@@ -162,18 +166,26 @@
|
||||
/obj/item/trash/brownies
|
||||
name = "brownie tray"
|
||||
icon_state = "brownies"
|
||||
drop_sound = 'sound/items/drop/soda.ogg'
|
||||
pickup_sound = 'sound/items/pickup/soda.ogg'
|
||||
|
||||
/obj/item/trash/snacktray
|
||||
name = "snacktray"
|
||||
icon_state = "snacktray"
|
||||
drop_sound = 'sound/items/drop/soda.ogg'
|
||||
pickup_sound = 'sound/items/pickup/soda.ogg'
|
||||
|
||||
/obj/item/trash/dipbowl
|
||||
name = "dip bowl"
|
||||
icon_state = "dipbowl"
|
||||
drop_sound = 'sound/items/drop/food.ogg'
|
||||
pickup_sound = 'sound/items/pickup/food.ogg'
|
||||
|
||||
/obj/item/trash/chipbasket
|
||||
name = "empty basket"
|
||||
icon_state = "chipbasket_empty"
|
||||
drop_sound = 'sound/items/drop/food.ogg'
|
||||
pickup_sound = 'sound/items/pickup/food.ogg'
|
||||
|
||||
/obj/item/trash/spitgum
|
||||
name = "old gum"
|
||||
@@ -181,12 +193,15 @@
|
||||
icon = 'icons/obj/clothing/masks.dmi'
|
||||
icon_state = "spit-gum"
|
||||
drop_sound = 'sound/items/drop/flesh.ogg'
|
||||
pickup_sound = 'sound/items/pickup/flesh.ogg'
|
||||
|
||||
/obj/item/trash/lollibutt
|
||||
name = "lollipop stick"
|
||||
desc = "A lollipop stick devoid of pop."
|
||||
icon = 'icons/obj/clothing/masks.dmi'
|
||||
icon_state = "pop-stick"
|
||||
drop_sound = 'sound/items/drop/component.ogg'
|
||||
pickup_sound = 'sound/items/pickup/component.ogg'
|
||||
|
||||
/obj/item/trash/spitwad
|
||||
name = "spit wad"
|
||||
@@ -194,6 +209,7 @@
|
||||
icon = 'icons/obj/clothing/masks.dmi'
|
||||
icon_state = "spit-chew"
|
||||
drop_sound = 'sound/items/drop/flesh.ogg'
|
||||
pickup_sound = 'sound/items/pickup/flesh.ogg'
|
||||
slot_flags = SLOT_EARS | SLOT_MASK
|
||||
|
||||
/obj/item/trash/attack(mob/M as mob, mob/living/user as mob)
|
||||
|
||||
@@ -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
|
||||
@@ -14,6 +14,8 @@
|
||||
var/list/datum/autopsy_data_scanner/chemtraces = list()
|
||||
var/target_name = null
|
||||
var/timeofdeath = null
|
||||
drop_sound = 'sound/items/drop/device.ogg'
|
||||
pickup_sound = 'sound/items/pickup/device.ogg'
|
||||
|
||||
/datum/autopsy_data_scanner
|
||||
var/weapon = null // this is the DEFINITE weapon type that was used
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
var/board_type = new /datum/frame/frame_types/computer
|
||||
var/list/req_components = null
|
||||
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.
|
||||
/obj/item/weapon/circuitboard/proc/construct(var/obj/machinery/M)
|
||||
|
||||
@@ -110,10 +110,6 @@
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/device/analyzer))
|
||||
var/obj/item/device/analyzer/A = W
|
||||
A.analyze_gases(src, user)
|
||||
return
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
@@ -6,8 +6,11 @@
|
||||
var/electronic_warfare = 1
|
||||
var/mob/registered_user = null
|
||||
|
||||
var/datum/tgui_module/agentcard/agentcard_module
|
||||
|
||||
/obj/item/weapon/card/id/syndicate/Initialize()
|
||||
. = ..()
|
||||
agentcard_module = new(src)
|
||||
access = syndicate_access.Copy()
|
||||
|
||||
/obj/item/weapon/card/id/syndicate/station_access/Initialize()
|
||||
@@ -15,6 +18,7 @@
|
||||
access |= get_all_station_access()
|
||||
|
||||
/obj/item/weapon/card/id/syndicate/Destroy()
|
||||
QDEL_NULL(agentcard_module)
|
||||
unset_registered_user(registered_user)
|
||||
return ..()
|
||||
|
||||
@@ -36,33 +40,12 @@
|
||||
if(registered_user == user)
|
||||
switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show"))
|
||||
if("Edit")
|
||||
ui_interact(user)
|
||||
agentcard_module.tgui_interact(user)
|
||||
if("Show")
|
||||
..()
|
||||
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)
|
||||
if(!istype(user) || user == registered_user)
|
||||
@@ -79,114 +62,6 @@
|
||||
registered_user.unregister(OBSERVER_EVENT_DESTROY, src)
|
||||
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
|
||||
/proc/id_card_states()
|
||||
if(!id_card_states)
|
||||
|
||||
@@ -169,6 +169,10 @@
|
||||
organ_to_implant = /obj/item/organ/internal/augment/armmounted/hand/sword
|
||||
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
|
||||
/obj/item/weapon/implant/organ/limbaugment/laser
|
||||
organ_to_implant = /obj/item/organ/internal/augment/armmounted
|
||||
@@ -185,6 +189,10 @@
|
||||
/obj/item/weapon/implant/organ/limbaugment/upperarm/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
|
||||
*/
|
||||
|
||||
@@ -279,3 +279,23 @@
|
||||
src.imp = new /obj/item/weapon/implant/organ/pelvic( src )
|
||||
..()
|
||||
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
|
||||
|
||||
@@ -362,6 +362,8 @@
|
||||
usr.client.screen -= W
|
||||
W.dropped(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)
|
||||
for(var/mob/M in viewers(usr, null))
|
||||
|
||||
@@ -128,6 +128,12 @@
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/imp_aug/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
|
||||
name = "boxed space suit and helmet"
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
slot_flags = SLOT_ID
|
||||
|
||||
var/obj/item/weapon/card/id/front_id = null
|
||||
|
||||
drop_sound = 'sound/items/drop/cloth.ogg'
|
||||
pickup_sound = 'sound/items/pickup/cloth.ogg'
|
||||
|
||||
drop_sound = 'sound/items/drop/leather.ogg'
|
||||
pickup_sound = 'sound/items/pickup/leather.ogg'
|
||||
|
||||
/obj/item/weapon/storage/wallet/remove_from_storage(obj/item/W as obj, atom/new_location)
|
||||
. = ..(W, new_location)
|
||||
|
||||
@@ -120,9 +120,6 @@ var/list/global/tank_gauge_cache = list()
|
||||
if (istype(src.loc, /obj/item/assembly))
|
||||
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))
|
||||
var/obj/item/latexballon/LB = W
|
||||
LB.blow(src)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
old_turf.unregister_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 && ..())
|
||||
return 1
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
CouldNotUseTopic(usr)
|
||||
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))
|
||||
return ..()
|
||||
to_chat(user, "<span class='danger'>[bicon(src)]Access Denied!</span>")
|
||||
@@ -69,7 +69,7 @@
|
||||
return 1
|
||||
|
||||
/obj/proc/CouldUseTopic(var/mob/user)
|
||||
var/atom/host = nano_host()
|
||||
var/atom/host = tgui_host()
|
||||
host.add_hiddenprint(user)
|
||||
|
||||
/obj/proc/CouldNotUseTopic(var/mob/user)
|
||||
@@ -135,7 +135,6 @@
|
||||
in_use = 0
|
||||
|
||||
/obj/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
..()
|
||||
|
||||
|
||||
@@ -153,6 +153,65 @@
|
||||
prob(2);/obj/item/ammo_magazine/m9mmt,
|
||||
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
|
||||
name = "Random Projectile Weapon"
|
||||
desc = "This is a random weapon."
|
||||
|
||||
@@ -585,7 +585,7 @@
|
||||
/obj/item/clothing/mask/breath,
|
||||
/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/tank,
|
||||
@@ -625,13 +625,20 @@
|
||||
/obj/random/powercell,
|
||||
/obj/structure/closet/crate/einstein //EINSTEIN BATTERYPACK
|
||||
),
|
||||
prob(10);list(
|
||||
prob(5);list(
|
||||
/obj/item/weapon/circuitboard/smes,
|
||||
/obj/random/smes_coil,
|
||||
/obj/random/smes_coil,
|
||||
/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,
|
||||
@@ -640,7 +647,7 @@
|
||||
/obj/random/cigarettes,
|
||||
/obj/structure/closet/crate/gilthari //GILTHARI LUXURY
|
||||
),
|
||||
prob(15);list(
|
||||
prob(10);list(
|
||||
/obj/random/tech_supply/nofail,
|
||||
/obj/random/tech_supply/component/nofail,
|
||||
/obj/random/tech_supply/component/nofail,
|
||||
@@ -655,7 +662,7 @@
|
||||
/obj/random/multiple/ore_pile,
|
||||
/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,
|
||||
@@ -671,24 +678,48 @@
|
||||
/obj/item/weapon/cell/device/weapon,
|
||||
/obj/structure/closet/crate/secure/heph //HEPHAESTUS ENERGY
|
||||
),
|
||||
prob(2);list(
|
||||
/obj/random/projectile/random,
|
||||
/obj/random/projectile/random,
|
||||
/obj/structure/closet/crate/secure/heph //HEPHAESTUS PROJECTILE
|
||||
prob(1);list(
|
||||
/obj/random/grenade/box,
|
||||
/obj/random/grenade/box,
|
||||
/obj/structure/closet/crate/secure/heph //HEPHAESTUS GRENADES
|
||||
),
|
||||
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/tank,
|
||||
/obj/item/clothing/mask/breath,
|
||||
/obj/structure/closet/crate/secure/nanotrasen //NTSEC SUIT
|
||||
),
|
||||
prob(2);list(
|
||||
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,
|
||||
@@ -697,11 +728,13 @@
|
||||
/obj/random/medical/lite,
|
||||
/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/unidentified_medicine/fresh_medicine,
|
||||
/obj/random/unidentified_medicine/fresh_medicine,
|
||||
/obj/structure/closet/crate/veymed //VM FAKS
|
||||
),
|
||||
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/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(
|
||||
/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/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/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(
|
||||
/obj/random/cash/big,
|
||||
@@ -849,6 +1200,100 @@
|
||||
/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.
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
@@ -29,6 +29,10 @@
|
||||
/obj/item/clothing/suit/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(
|
||||
/obj/item/clothing/suit/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
|
||||
name = "Random Security Voidsuit"
|
||||
|
||||
@@ -16,8 +16,8 @@ LINEN BINS
|
||||
throw_speed = 1
|
||||
throw_range = 2
|
||||
w_class = ITEMSIZE_SMALL
|
||||
drop_sound = 'sound/items/drop/cloth.ogg'
|
||||
pickup_sound = 'sound/items/pickup/cloth.ogg'
|
||||
drop_sound = 'sound/items/drop/clothing.ogg'
|
||||
pickup_sound = 'sound/items/pickup/clothing.ogg'
|
||||
|
||||
/obj/item/weapon/bedsheet/attack_self(mob/user as mob)
|
||||
user.drop_item()
|
||||
|
||||
@@ -20,8 +20,90 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
|
||||
var/has_items = FALSE
|
||||
var/dismantled = TRUE
|
||||
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()
|
||||
QDEL_NULL(mybag)
|
||||
@@ -29,20 +111,22 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
|
||||
QDEL_NULL(myspray)
|
||||
QDEL_NULL(myreplacer)
|
||||
QDEL_NULL(mybucket)
|
||||
clearTguiIcons()
|
||||
return ..()
|
||||
|
||||
/obj/structure/janitorialcart/examine(mob/user)
|
||||
if(..(user, 1))
|
||||
if (mybucket)
|
||||
var/contains = mybucket.reagents.total_volume
|
||||
to_chat(user, "\icon[src] The bucket contains [contains] unit\s of liquid!")
|
||||
else
|
||||
to_chat(user, "\icon[src] There is no bucket mounted on it!")
|
||||
. = ..(user)
|
||||
if(istype(mybucket))
|
||||
var/contains = mybucket.reagents.total_volume
|
||||
. += "[bicon(src)] The bucket contains [contains] unit\s of liquid!"
|
||||
else
|
||||
. += "[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)
|
||||
if (istype(O, /obj/structure/mopbucket) && !mybucket)
|
||||
O.forceMove(src)
|
||||
mybucket = O
|
||||
setTguiIcon("mybucket", mybucket)
|
||||
to_chat(user, "You mount the [O] on the janicart.")
|
||||
update_icon()
|
||||
else
|
||||
@@ -70,38 +154,19 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
|
||||
return 1
|
||||
|
||||
else if(istype(I, /obj/item/weapon/reagent_containers/spray) && !myspray)
|
||||
user.unEquip(I, 0, src)
|
||||
myspray = I
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
|
||||
equip_janicart_item(user, I)
|
||||
return 1
|
||||
|
||||
else if(istype(I, /obj/item/device/lightreplacer) && !myreplacer)
|
||||
user.unEquip(I, 0, src)
|
||||
myreplacer = I
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
|
||||
equip_janicart_item(user, I)
|
||||
return 1
|
||||
|
||||
else if(istype(I, /obj/item/weapon/storage/bag/trash) && !mybag)
|
||||
user.unEquip(I, 0, src)
|
||||
mybag = I
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
|
||||
equip_janicart_item(user, I)
|
||||
return 1
|
||||
|
||||
else if(istype(I, /obj/item/clothing/suit/caution))
|
||||
if(signs < 4)
|
||||
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>")
|
||||
equip_janicart_item(user, I)
|
||||
return 1
|
||||
|
||||
else if(mybag)
|
||||
@@ -124,16 +189,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
|
||||
if(user.incapacitated() || !Adjacent(user)) return
|
||||
var/obj/I = usr.get_active_hand()
|
||||
if(istype(I, /obj/item/weapon/mop))
|
||||
if(!mymop)
|
||||
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
|
||||
equip_janicart_item(user, I)
|
||||
else if(istype(I, /obj/item/weapon/reagent_containers) && mybucket)
|
||||
var/obj/item/weapon/reagent_containers/C = I
|
||||
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)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
return
|
||||
|
||||
/obj/structure/janitorialcart/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = TRUE)
|
||||
var/data[0]
|
||||
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)
|
||||
/obj/structure/janitorialcart/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "janitorcart.tmpl", "Janitorial cart", 240, 160)
|
||||
ui.set_initial_data(data)
|
||||
ui = new(user, src, "JanitorCart", name) // 240, 160
|
||||
ui.set_autoupdate(FALSE)
|
||||
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)
|
||||
if(!in_range(src, usr))
|
||||
return
|
||||
if(!isliving(usr))
|
||||
return
|
||||
var/mob/living/user = usr
|
||||
data["mybag"] = mybag ? capitalize(mybag.name) : null
|
||||
data["mybucket"] = mybucket ? capitalize(mybucket.name) : null
|
||||
data["mymop"] = mymop ? capitalize(mymop.name) : null
|
||||
data["myspray"] = myspray ? capitalize(myspray.name) : null
|
||||
data["myreplacer"] = myreplacer ? capitalize(myreplacer.name) : null
|
||||
data["signs"] = signs ? "[signs] sign\s" : null
|
||||
|
||||
if(href_list["take"])
|
||||
switch(href_list["take"])
|
||||
if("garbage")
|
||||
if(mybag)
|
||||
user.put_in_hands(mybag)
|
||||
to_chat(user, "<span class='notice'>You take [mybag] from [src].</span>")
|
||||
mybag = null
|
||||
if("mop")
|
||||
if(mymop)
|
||||
user.put_in_hands(mymop)
|
||||
to_chat(user, "<span class='notice'>You take [mymop] from [src].</span>")
|
||||
mymop = null
|
||||
if("spray")
|
||||
if(myspray)
|
||||
user.put_in_hands(myspray)
|
||||
to_chat(user, "<span class='notice'>You take [myspray] from [src].</span>")
|
||||
myspray = null
|
||||
if("replacer")
|
||||
if(myreplacer)
|
||||
user.put_in_hands(myreplacer)
|
||||
to_chat(user, "<span class='notice'>You take [myreplacer] from [src].</span>")
|
||||
myreplacer = null
|
||||
if("sign")
|
||||
if(signs)
|
||||
var/obj/item/clothing/suit/caution/Sign = locate() in src
|
||||
if(Sign)
|
||||
user.put_in_hands(Sign)
|
||||
to_chat(user, "<span class='notice'>You take \a [Sign] from [src].</span>")
|
||||
signs--
|
||||
else
|
||||
warning("[src] signs ([signs]) didn't match contents")
|
||||
signs = 0
|
||||
if("bucket")
|
||||
if(mybucket)
|
||||
mybucket.forceMove(get_turf(user))
|
||||
to_chat(user, "<span class='notice'>You unmount [mybucket] from [src].</span>")
|
||||
mybucket = null
|
||||
data["icons"] = tgui_icons
|
||||
return data
|
||||
|
||||
/obj/structure/janitorialcart/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
|
||||
switch(action)
|
||||
if("bag")
|
||||
if(mybag)
|
||||
usr.put_in_hands(mybag)
|
||||
to_chat(usr, "<span class='notice'>You take [mybag] from [src].</span>")
|
||||
mybag = null
|
||||
nullTguiIcon("mybag")
|
||||
else if(is_type_in_typecache(I, equippable_item_whitelist))
|
||||
equip_janicart_item(usr, I)
|
||||
if("mop")
|
||||
if(mymop)
|
||||
usr.put_in_hands(mymop)
|
||||
to_chat(usr, "<span class='notice'>You take [mymop] from [src].</span>")
|
||||
mymop = null
|
||||
nullTguiIcon("mymop")
|
||||
else if(is_type_in_typecache(I, equippable_item_whitelist))
|
||||
equip_janicart_item(usr, I)
|
||||
if("spray")
|
||||
if(myspray)
|
||||
usr.put_in_hands(myspray)
|
||||
to_chat(usr, "<span class='notice'>You take [myspray] from [src].</span>")
|
||||
myspray = null
|
||||
nullTguiIcon("myspray")
|
||||
else if(is_type_in_typecache(I, equippable_item_whitelist))
|
||||
equip_janicart_item(usr, I)
|
||||
if("replacer")
|
||||
if(myreplacer)
|
||||
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()
|
||||
updateUsrDialog()
|
||||
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/structure/janitorialcart/update_icon()
|
||||
overlays.Cut()
|
||||
@@ -229,11 +305,6 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
|
||||
if(signs)
|
||||
overlays += "cart_sign[signs]"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//This is called if the cart is caught in an explosion, or destroyed by weapon fire
|
||||
/obj/structure/janitorialcart/proc/spill(var/chance = 100)
|
||||
var/turf/dropspot = get_turf(src)
|
||||
@@ -275,6 +346,7 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
|
||||
mybag = null
|
||||
|
||||
update_icon()
|
||||
clearTguiIcons()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ obj/structure/safe/ex_act(severity)
|
||||
icon_state = "floorsafe"
|
||||
density = 0
|
||||
level = 1 //underfloor
|
||||
plane = TURF_PLANE
|
||||
plane = PLATING_PLANE
|
||||
layer = ABOVE_UTILITY
|
||||
|
||||
/obj/structure/safe/floor/Initialize()
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
if(!UWC)
|
||||
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
|
||||
if(selected_underwear && CanUseTopic(H, default_state))
|
||||
if(selected_underwear && CanUseTopic(H, GLOB.tgui_default_state))
|
||||
H.all_underwear[UWC.name] = selected_underwear
|
||||
H.hide_underwear[UWC.name] = FALSE
|
||||
. = TRUE
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
continue
|
||||
if(!SM.Adjacent(user) || !SM.Adjacent(target)) // Cleaving only hits mobs near the target mob and user.
|
||||
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.
|
||||
hit_mobs++
|
||||
|
||||
|
||||
Reference in New Issue
Block a user