Merge pull request #7200 from VOREStation/aro-offmap-rebase2

ITV Talon offmap spawn jobs
This commit is contained in:
Aronai Sieyes
2020-04-13 09:28:19 -04:00
committed by GitHub
118 changed files with 53024 additions and 1001 deletions

View File

@@ -176,7 +176,7 @@
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(

View File

@@ -151,7 +151,7 @@
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(

View File

@@ -128,7 +128,7 @@ Thus, the two variables affect pump operation are set in New():
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(

View File

@@ -107,7 +107,7 @@
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(

View File

@@ -263,7 +263,7 @@
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(

View File

@@ -93,7 +93,7 @@
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"area" = area_uid,

View File

@@ -70,10 +70,27 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define NETWORK_ALARM_ATMOS "Atmosphere Alarms"
#define NETWORK_ALARM_POWER "Power Alarms"
#define NETWORK_ALARM_FIRE "Fire Alarms"
#define NETWORK_TALON_HELMETS "TalonHelmets" //VOREStation Add
#define NETWORK_TALON_SHIP "TalonShip" //VOREStation Add
// Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them.
var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret", NETWORK_COMMUNICATORS)
#define TRANSMISSION_WIRE 0 //Is this ever used? I don't think it is.
#define TRANSMISSION_RADIO 1 //Radio transmissions (like airlock controller to pump)
#define TRANSMISSION_SUBSPACE 2 //Like headsets
#define TRANSMISSION_BLUESPACE 3 //Point-to-point links
#define SIGNAL_NORMAL 0 //Normal subspace signals
#define SIGNAL_SIMPLE 1 //Normal inter-machinery(?) signals
#define SIGNAL_FAKE 2 //Untrackable signals
#define SIGNAL_TEST 4 //Unlogged signals
#define DATA_NORMAL 0 //Normal data
#define DATA_INTERCOM 1 //Intercoms only
#define DATA_LOCAL 2 //Intercoms and SBRs
#define DATA_ANTAG 3 //Antag interception
#define DATA_FAKE 4 //Not from a real mob
//singularity defines
#define STAGE_ONE 1

View File

@@ -55,4 +55,6 @@
#define PTO_SCIENCE "Science"
#define PTO_EXPLORATION "Exploration"
#define PTO_CARGO "Cargo"
#define PTO_CIVILIAN "Civilian"
#define PTO_CIVILIAN "Civilian"
#define DEPARTMENT_TALON "ITV Talon"

View File

@@ -246,7 +246,7 @@
var/turf/speaker = get_turf(R)
if(speaker)
for(var/turf/T in hear(R.canhear_range,speaker))
speaker_coverage[T] = T
speaker_coverage[T] = R
// Try to find all the players who can hear the message

View File

@@ -125,6 +125,8 @@ var/const/EXP_FREQ = 1361
var/const/MED_I_FREQ = 1485
var/const/SEC_I_FREQ = 1475
var/const/TALON_FREQ = 1481 //VOREStation Add
var/list/radiochannels = list(
"Common" = PUB_FREQ,
"Science" = SCI_FREQ,
@@ -142,7 +144,8 @@ var/list/radiochannels = list(
"AI Private" = AI_FREQ,
"Entertainment" = ENT_FREQ,
"Medical(I)" = MED_I_FREQ,
"Security(I)" = SEC_I_FREQ
"Security(I)" = SEC_I_FREQ,
"Talon" = TALON_FREQ //VOREStation Add
)
// central command channels, i.e deathsquid & response teams
@@ -154,6 +157,8 @@ var/list/ANTAG_FREQS = list(SYND_FREQ, RAID_FREQ)
//Department channels, arranged lexically
var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, ENT_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ)
var/list/OFFMAP_FREQS = list(TALON_FREQ) //VOREStation Add
#define TRANSMISSION_WIRE 0
#define TRANSMISSION_RADIO 1
@@ -189,7 +194,10 @@ var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, ENT_FREQ, MED_FREQ, SEC
return "entradio"
if(frequency in DEPT_FREQS)
return "deptradio"
//VOREStation Add
if(frequency in OFFMAP_FREQS)
return "expradio"
//VOREStation Add End
return "radio"
/* filters */

View File

@@ -103,7 +103,7 @@ SUBSYSTEM_DEF(shuttles)
try_add_landmark_tag(shuttle_landmark_tag, O)
landmarks_still_needed -= shuttle_landmark_tag
else if(istype(shuttle_landmark, /obj/effect/shuttle_landmark/automatic)) //These find their sector automatically
O = map_sectors["[shuttle_landmark.z]"]
O = get_overmap_sector(get_z(shuttle_landmark))
O ? O.add_landmark(shuttle_landmark, shuttle_landmark.shuttle_restricted) : (landmarks_awaiting_sector += shuttle_landmark)
/datum/controller/subsystem/shuttles/proc/get_landmark(var/shuttle_landmark_tag)

View File

@@ -87,7 +87,7 @@ SUBSYSTEM_DEF(skybox)
res.overlays += base
if(global.using_map.use_overmap && settings.use_overmap_details)
var/obj/effect/overmap/visitable/O = map_sectors["[z]"]
var/obj/effect/overmap/visitable/O = get_overmap_sector(z)
if(istype(O))
var/image/overmap = image(settings.icon)
overmap.overlays += O.generate_skybox()

View File

@@ -5,11 +5,16 @@
/datum/datacore
var/name = "datacore"
var/medical[] = list()
var/general[] = list()
var/security[] = list()
//For general station crew
var/static/list/medical = list()
var/static/list/general = list()
var/static/list/security = list()
//For offmap spawns so they can have records accessible by certain things
var/static/list/hidden_medical = list()
var/static/list/hidden_general = list()
var/static/list/hidden_security = list()
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
var/locked[] = list()
var/static/list/locked = list()
/datum/datacore/proc/get_manifest(monochrome, OOC)
@@ -22,6 +27,7 @@
var/list/pla = new() //VOREStation Edit
var/list/civ = new()
var/list/bot = new()
var/list/off = new()
var/list/misc = new()
var/list/isactive = new()
var/dat = {"
@@ -46,7 +52,7 @@
if(OOC)
var/active = 0
for(var/mob/M in player_list)
if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
if(M.real_name == name && M.client && M.client.inactivity <= 10 MINUTES)
active = 1
break
isactive[name] = active ? "Active" : "Inactive"
@@ -84,6 +90,24 @@
if(!department && !(name in heads))
misc[name] = rank
//For the offmap spawns
if(OOC)
for(var/datum/data/record/t in hidden_general)
var/name = t.fields["name"]
var/rank = t.fields["rank"]
var/real_rank = make_list_rank(t.fields["real_rank"])
var/active = 0
for(var/mob/M in player_list)
if(M.real_name == name && M.client && M.client.inactivity <= 10 MINUTES)
active = 1
break
isactive[name] = active ? "Active" : "Inactive"
var/datum/job/J = SSjob.get_job(real_rank)
if(J?.offmap_spawn)
off[name] = rank
// Synthetics don't have actual records, so we will pull them from here.
for(var/mob/living/silicon/ai/ai in mob_list)
bot[ai.name] = "Artificial Intelligence"
@@ -142,6 +166,12 @@
for(name in bot)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[bot[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
// offmap spawners
if(off.len > 0)
dat += "<tr><th colspan=3>Offmap Spawns</th></tr>"
for(name in off)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[off[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
// misc guys
if(misc.len > 0)
dat += "<tr><th colspan=3>Miscellaneous</th></tr>"
@@ -154,6 +184,117 @@
dat = replacetext(dat, "\t", "")
return dat
/*
We can't just insert in HTML into the nanoUI so we need the raw data to play with.
Instead of creating this list over and over when someone leaves their PDA open to the page
we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change
using /datum/datacore/proc/manifest_inject( ), or manifest_insert( )
*/
var/global/list/PDA_Manifest = list()
/datum/datacore/proc/get_manifest_list()
if(PDA_Manifest.len)
return
var/list/heads = list()
var/list/sec = list()
var/list/eng = list()
var/list/med = list()
var/list/sci = list()
var/list/car = list()
var/list/pla = list() // Planetside crew: Explorers, Pilots, S&S
var/list/civ = list()
var/list/bot = list()
var/list/misc = list()
for(var/datum/data/record/t in data_core.general)
var/name = sanitize(t.fields["name"])
var/rank = sanitize(t.fields["rank"])
var/real_rank = make_list_rank(t.fields["real_rank"])
var/isactive = t.fields["p_stat"]
var/department = 0
var/depthead = 0 // Department Heads will be placed at the top of their lists.
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_COMMAND))
heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
depthead = 1
if(rank=="Colony Director" && heads.len != 1)
heads.Swap(1,heads.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SECURITY))
sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && sec.len != 1)
sec.Swap(1,sec.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_ENGINEERING))
eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && eng.len != 1)
eng.Swap(1,eng.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_MEDICAL))
med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && med.len != 1)
med.Swap(1,med.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_RESEARCH))
sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && sci.len != 1)
sci.Swap(1,sci.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_PLANET))
pla[++pla.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CARGO))
car[++car.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && car.len != 1)
car.Swap(1,car.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CIVILIAN))
civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && civ.len != 1)
civ.Swap(1,civ.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SYNTHETIC))
bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(!department && !(name in heads))
misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive)
// Synthetics don't have actual records, so we will pull them from here.
// Synths don't have records, which is the means by which isactive is retrieved, so I'm hardcoding it to active, don't really have any better means
for(var/mob/living/silicon/ai/ai in mob_list)
bot[++bot.len] = list("name" = ai.real_name, "rank" = "Artificial Intelligence", "active" = "Active")
for(var/mob/living/silicon/robot/robot in mob_list)
// No combat/syndicate cyborgs, no drones, and no AI shells.
if(robot.scrambledcodes || robot.shell || (robot.module && robot.module.hide_on_manifest))
continue
bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active")
PDA_Manifest = list(
list("cat" = "Command", "elems" = heads),
list("cat" = "Security", "elems" = sec),
list("cat" = "Engineering", "elems" = eng),
list("cat" = "Medical", "elems" = med),
list("cat" = "Science", "elems" = sci),
list("cat" = "Cargo", "elems" = car),
list("cat" = "Exploration", "elems" = pla), // VOREStation Edit
list("cat" = "Civilian", "elems" = civ),
list("cat" = "Silicon", "elems" = bot),
list("cat" = "Miscellaneous", "elems" = misc)
)
return
/datum/datacore/proc/manifest()
spawn()
for(var/mob/living/carbon/human/H in player_list)
@@ -187,10 +328,13 @@
/datum/datacore/proc/manifest_inject(var/mob/living/carbon/human/H)
if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1))
var/assignment = GetAssignment(H)
var/hidden
var/datum/job/J = SSjob.get_job(assignment)
hidden = J?.offmap_spawn
var/id = generate_record_id()
//General Record
var/datum/data/record/G = CreateGeneralRecord(H, id)
var/datum/data/record/G = CreateGeneralRecord(H, id, hidden)
G.fields["name"] = H.real_name
G.fields["real_rank"] = H.mind.assigned_role
G.fields["rank"] = assignment
@@ -212,7 +356,7 @@
G.fields["notes"] = H.gen_record
//Medical Record
var/datum/data/record/M = CreateMedicalRecord(H.real_name, id)
var/datum/data/record/M = CreateMedicalRecord(H.real_name, id, hidden)
M.fields["b_type"] = H.b_type
M.fields["b_dna"] = H.dna.unique_enzymes
M.fields["id_gender"] = gender2text(H.identifying_gender)
@@ -224,7 +368,7 @@
M.fields["notes"] = H.med_record
//Security Record
var/datum/data/record/S = CreateSecurityRecord(H.real_name, id)
var/datum/data/record/S = CreateSecurityRecord(H.real_name, id, hidden)
if(H.get_FBP_type())
S.fields["brain_type"] = H.get_FBP_type()
else
@@ -257,6 +401,7 @@
L.fields["image"] = icon(cached_character_icon(H), dir = SOUTH)
L.fields["antagfac"] = H.antag_faction
L.fields["antagvis"] = H.antag_vis
L.fields["offmap"] = hidden
if(H.exploit_record && !jobban_isbanned(H, "Records"))
L.fields["exploit_record"] = H.exploit_record
else
@@ -267,7 +412,7 @@
/proc/generate_record_id()
return add_zero(num2hex(rand(1, 65535)), 4) //no point generating higher numbers because of the limitations of num2hex
/datum/datacore/proc/CreateGeneralRecord(var/mob/living/carbon/human/H, var/id)
/datum/datacore/proc/CreateGeneralRecord(var/mob/living/carbon/human/H, var/id, var/hidden)
ResetPDAManifest()
var/icon/front
var/icon/side
@@ -301,11 +446,14 @@
G.fields["photo_front"] = front
G.fields["photo_side"] = side
G.fields["notes"] = "No notes found."
general += G
if(hidden)
hidden_general += G
else
general += G
return G
/datum/datacore/proc/CreateSecurityRecord(var/name, var/id)
/datum/datacore/proc/CreateSecurityRecord(var/name, var/id, var/hidden)
ResetPDAManifest()
var/datum/data/record/R = new /datum/data/record()
R.name = "Security Record #[id]"
@@ -319,11 +467,14 @@
R.fields["ma_crim_d"] = "No major crime convictions."
R.fields["notes"] = "No notes."
R.fields["notes"] = "No notes."
data_core.security += R
if(hidden)
hidden_security += R
else
security += R
return R
/datum/datacore/proc/CreateMedicalRecord(var/name, var/id)
/datum/datacore/proc/CreateMedicalRecord(var/name, var/id, var/hidden)
ResetPDAManifest()
var/datum/data/record/M = new()
M.name = "Medical Record #[id]"
@@ -342,7 +493,10 @@
M.fields["cdi"] = "None"
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
M.fields["notes"] = "No notes found."
data_core.medical += M
if(hidden)
hidden_medical += M
else
medical += M
return M

View File

@@ -14,10 +14,25 @@ var/global/datum/repository/cameras/camera_repository = new()
networks = list()
..()
/datum/repository/cameras/proc/cameras_in_network(var/network)
/datum/repository/cameras/proc/cameras_in_network(var/network, var/list/zlevels)
setup_cache()
var/list/network_list = networks[network]
return network_list
if(LAZYLEN(zlevels))
var/list/filtered_cameras = list()
for(var/list/C in network_list)
//Camera is marked as always-visible
if(C["omni"])
filtered_cameras[++filtered_cameras.len] = C
continue
//Camera might be in an adjacent zlevel
var/camz = C["z"]
if(!camz) //It's inside something (helmet, communicator, etc) or nullspace or who knows
camz = get_z(locate(C["camera"]) in cameranet.cameras)
if(camz in zlevels)
filtered_cameras[++filtered_cameras.len] = C //Can't add lists to lists with +=
return filtered_cameras
else
return network_list
/datum/repository/cameras/proc/setup_cache()
if(!invalidated)

View File

@@ -52,120 +52,6 @@
return copytext(rank, 2+length(prefix))
return rank
/*
We can't just insert in HTML into the nanoUI so we need the raw data to play with.
Instead of creating this list over and over when someone leaves their PDA open to the page
we'll only update it when it changes. The PDA_Manifest global list is zeroed out upon any change
using /datum/datacore/proc/manifest_inject( ), or manifest_insert( )
*/
var/global/list/PDA_Manifest = list()
/datum/datacore/proc/get_manifest_list()
if(PDA_Manifest.len)
return
var/list/heads = list()
var/list/sec = list()
var/list/eng = list()
var/list/med = list()
var/list/sci = list()
var/list/car = list()
var/list/pla = list() // Planetside crew: Explorers, Pilots, S&S
var/list/civ = list()
var/list/bot = list()
var/list/misc = list()
for(var/datum/data/record/t in data_core.general)
var/name = sanitize(t.fields["name"])
var/rank = sanitize(t.fields["rank"])
var/real_rank = make_list_rank(t.fields["real_rank"])
var/isactive = t.fields["p_stat"]
var/department = 0
var/depthead = 0 // Department Heads will be placed at the top of their lists.
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_COMMAND))
heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
depthead = 1
if(rank=="Colony Director" && heads.len != 1)
heads.Swap(1,heads.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SECURITY))
sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && sec.len != 1)
sec.Swap(1,sec.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_ENGINEERING))
eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && eng.len != 1)
eng.Swap(1,eng.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_MEDICAL))
med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && med.len != 1)
med.Swap(1,med.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_RESEARCH))
sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && sci.len != 1)
sci.Swap(1,sci.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_PLANET))
pla[++pla.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CARGO))
car[++car.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && car.len != 1)
car.Swap(1,car.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CIVILIAN))
civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && civ.len != 1)
civ.Swap(1,civ.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SYNTHETIC))
bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(!department && !(name in heads))
misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive)
// Synthetics don't have actual records, so we will pull them from here.
// Synths don't have records, which is the means by which isactive is retrieved, so I'm hardcoding it to active, don't really have any better means
for(var/mob/living/silicon/ai/ai in mob_list)
bot[++bot.len] = list("name" = ai.real_name, "rank" = "Artificial Intelligence", "active" = "Active")
for(var/mob/living/silicon/robot/robot in mob_list)
// No combat/syndicate cyborgs, no drones, and no AI shells.
if(robot.scrambledcodes || robot.shell || (robot.module && robot.module.hide_on_manifest))
continue
bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active")
PDA_Manifest = list(
list("cat" = "Command", "elems" = heads),
list("cat" = "Security", "elems" = sec),
list("cat" = "Engineering", "elems" = eng),
list("cat" = "Medical", "elems" = med),
list("cat" = "Science", "elems" = sci),
list("cat" = "Cargo", "elems" = car),
list("cat" = "Exploration", "elems" = pla), // VOREStation Edit
list("cat" = "Civilian", "elems" = civ),
list("cat" = "Silicon", "elems" = bot),
list("cat" = "Miscellaneous", "elems" = misc)
)
return
/obj/effect/laser
name = "laser"
desc = "IT BURNS!!!"

View File

@@ -32,7 +32,7 @@
title = "Security Announcement"
announcement_type = "Security Announcement"
/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0)
/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0, zlevel)
if(!message)
return
var/message_title = new_title ? new_title : title
@@ -42,28 +42,32 @@
message = sanitize(message, extra = 0)
message_title = sanitizeSafe(message_title)
Message(message, message_title)
var/list/zlevels
if(zlevel)
zlevels = using_map.get_map_levels(zlevel, TRUE)
Message(message, message_title, zlevels)
if(do_newscast)
NewsCast(message, message_title)
Sound(message_sound)
Sound(message_sound, zlevels)
Log(message, message_title)
datum/announcement/proc/Message(message as text, message_title as text)
global_announcer.autosay("<span class='alert'>[message_title]:</span> [message]", announcer ? announcer : ANNOUNCER_NAME)
datum/announcement/proc/Message(var/message as text, var/message_title as text, var/list/zlevels)
global_announcer.autosay("<span class='alert'>[message_title]:</span> [message]", announcer ? announcer : ANNOUNCER_NAME, zlevels)
datum/announcement/minor/Message(message as text, message_title as text)
global_announcer.autosay(message, announcer ? announcer : ANNOUNCER_NAME)
datum/announcement/minor/Message(var/message as text, var/message_title as text, var/list/zlevels)
global_announcer.autosay(message, announcer ? announcer : ANNOUNCER_NAME, zlevels)
datum/announcement/priority/Message(message as text, message_title as text)
global_announcer.autosay("<span class='alert'>[message_title]:</span> [message]", announcer ? announcer : ANNOUNCER_NAME)
datum/announcement/priority/Message(var/message as text, var/message_title as text, var/list/zlevels)
global_announcer.autosay("<span class='alert'>[message_title]:</span> [message]", announcer ? announcer : ANNOUNCER_NAME, zlevels)
datum/announcement/priority/command/Message(message as text, message_title as text)
global_announcer.autosay("<span class='alert'>[command_name()] - [message_title]:</span> [message]", ANNOUNCER_NAME)
datum/announcement/priority/command/Message(var/message as text, var/message_title as text, var/list/zlevels)
global_announcer.autosay("<span class='alert'>[command_name()] - [message_title]:</span> [message]", ANNOUNCER_NAME, zlevels)
datum/announcement/priority/security/Message(message as text, message_title as text)
global_announcer.autosay("<span class='alert'>[message_title]:</span> [message]", ANNOUNCER_NAME)
datum/announcement/priority/security/Message(var/message as text, var/message_title as text, var/list/zlevels)
global_announcer.autosay("<span class='alert'>[message_title]:</span> [message]", ANNOUNCER_NAME, zlevels)
datum/announcement/proc/NewsCast(message as text, message_title as text)
datum/announcement/proc/NewsCast(var/message as text, var/message_title as text)
if(!newscast)
return
@@ -75,15 +79,18 @@ datum/announcement/proc/NewsCast(message as text, message_title as text)
news.can_be_redacted = 0
announce_newscaster_news(news)
datum/announcement/proc/PlaySound(var/message_sound)
datum/announcement/proc/PlaySound(var/message_sound, var/list/zlevels)
if(!message_sound)
return
for(var/mob/M in player_list)
if(zlevels && !(M.z in zlevels))
continue
if(!istype(M,/mob/new_player) && !isdeaf(M))
M << message_sound
datum/announcement/proc/Sound(var/message_sound)
PlaySound(message_sound)
datum/announcement/proc/Sound(var/message_sound, var/list/zlevels)
PlaySound(message_sound, zlevels)
datum/announcement/priority/Sound(var/message_sound)
if(message_sound)
@@ -107,11 +114,12 @@ datum/announcement/proc/Log(message as text, message_title as text)
/proc/ion_storm_announcement()
command_announcement.Announce("It has come to our attention that \the [station_name()] passed through an ion storm. Please monitor all electronic equipment for malfunctions.", "Anomaly Alert")
/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message)
/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message, var/channel = "Common", var/zlevel)
if (ticker.current_state == GAME_STATE_PLAYING)
var/list/zlevels = zlevel ? using_map.get_map_levels(zlevel, TRUE) : null
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
AnnounceArrivalSimple(character.real_name, rank, join_message)
AnnounceArrivalSimple(character.real_name, rank, join_message, channel, zlevels)
/proc/AnnounceArrivalSimple(var/name, var/rank = "visitor", var/join_message = "will arrive at the station shortly", new_sound = 'sound/misc/notice3.ogg') //VOREStation Edit - Remove shuttle reference
global_announcer.autosay("[name], [rank], [join_message].", "Arrivals Announcement Computer")
/proc/AnnounceArrivalSimple(var/name, var/rank = "visitor", var/join_message = "will arrive at the station shortly", var/channel = "Common", var/list/zlevels)
global_announcer.autosay("[name], [rank], [join_message].", "Arrivals Announcement Computer", channel, zlevels)

View File

@@ -10,3 +10,10 @@ var/const/access_pilot = 67
id = access_pilot
desc = "Pilot"
region = ACCESS_REGION_SUPPLY
/var/const/access_talon = 301
/datum/access/talon
id = access_talon
desc = "Talon"
access_type = ACCESS_TYPE_PRIVATE

View File

@@ -30,6 +30,8 @@
var/outfit_type // What outfit datum does this job use in its default title?
var/offmap_spawn = FALSE // Do we require weird and special spawning and datacore handling?
// Description of the job's role and minimum responsibilities.
var/job_description = "This Job doesn't have a description! Please report it!"
@@ -67,7 +69,7 @@
//give them an account in the station database
var/money_amount = (rand(15,40) + rand(15,40)) * income * economic_modifier * ECO_MODIFIER //VOREStation Edit - Smoothed peaks, ECO_MODIFIER rather than per-species ones.
var/datum/money_account/M = create_account(H.real_name, money_amount, null)
var/datum/money_account/M = create_account(H.real_name, money_amount, null, offmap_spawn)
if(H.mind)
var/remembered_info = ""
remembered_info += "<b>Your account number is:</b> #[M.account_number]<br>"

View File

@@ -357,7 +357,11 @@ var/global/datum/controller/occupations/job_master
else
var/list/spawn_props = LateSpawn(H.client, rank)
var/turf/T = spawn_props["turf"]
H.forceMove(T)
if(!T)
to_chat(H, "<span class='critical'>You were unable to be spawned at your chosen late-join spawnpoint. Please verify your job/spawn point combination makes sense, and try another one.</span>")
return
else
H.forceMove(T)
// Moving wheelchair if they have one
if(H.buckled && istype(H.buckled, /obj/structure/bed/chair/wheelchair))
@@ -458,8 +462,8 @@ var/global/datum/controller/occupations/job_master
if("AI")
return H
if("Colony Director")
var/sound/announce_sound = (ticker.current_state <= GAME_STATE_SETTING_UP)? null : sound('sound/misc/boatswain.ogg', volume=20)
captain_announcement.Announce("All hands, [alt_title ? alt_title : "Colony Director"] [H.real_name] on deck!", new_sound=announce_sound)
var/sound/announce_sound = (ticker.current_state <= GAME_STATE_SETTING_UP) ? null : sound('sound/misc/boatswain.ogg', volume=20)
captain_announcement.Announce("All hands, [alt_title ? alt_title : "Colony Director"] [H.real_name] on deck!", new_sound = announce_sound, zlevel = H.z)
//Deferred item spawning.
if(spawn_in_storage && spawn_in_storage.len)
@@ -608,12 +612,20 @@ var/global/datum/controller/occupations/job_master
/datum/controller/occupations/proc/LateSpawn(var/client/C, var/rank)
var/datum/spawnpoint/spawnpos
var/fail_deadly = FALSE
var/datum/job/J = SSjob.get_job(rank)
fail_deadly = J?.offmap_spawn
//Spawn them at their preferred one
if(C && C.prefs.spawnpoint)
if(!(C.prefs.spawnpoint in using_map.allowed_spawns))
to_chat(C, "<span class='warning'>Your chosen spawnpoint ([C.prefs.spawnpoint]) is unavailable for the current map. Spawning you at one of the enabled spawn points instead.</span>")
spawnpos = null
if(fail_deadly)
to_chat(C, "<span class='warning'>Your chosen spawnpoint is unavailable for this map and your job requires a specific spawnpoint. Please correct your spawn point choice.</span>")
return
else
to_chat(C, "<span class='warning'>Your chosen spawnpoint ([C.prefs.spawnpoint]) is unavailable for the current map. Spawning you at one of the enabled spawn points instead.</span>")
spawnpos = null
else
spawnpos = spawntypes[C.prefs.spawnpoint]
@@ -623,12 +635,16 @@ var/global/datum/controller/occupations/job_master
if(spawnpos.check_job_spawning(rank))
.["turf"] = spawnpos.get_spawn_position()
.["msg"] = spawnpos.msg
.["channel"] = spawnpos.announce_channel
else
if(fail_deadly)
to_chat(C, "<span class='warning'>Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Please correct your spawn point choice.</span>")
return
to_chat(C, "Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead.")
var/spawning = pick(latejoin)
.["turf"] = get_turf(spawning)
.["msg"] = "will arrive at the station shortly" //VOREStation Edit - Grammar but mostly 'shuttle' reference removal, and this also applies to notified spawn-character verb use
else
else if(!fail_deadly)
var/spawning = pick(latejoin)
.["turf"] = get_turf(spawning)
.["msg"] = "has arrived on the station"

View File

@@ -387,7 +387,7 @@
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = command
@@ -449,7 +449,7 @@
var/datum/signal/alert_signal = new
alert_signal.source = src
alert_signal.transmission_method = 1
alert_signal.transmission_method = TRANSMISSION_RADIO
alert_signal.data["zone"] = alarm_area.name
alert_signal.data["type"] = "Atmospheric"

View File

@@ -29,7 +29,7 @@
/obj/machinery/air_sensor/process()
if(on)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.data["tag"] = id_tag
signal.data["timestamp"] = world.time
@@ -212,7 +212,7 @@ obj/machinery/computer/general_air_control/Destroy()
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
if(href_list["in_refresh_status"])
input_info = null
@@ -322,7 +322,7 @@ obj/machinery/computer/general_air_control/Destroy()
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
if(href_list["in_refresh_status"])
input_info = null
@@ -383,7 +383,7 @@ obj/machinery/computer/general_air_control/Destroy()
injecting = 1
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
@@ -445,7 +445,7 @@ obj/machinery/computer/general_air_control/Destroy()
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
@@ -463,7 +463,7 @@ obj/machinery/computer/general_air_control/Destroy()
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
@@ -478,7 +478,7 @@ obj/machinery/computer/general_air_control/Destroy()
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,

View File

@@ -67,7 +67,7 @@
var/datum/signal/signal = new
signal.source = src
signal.transmission_method = 1
signal.transmission_method = TRANSMISSION_RADIO
signal.data = list(
"tag" = id,
"device" = "AM",

View File

@@ -33,6 +33,7 @@
var/busy = 0
var/on_open_network = 0
var/always_visible = FALSE //Visable from any map, good for entertainment network cameras
var/affected_by_emp_until = 0
@@ -472,6 +473,7 @@
cam["name"] = sanitize(c_tag)
cam["deact"] = !can_use()
cam["camera"] = "\ref[src]"
cam["omni"] = always_visible
cam["x"] = x
cam["y"] = y
cam["z"] = z

View File

@@ -102,6 +102,7 @@ var/global/list/engineering_networks = list(
/obj/machinery/camera/network/thunder
network = list(NETWORK_THUNDER)
invuln = 1
always_visible = TRUE
// EMP

View File

@@ -43,11 +43,14 @@
data["current_camera"] = current_camera ? current_camera.nano_structure() : null
data["current_network"] = current_network
data["networks"] = network ? network : list()
var/map_levels = using_map.get_map_levels(src.z, TRUE)
data["map_levels"] = map_levels
if(current_network)
data["cameras"] = camera_repository.cameras_in_network(current_network)
data["cameras"] = camera_repository.cameras_in_network(current_network, map_levels)
if(current_camera)
switch_to_camera(user, current_camera)
data["map_levels"] = using_map.get_map_levels(src.z)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
@@ -91,9 +94,6 @@
. = ..()
/obj/machinery/computer/security/attack_hand(var/mob/user as mob)
if (using_map && !(src.z in using_map.contact_levels))
to_chat(user, "<span class='danger'>Unable to establish a connection:</span> You're too far away from the station!")
return
if(stat & (NOPOWER|BROKEN)) return
if(!isAI(user))

View File

@@ -546,7 +546,7 @@
var/datum/signal/status_signal = new
status_signal.source = src
status_signal.transmission_method = 1
status_signal.transmission_method = TRANSMISSION_RADIO
status_signal.data["command"] = command
switch(command)

View File

@@ -8,7 +8,7 @@
idle_power_usage = 250
active_power_usage = 500
circuit = /obj/item/weapon/circuitboard/crew
var/datum/nano_module/crew_monitor/crew_monitor
var/datum/nano_module/program/crew_monitor/crew_monitor
/obj/machinery/computer/crew/New()
crew_monitor = new(src)

View File

@@ -121,7 +121,7 @@ var/prison_shuttle_timeleft = 0
if(!frequency) return
var/datum/signal/status_signal = new
status_signal.source = src
status_signal.transmission_method = 1
status_signal.transmission_method = TRANSMISSION_RADIO
status_signal.data["command"] = command
frequency.post_signal(src, status_signal)
return

View File

@@ -421,7 +421,7 @@
var/datum/signal/status_signal = new
status_signal.source = src
status_signal.transmission_method = 1
status_signal.transmission_method = TRANSMISSION_RADIO
status_signal.data["command"] = command
frequency.post_signal(src, status_signal)

View File

@@ -219,6 +219,7 @@
var/on_enter_occupant_message = "You feel cool air surround you. You go numb as your senses turn inward."
var/on_store_visible_message_1 = "hums and hisses as it moves" //We need two variables because byond doesn't let us have variables inside strings at compile-time.
var/on_store_visible_message_2 = "into storage."
var/announce_channel = "Common"
var/allow_occupant_types = list(/mob/living/carbon/human)
var/disallow_occupant_types = list()
@@ -519,7 +520,7 @@
control_computer._admin_logs += "[key_name(to_despawn)] ([to_despawn.mind.role_alt_title]) at [stationtime2text()]"
log_and_message_admins("[key_name(to_despawn)] ([to_despawn.mind.role_alt_title]) entered cryostorage.")
announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]")
announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE))
//visible_message("<span class='notice'>\The [initial(name)] hums and hisses as it moves [to_despawn.real_name] into storage.</span>", 3)
visible_message("<span class='notice'>\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2].</span>", 3)

View File

@@ -91,7 +91,7 @@ obj/machinery/door/airlock/proc/command_completed(var/command)
obj/machinery/door/airlock/proc/send_status(var/bumped = 0)
if(radio_connection)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.data["tag"] = id_tag
signal.data["timestamp"] = world.time
@@ -172,7 +172,7 @@ obj/machinery/airlock_sensor/update_icon()
obj/machinery/airlock_sensor/attack_hand(mob/user)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.data["tag"] = master_tag
signal.data["command"] = command
@@ -186,7 +186,7 @@ obj/machinery/airlock_sensor/process()
if(abs(pressure - previousPressure) > 0.001 || previousPressure == null)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.data["tag"] = id_tag
signal.data["timestamp"] = world.time
signal.data["pressure"] = num2text(pressure)
@@ -263,7 +263,7 @@ obj/machinery/access_button/attack_hand(mob/user)
else if(radio_connection)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.data["tag"] = master_tag
signal.data["command"] = command

View File

@@ -275,7 +275,7 @@
// Prepare signal beforehand, because this is a radio operation
var/datum/signal/signal = new
signal.transmission_method = 1 // radio transmission
signal.transmission_method = TRANSMISSION_RADIO // radio transmission
signal.source = src
signal.frequency = frequency
signal.data["code"] = code
@@ -341,7 +341,7 @@
// Prepare the radio signal
var/datum/signal/signal = new
signal.transmission_method = 1 // radio transmission
signal.transmission_method = TRANSMISSION_RADIO // radio transmission
signal.source = src
signal.frequency = frequency
signal.data["code"] = code

View File

@@ -23,6 +23,12 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
produces_heat = 0
delay = 7
circuit = /obj/item/weapon/circuitboard/telecomms/broadcaster
//Vars only used if you're using the overmap
var/overmap_range = 0
var/overmap_range_min = 0
var/overmap_range_max = 5
//Linked bluespace radios
var/list/linked_radios_weakrefs = list()
/obj/machinery/telecomms/processor/Initialize()
. = ..()
@@ -34,6 +40,11 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
component_parts += new /obj/item/weapon/stock_parts/micro_laser/high(src)
component_parts += new /obj/item/stack/cable_coil(src, 1)
/obj/machinery/telecomms/broadcaster/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R))
return
linked_radios_weakrefs |= weakref(R)
/obj/machinery/telecomms/broadcaster/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
// Don't broadcast rejected signals
if(signal.data["reject"])
@@ -58,46 +69,51 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
if(signal.data["slow"] > 0)
sleep(signal.data["slow"]) // simulate the network lag if necessary
signal.data["level"] |= listening_level
signal.data["level"] |= using_map.get_map_levels(listening_level, TRUE, overmap_range)
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
/** #### - Normal Broadcast - #### **/
if(signal.data["type"] == 0)
if(signal.data["type"] == SIGNAL_NORMAL)
/* ###### Broadcast a message using signal.data ###### */
Broadcast_Message(signal.data["connection"], signal.data["mob"],
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"],,
signal.data["realname"], signal.data["vname"], DATA_NORMAL,
signal.data["compression"], signal.data["level"], signal.frequency,
signal.data["verb"], signal.data["language"] )
signal.data["verb"], signal.data["language"], forced_radios)
/** #### - Simple Broadcast - #### **/
if(signal.data["type"] == 1)
if(signal.data["type"] == SIGNAL_SIMPLE)
/* ###### Broadcast a message using signal.data ###### */
Broadcast_SimpleMessage(signal.data["name"], signal.frequency,
signal.data["message"],null, null,
signal.data["compression"], listening_level)
signal.data["message"], DATA_NORMAL, null,
signal.data["compression"], listening_level, forced_radios)
/** #### - Artificial Broadcast - #### **/
// (Imitates a mob)
if(signal.data["type"] == 2)
if(signal.data["type"] == SIGNAL_FAKE)
/* ###### Broadcast a message using signal.data ###### */
// Parameter "data" as 4: AI can't track this person/mob
// Parameter "data" as DATA_FAKE: AI can't track this person/mob
Broadcast_Message(signal.data["connection"], signal.data["mob"],
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"], 4, signal.data["compression"], signal.data["level"], signal.frequency,
signal.data["verb"], signal.data["language"])
signal.data["realname"], signal.data["vname"], DATA_FAKE,
signal.data["compression"], signal.data["level"], signal.frequency,
signal.data["verb"], signal.data["language"], forced_radios)
if(!message_delay)
message_delay = 1
@@ -118,6 +134,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/*
Basically just an empty shell for receiving and broadcasting radio messages. Not
very flexible, but it gets the job done.
NOTE: This AIO device listens on *every* zlevel (it does not even check)
*/
/obj/machinery/telecomms/allinone
@@ -126,15 +143,98 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
icon_state = "comm_server"
desc = "A compact machine used for portable subspace telecommuniations processing."
density = 1
use_power = USE_POWER_IDLE
idle_power_usage = 20
anchored = 1
use_power = USE_POWER_OFF
idle_power_usage = 0
machinetype = 6
produces_heat = 0
var/intercept = 0 // if nonzero, broadcasts all messages to syndicate channel
var/overmap_range = 0 //Same turf
var/list/linked_radios_weakrefs = list()
/obj/machinery/telecomms/allinone/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R))
return
linked_radios_weakrefs |= weakref(R)
/obj/machinery/telecomms/allinone/receive_signal(datum/signal/signal)
// Has to be on to receive messages
if(!on)
return
// Why did you use this subtype?
if(!using_map.use_overmap)
return
// Someone else handling it?
if(signal.data["done"])
return
// Where are we able to hear from (and talk to, since we're AIO) anyway?
var/map_levels = using_map.get_map_levels(z, TRUE, overmap_range)
//Bluespace can skip this check
if(signal.transmission_method != TRANSMISSION_BLUESPACE)
var/list/signal_levels = list()
signal_levels += signal.data["level"] //If it's text/number, it'll be the only entry, if it's a list, it'll get combined
var/list/overlap = map_levels & signal_levels //Returns a list of similar levels
if(!overlap.len)
return
if(is_freq_listening(signal)) // detect subspace signals
signal.data["done"] = 1 // mark the signal as being broadcasted since we're a broadcaster
signal.data["compression"] = 0 // decompress since we're a processor
// Search for the original signal and mark it as done as well
var/datum/signal/original = signal.data["original"]
if(original)
original.data["done"] = 1
// For some reason level is both used as a list and not a list, and now it needs to be a list.
signal.data["level"] = map_levels
if(signal.data["slow"] > 0)
sleep(signal.data["slow"]) // simulate the network lag if necessary
/* ###### Broadcast a message using signal.data ###### */
var/datum/radio_frequency/connection = signal.data["connection"]
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
Broadcast_Message(
signal.data["connection"],
signal.data["mob"],
signal.data["vmask"],
signal.data["vmessage"],
signal.data["radio"],
signal.data["message"],
signal.data["name"],
signal.data["job"],
signal.data["realname"],
signal.data["vname"],
DATA_NORMAL,
signal.data["compression"],
signal.data["level"],
connection.frequency,
signal.data["verb"],
signal.data["language"],
forced_radios
)
//Antag version with unlimited range (doesn't even check) and uses no power, to enable antag comms to work anywhere.
/obj/machinery/telecomms/allinone/antag
use_power = USE_POWER_OFF
idle_power_usage = 0
/obj/machinery/telecomms/allinone/antag/receive_signal(datum/signal/signal)
if(!on) // has to be on to receive messages
return
@@ -159,23 +259,29 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/datum/radio_frequency/connection = signal.data["connection"]
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
if(connection.frequency in ANTAG_FREQS) // if antag broadcast, just
Broadcast_Message(signal.data["connection"], signal.data["mob"],
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency,
signal.data["verb"], signal.data["language"])
signal.data["realname"], signal.data["vname"], DATA_NORMAL,
signal.data["compression"], list(0), connection.frequency,
signal.data["verb"], signal.data["language"], forced_radios)
else
if(intercept)
Broadcast_Message(signal.data["connection"], signal.data["mob"],
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"], 3, signal.data["compression"], list(0), connection.frequency,
signal.data["verb"], signal.data["language"])
signal.data["realname"], signal.data["vname"], DATA_ANTAG,
signal.data["compression"], list(0), connection.frequency,
signal.data["verb"], signal.data["language"], forced_radios)
/**
@@ -237,7 +343,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/proc/Broadcast_Message(var/datum/radio_frequency/connection, var/mob/M,
var/vmask, var/vmessage, var/obj/item/device/radio/radio,
var/message, var/name, var/job, var/realname, var/vname,
var/data, var/compression, var/list/level, var/freq, var/verbage = "says", var/datum/language/speaking = null)
var/data, var/compression, var/list/level, var/freq, var/verbage = "says",
var/datum/language/speaking = null, var/list/forced_radios)
/* ###### Prepare the radio connection ###### */
@@ -246,17 +353,22 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/list/obj/item/device/radio/radios = list()
for(var/obj/item/device/radio/R in forced_radios)
//Cursory check to ensure they are 'on' and stuff
if(R.receive_range(display_freq, list(0)))
radios |= R
// --- Broadcast only to intercom devices ---
if(data == 1)
if(data == DATA_INTERCOM)
for (var/obj/item/device/radio/intercom/R in connection.devices["[RADIO_CHAT]"])
if(R.receive_range(display_freq, level) > -1)
radios += R
radios |= R
// --- Broadcast only to intercoms and station-bounced radios ---
else if(data == 2)
else if(data == DATA_LOCAL)
for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"])
@@ -264,16 +376,16 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
continue
if(R.receive_range(display_freq, level) > -1)
radios += R
radios |= R
// --- Broadcast to antag radios! ---
else if(data == 3)
else if(data == DATA_ANTAG)
for(var/antag_freq in ANTAG_FREQS)
var/datum/radio_frequency/antag_connection = radio_controller.return_frequency(antag_freq)
for (var/obj/item/device/radio/R in antag_connection.devices["[RADIO_CHAT]"])
if(R.receive_range(antag_freq, level) > -1)
radios += R
radios |= R
// --- Broadcast to ALL radio devices ---
@@ -281,7 +393,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"])
if(R.receive_range(display_freq, level) > -1)
radios += R
radios |= R
// Get a list of mobs who can hear from the radios we collected.
var/list/receive = get_mobs_in_radio_ranges(radios)
@@ -307,7 +419,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
continue
// Ghosts hearing all radio chat don't want to hear syndicate intercepts, they're duplicates
if(data == 3 && istype(R, /mob/observer/dead) && R.is_preference_enabled(/datum/client_preference/ghost_radio))
if(data == DATA_ANTAG && istype(R, /mob/observer/dead) && R.is_preference_enabled(/datum/client_preference/ghost_radio))
continue
// --- Check for compression ---
@@ -346,7 +458,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/freq_text = get_frequency_name(display_freq)
var/part_b_extra = ""
if(data == 3) // intercepted radio message
if(data == DATA_ANTAG) // intercepted radio message
part_b_extra = " <i>(Intercepted)</i>"
var/part_a = "<span class='[frequency_span_class(display_freq)]'>[bicon(radio)]<b>\[[freq_text]\][part_b_extra]</b> <span class='name'>" // goes in the actual output
@@ -438,7 +550,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
return 1
/proc/Broadcast_SimpleMessage(var/source, var/frequency, var/text, var/data, var/mob/M, var/compression, var/level)
/proc/Broadcast_SimpleMessage(var/source, var/frequency, var/text, var/data, var/mob/M, var/compression, var/level, var/list/forced_radios)
/* ###### Prepare the radio connection ###### */
@@ -452,10 +564,12 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/list/receive = list()
for(var/obj/item/device/radio/R in forced_radios)
receive |= R.send_hear(display_freq)
// --- Broadcast only to intercom devices ---
if(data == 1)
if(data == DATA_INTERCOM)
for (var/obj/item/device/radio/intercom/R in connection.devices["[RADIO_CHAT]"])
var/turf/position = get_turf(R)
if(position && position.z == level)
@@ -464,7 +578,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// --- Broadcast only to intercoms and station-bounced radios ---
else if(data == 2)
else if(data == DATA_LOCAL)
for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"])
if(istype(R, /obj/item/device/radio/headset))
@@ -476,7 +590,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// --- Broadcast to antag radios! ---
else if(data == 3)
else if(data == DATA_ANTAG)
for(var/freq in ANTAG_FREQS)
var/datum/radio_frequency/antag_connection = radio_controller.return_frequency(freq)
for (var/obj/item/device/radio/R in antag_connection.devices["[RADIO_CHAT]"])
@@ -541,7 +655,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// --- Some more pre-message formatting ---
var/part_b_extra = ""
if(data == 3) // intercepted radio message
if(data == DATA_ANTAG) // intercepted radio message
part_b_extra = " <i>(Intercepted)</i>"
// Create a radio headset for the sole purpose of using its icon
@@ -617,15 +731,15 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/atom/proc/test_telecomms()
var/datum/signal/signal = src.telecomms_process()
var/turf/position = get_turf(src)
return (position.z in signal.data["level"] && signal.data["done"])
var/pos_z = get_z(src)
return (pos_z in signal.data["level"] && signal.data["done"])
/atom/proc/telecomms_process(var/do_sleep = 1)
// First, we want to generate a new radio signal
var/datum/signal/signal = new
signal.transmission_method = 2 // 2 would be a subspace transmission.
var/turf/pos = get_turf(src)
signal.transmission_method = TRANSMISSION_SUBSPACE
var/pos_z = get_z(src)
// --- Finally, tag the actual signal with the appropriate values ---
signal.data = list(
@@ -633,10 +747,10 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
"message" = "TEST",
"compression" = rand(45, 50), // If the signal is compressed, compress our message too.
"traffic" = 0, // dictates the total traffic sum that the signal went through
"type" = 4, // determines what type of radio input it is: test broadcast
"type" = SIGNAL_TEST, // determines what type of radio input it is: test broadcast
"reject" = 0,
"done" = 0,
"level" = pos.z // The level it is being broadcasted at.
"level" = pos_z // The level it is being broadcasted at.
)
signal.frequency = PUB_FREQ// Common channel

View File

@@ -219,6 +219,38 @@
temp = "<font color = #666633>-% Frequency changing deactivated %-</font>"
// BROADCASTER
/obj/machinery/telecomms/broadcaster/Options_Menu()
// Note the machine 'displays' 1 higher than overmap_range to save users from the abstraction that range '0' is valid and everything on the same turf.
var/dat = "<br>Broadcast Range (affects power usage)<br><a href='?src=\ref[src];range_down=1'>-</a> [overmap_range+1] gigameter\s <a href='?src=\ref[src];range_up=1'>+</a>"
return dat
/obj/machinery/telecomms/broadcaster/Options_Topic(href, href_list)
if(href_list["range_down"])
if(overmap_range > overmap_range_min)
overmap_range--
idle_power_usage = initial(idle_power_usage)**(overmap_range+1)
if(href_list["range_up"])
if(overmap_range < overmap_range_max)
overmap_range++
idle_power_usage = initial(idle_power_usage)**(overmap_range+1)
// RECEIVER
/obj/machinery/telecomms/receiver/Options_Menu()
// Note the machine 'displays' 1 higher than overmap_range to save users from the abstraction that range '0' is valid and everything on the same turf.
var/dat = "<br>Receive Range (affects power usage)<br><a href='?src=\ref[src];range_down=1'>-</a> [overmap_range+1] gigameter\s <a href='?src=\ref[src];range_up=1'>+</a>"
return dat
/obj/machinery/telecomms/receiver/Options_Topic(href, href_list)
if(href_list["range_down"])
if(overmap_range > overmap_range_min)
overmap_range--
idle_power_usage = initial(idle_power_usage)**(overmap_range+1)
if(href_list["range_up"])
if(overmap_range < overmap_range_max)
overmap_range++
idle_power_usage = initial(idle_power_usage)**(overmap_range+1)
/obj/machinery/telecomms/Topic(href, href_list)
if(!issilicon(usr))

View File

@@ -68,7 +68,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
var/datum/signal/copy
if(copysig)
copy = new
copy.transmission_method = 2
copy.transmission_method = TRANSMISSION_SUBSPACE
copy.frequency = signal.frequency
copy.data = signal.data.Copy()
@@ -141,9 +141,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
// Used in auto linking
/obj/machinery/telecomms/proc/add_link(var/obj/machinery/telecomms/T)
var/turf/position = get_turf(src)
var/turf/T_position = get_turf(T)
if((position.z == T_position.z) || (src.long_range_link && T.long_range_link))
var/pos_z = get_z(src)
var/tpos_z = get_z(T)
if((pos_z == tpos_z) || (src.long_range_link && T.long_range_link))
for(var/x in autolinkers)
if(T.autolinkers.Find(x))
if(src != T)
@@ -256,6 +256,12 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
machinetype = 1
produces_heat = 0
circuit = /obj/item/weapon/circuitboard/telecomms/receiver
//Vars only used if you're using the overmap
var/overmap_range = 0
var/overmap_range_min = 0
var/overmap_range_max = 5
var/list/linked_radios_weakrefs = list()
/obj/machinery/telecomms/receiver/Initialize()
. = ..()
@@ -267,8 +273,12 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
RefreshParts()
/obj/machinery/telecomms/receiver/receive_signal(datum/signal/signal)
/obj/machinery/telecomms/receiver/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R))
return
linked_radios_weakrefs |= weakref(R)
/obj/machinery/telecomms/receiver/receive_signal(datum/signal/signal)
if(!on) // has to be on to receive messages
return
if(!signal)
@@ -276,7 +286,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
if(!check_receive_level(signal))
return
if(signal.transmission_method == 2)
if(signal.transmission_method == TRANSMISSION_SUBSPACE)
if(is_freq_listening(signal)) // detect subspace signals
@@ -288,14 +298,31 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
relay_information(signal, "/obj/machinery/telecomms/bus") // Send it to a bus instead, if it's linked to one
/obj/machinery/telecomms/receiver/proc/check_receive_level(datum/signal/signal)
// If it's a direct message from a bluespace radio, we eat it and convert it into a subspace signal locally
if(signal.transmission_method == TRANSMISSION_BLUESPACE)
var/obj/item/device/radio/R = signal.data["radio"]
if(signal.data["level"] != listening_level)
//Who're you?
if(!(weakref(R) in linked_radios_weakrefs))
signal.data["reject"] = 1
return 0
//We'll resend this for you
signal.data["level"] = z
signal.transmission_method = TRANSMISSION_SUBSPACE
return 1
//Where can we hear?
var/list/listening_levels = using_map.get_map_levels(listening_level, TRUE, overmap_range)
// We couldn't 'hear' it, maybe a relay linked to our hub can 'hear' it
if(!(signal.data["level"] in listening_levels))
for(var/obj/machinery/telecomms/hub/H in links)
var/list/connected_levels = list()
var/list/relayed_levels = list()
for(var/obj/machinery/telecomms/relay/R in H.links)
if(R.can_receive(signal))
connected_levels |= R.listening_level
if(signal.data["level"] in connected_levels)
relayed_levels |= R.listening_level
if(signal.data["level"] in relayed_levels)
return 1
return 0
return 1
@@ -405,7 +432,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
// Add our level and send it back
if(can_send(signal))
signal.data["level"] |= listening_level
signal.data["level"] |= using_map.get_map_levels(listening_level)
// Checks to see if it can send/receive.
@@ -602,7 +629,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
totaltraffic += traffic // add current traffic to total traffic
//Is this a test signal? Bypass logging
if(signal.data["type"] != 4)
if(signal.data["type"] != SIGNAL_TEST)
// If signal has a message and appropriate frequency

View File

@@ -256,7 +256,7 @@ var/list/civilian_cartridges = list(
var/datum/signal/status_signal = new
status_signal.source = src
status_signal.transmission_method = 1
status_signal.transmission_method = TRANSMISSION_RADIO
status_signal.data["command"] = command
switch(command)

View File

@@ -22,7 +22,7 @@
var/datum/signal/signal = new()
signal.source = src
signal.transmission_method = 1
signal.transmission_method = TRANSMISSION_RADIO
signal.data[key] = value
if(key2)
signal.data[key2] = value2

View File

@@ -329,7 +329,7 @@
var/datum/signal/status_signal = new
status_signal.source = src
status_signal.transmission_method = 1
status_signal.transmission_method = TRANSMISSION_RADIO
status_signal.data["command"] = command
switch(command)

View File

@@ -83,7 +83,7 @@ var/list/GPS_list = list()
dat["curr_z_name"] = using_map.get_zlevel_name(curr.z)
dat["gps_list"] = list()
dat["z_level_detection"] = using_map.get_map_levels(curr.z, long_range)
for(var/obj/item/device/gps/G in GPS_list - src)
if(!G.tracking || G.emped || G.hide_signal)
continue

View File

@@ -52,6 +52,13 @@ var/global/list/default_medbay_channels = list(
w_class = ITEMSIZE_SMALL
show_messages = 1
// Bluespace radios talk directly to telecomms equipment
var/bluespace_radio = FALSE
var/weakref/bs_tx_weakref //Maybe misleading, this is the device to TRANSMIT TO
// For mappers or subtypes, to start them prelinked to these devices
var/bs_tx_preload_id
var/bs_rx_preload_id
matter = list("glass" = 25,DEFAULT_WALL_MATERIAL = 75)
var/const/FREQ_LISTENING = 1
var/list/internal_channels
@@ -90,6 +97,43 @@ var/global/list/default_medbay_channels = list(
for (var/ch_name in channels)
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
if(bluespace_radio)
if(bs_tx_preload_id)
//Try to find a receiver
for(var/obj/machinery/telecomms/receiver/RX in telecomms_list)
if(RX.id == bs_tx_preload_id) //Again, bs_tx is the thing to TRANSMIT TO, so a receiver.
bs_tx_weakref = weakref(RX)
RX.link_radio(src)
break
//Hmm, howabout an AIO machine
if(!bs_tx_weakref)
for(var/obj/machinery/telecomms/allinone/AIO in telecomms_list)
if(AIO.id == bs_tx_preload_id)
bs_tx_weakref = weakref(AIO)
AIO.link_radio(src)
break
if(!bs_tx_weakref)
testing("A radio [src] at [x],[y],[z] specified bluespace prelink IDs, but the machines with corresponding IDs ([bs_tx_preload_id], [bs_rx_preload_id]) couldn't be found.")
if(bs_rx_preload_id)
var/found = 0
//Try to find a transmitter
for(var/obj/machinery/telecomms/broadcaster/TX in telecomms_list)
if(TX.id == bs_rx_preload_id) //Again, bs_rx is the thing to RECEIVE FROM, so a transmitter.
TX.link_radio(src)
found = 1
break
//Hmm, howabout an AIO machine
if(!found)
for(var/obj/machinery/telecomms/allinone/AIO in telecomms_list)
if(AIO.id == bs_rx_preload_id)
AIO.link_radio(src)
found = 1
break
if(!found)
testing("A radio [src] at [x],[y],[z] specified bluespace prelink IDs, but the machines with corresponding IDs ([bs_tx_preload_id], [bs_rx_preload_id]) couldn't be found.")
/obj/item/device/radio/attack_self(mob/user as mob)
user.set_machine(src)
interact(user)
@@ -240,11 +284,10 @@ var/global/list/default_medbay_channels = list(
if(.)
SSnanoui.update_uis(src)
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) //BS12 EDIT
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels) //BS12 EDIT
var/datum/radio_frequency/connection = null
if(channel && channels && channels.len > 0)
if (channel == "department")
//to_world("DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\"")
channel = channels[1]
connection = secure_radio_connections[channel]
else
@@ -253,12 +296,15 @@ var/global/list/default_medbay_channels = list(
if (!istype(connection))
return
if(!LAZYLEN(zlevels))
zlevels = list(0)
var/static/mob/living/silicon/ai/announcer/A = new /mob/living/silicon/ai/announcer(src, null, null, 1)
A.SetName(from)
Broadcast_Message(connection, A,
0, "*garbled automated announcement*", src,
message, from, "Automated Announcement", from, "synthesized voice",
4, 0, list(0), connection.frequency, "states")
4, 0, zlevels, connection.frequency, "states")
// Interprets the message mode when talking into a radio, possibly returning a connection datum
/obj/item/device/radio/proc/handle_message_mode(mob/living/M as mob, message, message_mode)
@@ -310,7 +356,7 @@ var/global/list/default_medbay_channels = list(
if (!istype(connection))
return FALSE
var/turf/position = get_turf(src)
var/pos_z = get_z(src)
//#### Tagging the signal with all appropriate identity values ####//
@@ -359,10 +405,63 @@ var/global/list/default_medbay_channels = list(
jobname = "Unknown"
voicemask = 1
// First, we want to generate a new radio signal
var/datum/signal/signal = new
// --- Finally, tag the actual signal with the appropriate values ---
signal.data = list(
// Identity-associated tags:
"mob" = M, // store a reference to the mob
"mobtype" = M.type, // the mob's type
"realname" = real_name, // the mob's real name
"name" = displayname, // the mob's display name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood
"vname" = M.voice_name, // the name to display if the voice wasn't understood
"vmask" = voicemask, // 1 if the mob is using a voice gas mask
/* ###### Radio headsets can only broadcast through subspace ###### */
if(subspace_transmission)
// We store things that would otherwise be kept in the actual mob
// so that they can be logged even AFTER the mob is deleted or something
// Other tags:
"compression" = rand(45,50), // compressed radio signal
"message" = message, // the actual sent message
"connection" = connection, // the radio connection to use
"radio" = src, // stores the radio used for transmission
"slow" = 0, // how much to sleep() before broadcasting - simulates net lag
"traffic" = 0, // dictates the total traffic sum that the signal went through
"type" = SIGNAL_NORMAL, // determines what type of radio input it is: normal broadcast
"server" = null, // the last server to log this signal
"reject" = 0, // if nonzero, the signal will not be accepted by any broadcasting machinery
"level" = pos_z, // The source's z level
"language" = speaking,
"verb" = verb
)
signal.frequency = connection.frequency // Quick frequency set
var/filter_type = DATA_LOCAL //If we end up having to send it the old fashioned way, it's with this data var.
/* ###### Bluespace radios talk directly to receivers (and only directly to receivers) ###### */
if(bluespace_radio)
//Nothing to transmit to
if(!bs_tx_weakref)
to_chat(loc, "<span class='warning'>\The [src] buzzes to inform you of the lack of a functioning connection.</span>")
return FALSE
var/obj/machinery/telecomms/tx_to = bs_tx_weakref.resolve()
//Was linked, now destroyed or something
if(!tx_to)
bs_tx_weakref = null
to_chat(loc, "<span class='warning'>\The [src] buzzes to inform you of the lack of a functioning connection.</span>")
return FALSE
//Transmitted in the blind. If we get a message back, cool. If not, oh well.
signal.transmission_method = TRANSMISSION_BLUESPACE
return tx_to.receive_signal(signal)
/* ###### Radios with subspace_transmission can only broadcast through subspace (unless they have adhoc_fallback) ###### */
else if(subspace_transmission)
var/list/jamming = is_jammed(src)
if(jamming)
var/distance = jamming["distance"]
@@ -370,43 +469,9 @@ var/global/list/default_medbay_channels = list(
return FALSE
// First, we want to generate a new radio signal
var/datum/signal/signal = new
signal.transmission_method = 2 // 2 would be a subspace transmission.
// transmission_method could probably be enumerated through #define. Would be neater.
signal.transmission_method = TRANSMISSION_SUBSPACE
// --- Finally, tag the actual signal with the appropriate values ---
signal.data = list(
// Identity-associated tags:
"mob" = M, // store a reference to the mob
"mobtype" = M.type, // the mob's type
"realname" = real_name, // the mob's real name
"name" = displayname, // the mob's display name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood
"vname" = M.voice_name, // the name to display if the voice wasn't understood
"vmask" = voicemask, // 1 if the mob is using a voice gas mask
// We store things that would otherwise be kept in the actual mob
// so that they can be logged even AFTER the mob is deleted or something
// Other tags:
"compression" = rand(45,50), // compressed radio signal
"message" = message, // the actual sent message
"connection" = connection, // the radio connection to use
"radio" = src, // stores the radio used for transmission
"slow" = 0, // how much to sleep() before broadcasting - simulates net lag
"traffic" = 0, // dictates the total traffic sum that the signal went through
"type" = 0, // determines what type of radio input it is: normal broadcast
"server" = null, // the last server to log this signal
"reject" = 0, // if nonzero, the signal will not be accepted by any broadcasting machinery
"level" = position.z, // The source's z level
"language" = speaking,
"verb" = verb
)
signal.frequency = connection.frequency // Quick frequency set
//#### Sending the signal to all subspace receivers ####//
//#### Sending the signal to all subspace receivers ####//
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
R.receive_signal(signal)
@@ -416,84 +481,47 @@ var/global/list/default_medbay_channels = list(
R.receive_signal(signal)
// Receiving code can be located in Telecommunications.dm
if(signal.data["done"] && position.z in signal.data["level"])
if(signal.data["done"] && (pos_z in signal.data["level"]))
return TRUE //Huzzah, sent via subspace
else if(adhoc_fallback) //Less huzzah, we have to fallback
to_chat(loc, "<span class='warning'>\The [src] pings as it falls back to local radio transmission.</span>")
subspace_transmission = FALSE
return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
src, message, displayname, jobname, real_name, M.voice_name,
signal.transmission_method, signal.data["compression"], GetConnectedZlevels(position.z), connection.frequency,verb,speaking)
/* ###### Intercoms and station-bounced radios ###### */
else //Oh well
return FALSE
var/filter_type = 2
/* ###### Intercoms and station-bounced radios ###### */
else
/* --- Intercoms can only broadcast to other intercoms, but bounced radios can broadcast to bounced radios and intercoms --- */
if(istype(src, /obj/item/device/radio/intercom))
filter_type = DATA_INTERCOM
/* --- Intercoms can only broadcast to other intercoms, but bounced radios can broadcast to bounced radios and intercoms --- */
if(istype(src, /obj/item/device/radio/intercom))
filter_type = 1
/* --- Try to send a normal subspace broadcast first */
signal.transmission_method = TRANSMISSION_SUBSPACE
signal.data["compression"] = 0
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
R.receive_signal(signal)
var/datum/signal/signal = new
signal.transmission_method = 2
/* --- Try to send a normal subspace broadcast first */
signal.data = list(
"mob" = M, // store a reference to the mob
"mobtype" = M.type, // the mob's type
"realname" = real_name, // the mob's real name
"name" = displayname, // the mob's display name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood
"vname" = M.voice_name, // the name to display if the voice wasn't understood
"vmask" = voicemask, // 1 if the mob is using a voice gas mas
"compression" = 0, // uncompressed radio signal
"message" = message, // the actual sent message
"connection" = connection, // the radio connection to use
"radio" = src, // stores the radio used for transmission
"slow" = 0,
"traffic" = 0,
"type" = 0,
"server" = null,
"reject" = 0,
"level" = position.z,
"language" = speaking,
"verb" = verb
)
signal.frequency = connection.frequency // Quick frequency set
// Allinone can act as receivers.
for(var/obj/machinery/telecomms/allinone/R in telecomms_list)
R.receive_signal(signal)
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
R.receive_signal(signal)
if(signal.data["done"] && position.z in signal.data["level"])
if(adhoc_fallback)
to_chat(loc, "<span class='notice'>\The [src] pings as it reestablishes subspace communications.</span>")
subspace_transmission = TRUE
// we're done here.
return TRUE
// Oh my god; the comms are down or something because the signal hasn't been broadcasted yet in our level.
// Send a mundane broadcast with limited targets:
//THIS IS TEMPORARY. YEAH RIGHT
if(!connection) return FALSE //~Carn
//VOREStation Add Start
if(bluespace_radio)
return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
src, message, displayname, jobname, real_name, M.voice_name,
0, signal.data["compression"], list(0), connection.frequency,verb,speaking)
//VOREStation Add End
if(signal.data["done"] && pos_z in signal.data["level"])
if(adhoc_fallback)
to_chat(loc, "<span class='notice'>\The [src] pings as it reestablishes subspace communications.</span>")
subspace_transmission = TRUE
// we're done here.
return TRUE
//Nothing handled any sort of remote radio-ing and returned before now, just squawk on this zlevel.
return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
src, message, displayname, jobname, real_name, M.voice_name,
filter_type, signal.data["compression"], GetConnectedZlevels(position.z), connection.frequency,verb,speaking)
src, message, displayname, jobname, real_name, M.voice_name,
filter_type, signal.data["compression"], using_map.get_map_levels(pos_z), connection.frequency, verb, speaking)
/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
@@ -502,33 +530,20 @@ var/global/list/default_medbay_channels = list(
talk_into(M, msg,null,verb,speaking)
/*
/obj/item/device/radio/proc/accept_rad(obj/item/device/radio/R as obj, message)
if ((R.frequency == frequency && message))
return TRUE
else if
else
return null
return
*/
/obj/item/device/radio/proc/receive_range(freq, level)
// check if this radio can receive on the given frequency, and if so,
// what the range is in which mobs will hear the radio
// returns: -1 if can't receive, range otherwise
if (wires.IsIndexCut(WIRE_RECEIVE))
if(wires.IsIndexCut(WIRE_RECEIVE))
return -1
if(!listening)
return -1
if(is_jammed(src))
return -1
if(!(0 in level))
var/turf/position = get_turf(src)
if((!position || !(position.z in level)) && !bluespace_radio) //VOREStation Edit
var/pos_z = get_z(src)
if(!(pos_z in level))
return -1
if(freq in ANTAG_FREQS)
if(!(src.syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys

View File

@@ -1,6 +1,3 @@
/obj/item/device/radio
var/bluespace_radio = FALSE
/obj/item/device/radio/phone
subspace_transmission = 1
canhear_range = 0
@@ -17,132 +14,20 @@
..()
internal_channels = default_medbay_channels.Copy()
//Pathfinder's Subspace Radio
/obj/item/device/subspaceradio
name = "subspace radio"
desc = "A powerful new radio recently gifted to Nanotrasen from KHI, this communications device has the ability to send and recieve transmissions from anywhere."
catalogue_data = list(/datum/category_item/catalogue/information/organization/khi)
icon = 'icons/vore/custom_items_vr.dmi'
icon_override = 'icons/mob/back_vr.dmi'
icon_state = "radiopack"
item_state = "radiopack"
slot_flags = SLOT_BACK
force = 5
throwforce = 6
preserve_item = 1
w_class = ITEMSIZE_LARGE
action_button_name = "Remove/Replace Handset"
var/obj/item/device/radio/subspacehandset/linked/handset
/obj/item/device/subspaceradio/New() //starts without a cell for rnd
..()
if(ispath(handset))
handset = new handset(src, src)
else
handset = new(src, src)
/obj/item/device/bluespaceradio/tether_prelinked
name = "bluespace radio (tether)"
handset = /obj/item/device/radio/bluespacehandset/linked/tether_prelinked
/obj/item/device/subspaceradio/Destroy()
. = ..()
QDEL_NULL(handset)
/obj/item/device/radio/bluespacehandset/linked/tether_prelinked
bs_tx_preload_id = "tether_rx" //Transmit to a receiver
bs_rx_preload_id = "tether_tx" //Recveive from a transmitter
/obj/item/device/subspaceradio/ui_action_click()
toggle_handset()
/obj/item/device/bluespaceradio/talon_prelinked
name = "bluespace radio (talon)"
handset = /obj/item/device/radio/bluespacehandset/linked/talon_prelinked
/obj/item/device/subspaceradio/attack_hand(mob/user)
if(loc == user)
toggle_handset()
else
..()
/obj/item/device/subspaceradio/MouseDrop()
if(ismob(loc))
if(!CanMouseDrop(src))
return
var/mob/M = loc
if(!M.unEquip(src))
return
add_fingerprint(usr)
M.put_in_any_hand_if_possible(src)
/obj/item/device/subspaceradio/attackby(obj/item/weapon/W, mob/user, params)
if(W == handset)
reattach_handset(user)
else
return ..()
/obj/item/device/subspaceradio/verb/toggle_handset()
set name = "Toggle Handset"
set category = "Object"
var/mob/living/carbon/human/user = usr
if(!handset)
to_chat(user, "<span class='warning'>The handset is missing!</span>")
return
if(handset.loc != src)
reattach_handset(user) //Remove from their hands and back onto the defib unit
return
if(!slot_check())
to_chat(user, "<span class='warning'>You need to equip [src] before taking out [handset].</span>")
else
if(!usr.put_in_hands(handset)) //Detach the handset into the user's hands
to_chat(user, "<span class='warning'>You need a free hand to hold the handset!</span>")
update_icon() //success
//checks that the base unit is in the correct slot to be used
/obj/item/device/subspaceradio/proc/slot_check()
var/mob/M = loc
if(!istype(M))
return 0 //not equipped
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_back) == src)
return 1
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_s_store) == src)
return 1
return 0
/obj/item/device/subspaceradio/dropped(mob/user)
..()
reattach_handset(user) //handset attached to a base unit should never exist outside of their base unit or the mob equipping the base unit
/obj/item/device/subspaceradio/proc/reattach_handset(mob/user)
if(!handset) return
if(ismob(handset.loc))
var/mob/M = handset.loc
if(M.drop_from_inventory(handset, src))
to_chat(user, "<span class='notice'>\The [handset] snaps back into the main unit.</span>")
else
handset.forceMove(src)
//Subspace Radio Handset
/obj/item/device/radio/subspacehandset
name = "subspace radio handset"
desc = "A large walkie talkie attached to the subspace radio by a retractable cord. It sits comfortably on a slot in the radio when not in use."
bluespace_radio = TRUE
icon_state = "signaller"
slot_flags = null
w_class = ITEMSIZE_LARGE
/obj/item/device/radio/subspacehandset/linked
var/obj/item/device/subspaceradio/base_unit
/obj/item/device/radio/subspacehandset/linked/New(newloc, obj/item/device/subspaceradio/radio)
base_unit = radio
..(newloc)
/obj/item/device/radio/subspacehandset/linked/Destroy()
if(base_unit)
//ensure the base unit's icon updates
if(base_unit.handset == src)
base_unit.handset = null
base_unit = null
return ..()
/obj/item/device/radio/subspacehandset/linked/dropped(mob/user)
..() //update twohanding
if(base_unit)
base_unit.reattach_handset(user) //handset attached to a base unit should never exist outside of their base unit or the mob equipping the base unit
/obj/item/device/radio/bluespacehandset/linked/talon_prelinked
bs_tx_preload_id = "talon_aio" //Transmit to a receiver
bs_rx_preload_id = "talon_aio" //Recveive from a transmitter

View File

@@ -0,0 +1,153 @@
/obj/item/device/bluespaceradio
name = "bluespace radio"
desc = "A powerful radio that uses a tiny bluespace wormhole to send signals directly to subspace receivers and transmitters, bypassing the limitations of subspace."
icon = 'icons/obj/radio.dmi'
icon_state = "radiopack"
item_state = "radiopack"
slot_flags = SLOT_BACK
force = 5
throwforce = 6
preserve_item = 1
w_class = ITEMSIZE_LARGE
action_button_name = "Remove/Replace Handset"
var/obj/item/device/radio/bluespacehandset/linked/handset = /obj/item/device/radio/bluespacehandset/linked
/obj/item/device/bluespaceradio/Initialize()
. = ..()
if(ispath(handset))
handset = new handset(src, src)
/obj/item/device/bluespaceradio/Destroy()
. = ..()
QDEL_NULL(handset)
/obj/item/device/bluespaceradio/ui_action_click()
toggle_handset()
/obj/item/device/bluespaceradio/attack_hand(var/mob/user)
if(loc == user)
toggle_handset()
else
..()
/obj/item/device/bluespaceradio/MouseDrop()
if(ismob(loc))
if(!CanMouseDrop(src))
return
var/mob/M = loc
if(!M.unEquip(src))
return
add_fingerprint(usr)
M.put_in_any_hand_if_possible(src)
/obj/item/device/bluespaceradio/attackby(var/obj/item/weapon/W, var/mob/user, var/params)
if(W == handset)
reattach_handset(user)
else
return ..()
/obj/item/device/bluespaceradio/verb/toggle_handset()
set name = "Toggle Handset"
set category = "Object"
var/mob/living/carbon/human/user = usr
if(!handset)
to_chat(user, "<span class='warning'>The handset is missing!</span>")
return
if(handset.loc != src)
reattach_handset(user) //Remove from their hands and back onto the defib unit
return
if(!slot_check())
to_chat(user, "<span class='warning'>You need to equip [src] before taking out [handset].</span>")
else
if(!usr.put_in_hands(handset)) //Detach the handset into the user's hands
to_chat(user, "<span class='warning'>You need a free hand to hold the handset!</span>")
update_icon() //success
//checks that the base unit is in the correct slot to be used
/obj/item/device/bluespaceradio/proc/slot_check()
var/mob/M = loc
if(!istype(M))
return 0 //not equipped
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_back) == src)
return 1
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_s_store) == src)
return 1
return 0
/obj/item/device/bluespaceradio/dropped(var/mob/user)
..()
reattach_handset(user) //handset attached to a base unit should never exist outside of their base unit or the mob equipping the base unit
/obj/item/device/bluespaceradio/proc/reattach_handset(var/mob/user)
if(!handset) return
if(ismob(handset.loc))
var/mob/M = handset.loc
if(M.drop_from_inventory(handset, src))
to_chat(user, "<span class='notice'>\The [handset] snaps back into the main unit.</span>")
else
handset.forceMove(src)
//Subspace Radio Handset
/obj/item/device/radio/bluespacehandset
name = "bluespace radio handset"
desc = "A large walkie talkie attached to the bluespace radio by a retractable cord. It sits comfortably on a slot in the radio when not in use."
bluespace_radio = TRUE
icon_state = "signaller"
slot_flags = null
w_class = ITEMSIZE_LARGE
canhear_range = 1
/obj/item/device/radio/bluespacehandset/linked
var/obj/item/device/bluespaceradio/base_unit
/obj/item/device/radio/bluespacehandset/linked/Initialize(mapload, var/obj/item/device/bluespaceradio/radio)
base_unit = radio
. = ..()
/obj/item/device/radio/bluespacehandset/linked/Destroy()
if(base_unit)
//ensure the base unit's icon updates
if(base_unit.handset == src)
base_unit.handset = null
base_unit = null
return ..()
/obj/item/device/radio/bluespacehandset/linked/dropped(var/mob/user)
..() //update twohanding
if(base_unit)
base_unit.reattach_handset(user) //handset attached to a base unit should never exist outside of their base unit or the mob equipping the base unit
/obj/item/device/radio/bluespacehandset/linked/receive_range(var/freq, var/list/level)
//Only care about megabroadcasts or things that are targeted at us
if(!(0 in level))
return -1
if(wires.IsIndexCut(WIRE_RECEIVE))
return -1
if(!listening)
return -1
if(is_jammed(src))
return -1
if (!on)
return -1
if (!freq) //recieved on main frequency
if (!listening)
return -1
else
var/accept = (freq==frequency && listening)
if (!accept)
for (var/ch_name in channels)
var/datum/radio_frequency/RF = secure_radio_connections[ch_name]
if (RF && RF.frequency==freq && (channels[ch_name]&FREQ_LISTENING))
accept = 1
break
if (!accept)
return -1
return canhear_range

View File

@@ -3,20 +3,36 @@
/turf/simulated/wall/r_wall/Initialize(mapload)
. = ..(mapload, "plasteel","plasteel") //3strong
/turf/simulated/wall/shull
icon_state = "hull-steel"
/turf/simulated/wall/shull/Initialize(mapload) //Spaaaace ship.
. = ..(mapload, MAT_STEELHULL, null, MAT_STEELHULL)
/turf/simulated/wall/rshull
icon_state = "hull-r_steel"
/turf/simulated/wall/rshull/Initialize(mapload)
. = ..(mapload, MAT_STEELHULL, MAT_STEELHULL, MAT_STEELHULL)
/turf/simulated/wall/pshull
icon_state = "hull-plasteel"
/turf/simulated/wall/pshull/Initialize(mapload) //Spaaaace-er ship.
. = ..(mapload, MAT_PLASTEELHULL, null, MAT_PLASTEELHULL)
/turf/simulated/wall/rpshull
icon_state = "hull-r_plasteel"
/turf/simulated/wall/rpshull/Initialize(mapload)
. = ..(mapload, MAT_PLASTEELHULL, MAT_PLASTEELHULL, MAT_PLASTEELHULL)
/turf/simulated/wall/dshull
icon_state = "hull-durasteel"
/turf/simulated/wall/dshull/Initialize(mapload) //Spaaaace-est ship.
. = ..(mapload, MAT_DURASTEELHULL, null, MAT_DURASTEELHULL)
/turf/simulated/wall/rdshull
icon_state = "hull-r_durasteel"
/turf/simulated/wall/rdshull/Initialize(mapload)
. = ..(mapload, MAT_DURASTEELHULL, MAT_DURASTEELHULL, MAT_DURASTEELHULL)
/turf/simulated/wall/thull
icon_state = "hull-titanium"
/turf/simulated/wall/thull/Initialize(mapload)
. = ..(mapload, MAT_TITANIUMHULL, null, MAT_TITANIUMHULL)
/turf/simulated/wall/rthull
icon_state = "hull-r_titanium"
/turf/simulated/wall/rthull/Initialize(mapload)
. = ..(mapload, MAT_TITANIUMHULL, MAT_TITANIUMHULL, MAT_TITANIUMHULL)

View File

@@ -251,7 +251,7 @@ var/const/enterloopsanity = 100
/turf/proc/inertial_drift(atom/movable/A as mob|obj)
if(!(A.last_move)) return
if((istype(A, /mob/) && src.x > 2 && src.x < (world.maxx - 1) && src.y > 2 && src.y < (world.maxy-1)))
if((istype(A, /mob/) && src.x > 1 && src.x < (world.maxx) && src.y > 1 && src.y < (world.maxy)))
var/mob/M = A
if(M.Process_Spacemove(1))
M.inertia_dir = 0

View File

@@ -181,6 +181,17 @@ var/world_topic_spam_protect_time = world.timeofday
if(!positions["misc"])
positions["misc"] = list()
positions["misc"][name] = rank
for(var/datum/data/record/t in data_core.hidden_general)
var/name = t.fields["name"]
var/rank = t.fields["rank"]
var/real_rank = make_list_rank(t.fields["real_rank"])
var/datum/job/J = SSjob.get_job(real_rank)
if(J?.offmap_spawn)
if(!positions["off"])
positions["off"] = list()
positions["off"][name] = rank
// Synthetics don't have actual records, so we will pull them from here.
for(var/mob/living/silicon/ai/ai in mob_list)

View File

@@ -525,7 +525,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
//If we're announcing their arrival
if(announce)
AnnounceArrival(new_character, new_character.mind.assigned_role)
AnnounceArrival(new_character, new_character.mind.assigned_role, "Common", new_character.z)
log_admin("[admin] has spawned [player_key]'s character [new_character.real_name].")
message_admins("[admin] has spawned [player_key]'s character [new_character.real_name].", 1)

View File

@@ -47,16 +47,17 @@
existing.clear(source)
return check_alarm_cleared(existing)
/datum/alarm_handler/proc/major_alarms()
return visible_alarms()
/datum/alarm_handler/proc/major_alarms(var/z)
return visible_alarms(z)
/datum/alarm_handler/proc/has_major_alarms()
if(alarms && alarms.len)
return 1
return 0
/datum/alarm_handler/proc/has_major_alarms(var/z)
if(!LAZYLEN(alarms))
return 0
/datum/alarm_handler/proc/minor_alarms()
return visible_alarms()
return LAZYLEN(major_alarms(z))
/datum/alarm_handler/proc/minor_alarms(var/z)
return visible_alarms(z)
/datum/alarm_handler/proc/check_alarm_cleared(var/datum/alarm/alarm)
if ((alarm.end_time && world.time > alarm.end_time) || !alarm.sources.len)
@@ -101,9 +102,15 @@
for(var/listener in listeners)
call(listener, listeners[listener])(src, alarm, was_raised)
/datum/alarm_handler/proc/visible_alarms()
/datum/alarm_handler/proc/visible_alarms(var/z)
if(!LAZYLEN(alarms))
return list()
var/list/map_levels = using_map.get_map_levels(z)
var/list/visible_alarms = new()
for(var/datum/alarm/A in alarms)
if(!A.hidden)
visible_alarms.Add(A)
if(A.hidden || (z && !(A.origin?.z in map_levels)))
continue
visible_alarms.Add(A)
return visible_alarms

View File

@@ -1,16 +1,22 @@
/datum/alarm_handler/atmosphere
category = "Atmosphere Alarms"
/datum/alarm_handler/atmosphere/major_alarms()
/datum/alarm_handler/atmosphere/major_alarms(var/z)
var/list/major_alarms = new()
var/list/map_levels = using_map.get_map_levels(z)
for(var/datum/alarm/A in visible_alarms())
if(z && (z && !(A.origin?.z in map_levels)))
continue
if(A.max_severity() > 1)
major_alarms.Add(A)
return major_alarms
/datum/alarm_handler/atmosphere/minor_alarms()
/datum/alarm_handler/atmosphere/minor_alarms(var/z)
var/list/minor_alarms = new()
var/list/map_levels = using_map.get_map_levels(z)
for(var/datum/alarm/A in visible_alarms())
if(z && (z && !(A.origin?.z in map_levels)))
continue
if(A.max_severity() == 1)
minor_alarms.Add(A)
return minor_alarms

View File

@@ -12,6 +12,7 @@ var/list/spawntypes = list()
var/display_name //Name used in preference setup.
var/list/restrict_job = null
var/list/disallow_job = null
var/announce_channel = "Common"
proc/check_job_spawning(job)
if(restrict_job && !(job in restrict_job))
@@ -20,6 +21,10 @@ var/list/spawntypes = list()
if(disallow_job && (job in disallow_job))
return 0
var/datum/job/J = SSjob.get_job(job)
if(J?.offmap_spawn && !(job in restrict_job))
return 0
return 1
/datum/spawnpoint/proc/get_spawn_position()

View File

@@ -71,7 +71,7 @@
These have been upgraded with medical records access and virus database integration."
mode = "med"
action_button_name = "AR Console (Crew Monitor)"
arscreen_path = /datum/nano_module/crew_monitor
arscreen_path = /datum/nano_module/program/crew_monitor
enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_STATUS_R,VIS_CH_BACKUP,VIS_AUGMENTED)
ar_interact(var/mob/living/carbon/human/user)

View File

@@ -17,39 +17,39 @@
//Area allowing backpacks to be placed on rigsuits.
/obj/item/weapon/rig/vox
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/backpack, /obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/combat
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton,/obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton,/obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/ert
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/tool/crowbar, \
/obj/item/weapon/tool/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/tool/wirecutters, /obj/item/weapon/tool/wrench, /obj/item/device/multitool, \
/obj/item/device/radio, /obj/item/device/analyzer,/obj/item/weapon/storage/briefcase/inflatable, /obj/item/weapon/melee/baton, /obj/item/weapon/gun, \
/obj/item/weapon/storage/firstaid, /obj/item/weapon/reagent_containers/hypospray, /obj/item/roller, /obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/storage/firstaid, /obj/item/weapon/reagent_containers/hypospray, /obj/item/roller, /obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/light/ninja
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell, /obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell, /obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/merc
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs, /obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs, /obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/ce
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd,/obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd,/obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/medical
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller,/obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller,/obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/hazmat
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/stack/flag,/obj/item/weapon/storage/excavation,/obj/item/weapon/pickaxe,/obj/item/device/healthanalyzer,/obj/item/device/measuring_tape,/obj/item/device/ano_scanner,/obj/item/device/depth_scanner,/obj/item/device/core_sampler,/obj/item/device/gps,/obj/item/device/beacon_locator,/obj/item/device/radio/beacon,/obj/item/weapon/pickaxe/hand,/obj/item/weapon/storage/bag/fossils,/obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/stack/flag,/obj/item/weapon/storage/excavation,/obj/item/weapon/pickaxe,/obj/item/device/healthanalyzer,/obj/item/device/measuring_tape,/obj/item/device/ano_scanner,/obj/item/device/depth_scanner,/obj/item/device/core_sampler,/obj/item/device/gps,/obj/item/device/beacon_locator,/obj/item/device/radio/beacon,/obj/item/weapon/pickaxe/hand,/obj/item/weapon/storage/bag/fossils,/obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/hazard
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton,/obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton,/obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/industrial
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd,/obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd,/obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/military
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/handcuffs, \
/obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/weldingtool, /obj/item/weapon/tool, /obj/item/device/multitool, \
/obj/item/device/radio, /obj/item/device/analyzer,/obj/item/weapon/storage/briefcase/inflatable, /obj/item/weapon/melee/baton, /obj/item/weapon/gun, \
/obj/item/weapon/storage/firstaid, /obj/item/weapon/reagent_containers/hypospray, /obj/item/roller, /obj/item/device/suit_cooling_unit, /obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/storage/firstaid, /obj/item/weapon/reagent_containers/hypospray, /obj/item/roller, /obj/item/device/suit_cooling_unit, /obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/pmc
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/tool/crowbar, \
/obj/item/weapon/tool/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/tool/wirecutters, /obj/item/weapon/tool/wrench, /obj/item/device/multitool, \
/obj/item/device/radio, /obj/item/device/analyzer,/obj/item/weapon/storage/briefcase/inflatable, /obj/item/weapon/melee/baton, /obj/item/weapon/gun, \
/obj/item/weapon/storage/firstaid, /obj/item/weapon/reagent_containers/hypospray, /obj/item/roller, /obj/item/weapon/storage/backpack,/obj/item/device/subspaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/storage/firstaid, /obj/item/weapon/reagent_containers/hypospray, /obj/item/roller, /obj/item/weapon/storage/backpack,/obj/item/device/bluespaceradio, /obj/item/device/defib_kit)
/obj/item/weapon/rig/robotics
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/storage/box, /obj/item/weapon/storage/belt, /obj/item/device/defib_kit/compact)

View File

@@ -9,6 +9,7 @@
var/security_level = 0 //0 - auto-identify from worn ID, require only account number
//1 - require manual login / account number and pin
//2 - require card and manual login
var/offmap = FALSE //Should this account be hidden from station consoles?
/datum/transaction
var/target_name = ""
@@ -18,10 +19,11 @@
var/time = ""
var/source_terminal = ""
/proc/create_account(var/new_owner_name = "Default user", var/starting_funds = 0, var/obj/machinery/account_database/source_db)
/proc/create_account(var/new_owner_name = "Default user", var/starting_funds = 0, var/obj/machinery/account_database/source_db, var/offmap = FALSE)
//create a new account
var/datum/money_account/M = new()
M.offmap = offmap
M.owner_name = new_owner_name
M.remote_access_pin = rand(1111, 111111)
M.money = starting_funds

View File

@@ -14,31 +14,31 @@
var/creating_new_account = 0
var/const/fund_cap = 1000000
proc/get_access_level()
if (!held_card)
return 0
if(access_cent_captain in held_card.access)
return 2
else if(access_hop in held_card.access || access_captain in held_card.access)
return 1
/obj/machinery/account_database/proc/get_access_level()
if (!held_card)
return 0
if(access_cent_captain in held_card.access)
return 2
else if(access_hop in held_card.access || access_captain in held_card.access)
return 1
proc/create_transation(target, reason, amount)
var/datum/transaction/T = new()
T.target_name = target
T.purpose = reason
T.amount = amount
T.date = current_date_string
T.time = stationtime2text()
T.source_terminal = machine_id
return T
/obj/machinery/account_database/proc/create_transation(target, reason, amount)
var/datum/transaction/T = new()
T.target_name = target
T.purpose = reason
T.amount = amount
T.date = current_date_string
T.time = stationtime2text()
T.source_terminal = machine_id
return T
proc/accounting_letterhead(report_name)
return {"
<center><h1><b>[report_name]</b></h1></center>
<center><small><i>[station_name()] Accounting Report</i></small></center>
<hr>
<u>Generated By:</u> [held_card.registered_name], [held_card.assignment]<br>
"}
/obj/machinery/account_database/proc/accounting_letterhead(report_name)
return {"
<center><h1><b>[report_name]</b></h1></center>
<center><small><i>[station_name()] Accounting Report</i></small></center>
<hr>
<u>Generated By:</u> [held_card.registered_name], [held_card.assignment]<br>
"}
/obj/machinery/account_database/New()
machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]"
@@ -98,6 +98,8 @@
var/list/accounts[0]
for(var/i=1, i<=all_money_accounts.len, i++)
var/datum/money_account/D = all_money_accounts[i]
if(D.offmap)
continue
accounts.Add(list(list(\
"account_number"=D.account_number,\
"owner_name"=D.owner_name,\

View File

@@ -17,6 +17,7 @@ var/list/department_radio_keys = list(
":v" = "Service", ".v" = "Service",
":p" = "AI Private", ".p" = "AI Private",
":y" = "Explorer", ".y" = "Explorer",
":t" = "Talon", ".t" = "Talon", //VOREStation Add,
":R" = "right ear", ".R" = "right ear",
":L" = "left ear", ".L" = "left ear",
@@ -35,6 +36,7 @@ var/list/department_radio_keys = list(
":V" = "Service", ".V" = "Service",
":P" = "AI Private", ".P" = "AI Private",
":Y" = "Explorer", ".Y" = "Explorer",
":T" = "Talon", ".T" = "Talon", //VOREStation Add,
//kinda localization -- rastaf0
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.

View File

@@ -2,7 +2,7 @@
var/register_alarms = 1
var/datum/nano_module/alarm_monitor/all/alarm_monitor
var/datum/nano_module/atmos_control/atmos_control
var/datum/nano_module/crew_monitor/crew_monitor
var/datum/nano_module/program/crew_monitor/crew_monitor
var/datum/nano_module/law_manager/law_manager
var/datum/nano_module/power_monitor/power_monitor
var/datum/nano_module/rcon/rcon

View File

@@ -370,8 +370,13 @@
//Find our spawning point.
var/list/join_props = job_master.LateSpawn(client, rank)
if(!join_props)
return
var/turf/T = join_props["turf"]
var/join_message = join_props["msg"]
var/announce_channel = join_props["channel"] || "Common"
if(!T || !join_message)
return 0
@@ -421,18 +426,19 @@
//Grab some data from the character prefs for use in random news procs.
AnnounceArrival(character, rank, join_message)
AnnounceArrival(character, rank, join_message, announce_channel, character.z)
else
AnnounceCyborg(character, rank, join_message)
AnnounceCyborg(character, rank, join_message, announce_channel, character.z)
qdel(src)
/mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message)
/mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message, var/channel, var/zlevel)
if (ticker.current_state == GAME_STATE_PLAYING)
var/list/zlevels = zlevel ? using_map.get_map_levels(zlevel, TRUE) : null
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer", channel, zlevels)
/mob/new_player/proc/LateChoices()
var/name = client.prefs.be_random_name ? "friend" : client.prefs.real_name
@@ -452,6 +458,8 @@
dat += "Choose from the following open/valid positions:<br>"
dat += "<a href='byond://?src=\ref[src];hidden_jobs=1'>[show_hidden_jobs ? "Hide":"Show"] Hidden Jobs.</a><br>"
var/deferred = ""
for(var/datum/job/job in job_master.occupations)
if(job && IsJobAvailable(job.title))
// Checks for jobs with minimum age requirements
@@ -465,9 +473,17 @@
continue
var/active = 0
// Only players with the job assigned and AFK for less than 10 minutes count as active
for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 * 60 * 10)
for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 MINUTES)
active++
dat += "<a href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions]) (Active: [active])</a><br>"
var/string = "<a href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions]) (Active: [active])</a><br>"
if(job.offmap_spawn) //At the bottom
deferred += string
else
dat += string
dat += deferred
dat += "</center>"
src << browse(dat, "window=latechoices;size=300x640;can_close=1")

View File

@@ -1,7 +1,7 @@
/obj/item/modular_computer/console
name = "console"
desc = "A stationary computer."
icon = 'icons/obj/modular_console_vr.dmi' //VOREStation Edit
icon = 'icons/obj/modular_console.dmi'
icon_state = "console"
icon_state_unpowered = "console"
icon_state_screensaver = "standby"

View File

@@ -4,7 +4,7 @@
desc = "A portable computer."
hardware_flag = PROGRAM_LAPTOP
icon_state_unpowered = "laptop-open"
icon = 'icons/obj/modular_laptop_vr.dmi' //VOREStation Edit
icon = 'icons/obj/modular_laptop.dmi'
icon_state = "laptop-open"
icon_state_screensaver = "standby"
base_idle_power_usage = 25

View File

@@ -1,7 +1,7 @@
/obj/item/modular_computer/tablet/preset/custom_loadout/rugged
name = "rugged tablet computer"
desc = "A rugged tablet computer."
icon = 'icons/obj/modular_tablet_vr.dmi'
icon = 'icons/obj/modular_tablet.dmi'
icon_state = "rugged"
icon_state_unpowered = "rugged"
max_damage = 300
@@ -19,7 +19,7 @@
/obj/item/modular_computer/tablet/preset/custom_loadout/elite
name = "elite tablet computer"
desc = "A more expensive tablet computer."
icon = 'icons/obj/modular_tablet_vr.dmi'
icon = 'icons/obj/modular_tablet.dmi'
icon_state = "elite"
icon_state_unpowered = "elite"
@@ -37,7 +37,7 @@
/obj/item/modular_computer/tablet/preset/custom_loadout/hybrid
name = "hybrid tablet computer"
desc = "A human/alien hybrid tech tablet computer."
icon = 'icons/obj/modular_tablet_vr.dmi'
icon = 'icons/obj/modular_tablet.dmi'
icon_state = "hybrid"
icon_state_unpowered = "hybrid"

View File

@@ -268,7 +268,7 @@
var/datum/signal/status_signal = new
status_signal.source = src
status_signal.transmission_method = 1
status_signal.transmission_method = TRANSMISSION_RADIO
status_signal.data["command"] = command
switch(command)

View File

@@ -61,31 +61,35 @@
AH.unregister_alarm(object)
/datum/nano_module/alarm_monitor/proc/all_alarms()
var/z = get_z(nano_host())
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
all_alarms += AH.visible_alarms()
all_alarms += AH.visible_alarms(z)
return all_alarms
/datum/nano_module/alarm_monitor/proc/major_alarms()
var/z = get_z(nano_host())
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
all_alarms += AH.major_alarms()
all_alarms += AH.major_alarms(z)
return all_alarms
// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise.
/datum/nano_module/alarm_monitor/proc/has_major_alarms()
var/z = get_z(nano_host())
for(var/datum/alarm_handler/AH in alarm_handlers)
if(AH.has_major_alarms())
if(AH.has_major_alarms(z))
return 1
return 0
/datum/nano_module/alarm_monitor/proc/minor_alarms()
var/z = get_z(nano_host())
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
all_alarms += AH.minor_alarms()
all_alarms += AH.minor_alarms(z)
return all_alarms
@@ -104,9 +108,10 @@
var/list/data = host.initial_data()
var/categories[0]
var/z = get_z(nano_host())
for(var/datum/alarm_handler/AH in alarm_handlers)
categories[++categories.len] = list("category" = AH.category, "alarms" = list())
for(var/datum/alarm/A in AH.major_alarms())
for(var/datum/alarm/A in AH.major_alarms(z))
var/cameras[0]
var/lost_sources[0]

View File

@@ -47,12 +47,17 @@
/datum/nano_module/atmos_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
var/alarms[0]
var/turf/T = get_turf(nano_host())
var/z = get_z(nano_host())
var/list/map_levels = using_map.get_map_levels(z)
data["map_levels"] = map_levels
// TODO: Move these to a cache, similar to cameras
for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines))
if(!monitored_alarms.len && alarm.alarms_hidden)
continue
if(!(alarm.z in map_levels))
continue
alarms[++alarms.len] = list(
"name" = sanitize(alarm.name),
"ref"= "\ref[alarm]",
@@ -61,7 +66,6 @@
"y" = alarm.y,
"z" = alarm.z)
data["alarms"] = alarms
data["map_levels"] = using_map.get_map_levels(T.z)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)

View File

@@ -53,10 +53,15 @@
var/list/sensors = list()
// Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading.
var/obj/machinery/power/sensor/focus = null
var/turf/T = get_turf(nano_host())
var/z = get_z(nano_host())
var/list/map_levels = using_map.get_map_levels(z)
data["map_levels"] = map_levels
// Build list of data from sensor readings.
for(var/obj/machinery/power/sensor/S in grid_sensors)
if(!(S.z in map_levels))
continue
sensors.Add(list(list(
"name" = S.name_tag,
"alarm" = S.check_grid_warning()
@@ -67,7 +72,6 @@
data["all_sensors"] = sensors
if(focus)
data["focus"] = focus.return_reading_data()
data["map_levels"] = using_map.get_map_levels(T.z)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)

View File

@@ -122,11 +122,19 @@
// Description: Refreshes local list of known devices.
/datum/nano_module/rcon/proc/FindDevices()
known_SMESs = new /list()
var/z = get_z(nano_host())
var/list/map_levels = using_map.get_map_levels(z)
for(var/obj/machinery/power/smes/buildable/SMES in machines)
if(!(SMES.z in map_levels))
continue
if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon)
known_SMESs.Add(SMES)
known_breakers = new /list()
for(var/obj/machinery/power/breakerbox/breaker in machines)
if(!(breaker.z in map_levels))
continue
if(breaker.RCon_tag != "NO_TAG")
known_breakers.Add(breaker)

View File

@@ -41,10 +41,10 @@
// Refreshes list of active supermatter crystals
/datum/nano_module/supermatter_monitor/proc/refresh()
supermatters = list()
var/turf/T = get_turf(nano_host())
if(!T)
var/z = get_z(nano_host())
if(!z)
return
var/valid_z_levels = (GetConnectedZlevels(T.z) & using_map.station_levels)
var/valid_z_levels = using_map.get_map_levels(z)
for(var/obj/machinery/power/supermatter/S in machines)
// Delaminating, not within coverage, not on a tile.
if(S.grav_pulling || S.exploded || !(S.z in valid_z_levels) || !istype(S.loc, /turf/))

View File

@@ -15,6 +15,12 @@
return access_research
if(NETWORK_ERT)
return access_cent_specops
//VOREStation Add Start
if(NETWORK_TALON_SHIP)
return access_talon
if(NETWORK_TALON_HELMETS)
return access_talon
//VOREStation Add End
if(network in using_map.station_networks)
return access_security // Default for all other station networks
@@ -62,8 +68,10 @@
data["networks"] = all_networks
var/list/map_levels = using_map.get_map_levels(get_z(nano_host()), TRUE)
if(current_network)
data["cameras"] = camera_repository.cameras_in_network(current_network)
data["cameras"] = camera_repository.cameras_in_network(current_network, map_levels)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)

View File

@@ -1,7 +1,7 @@
/datum/computer_file/program/suit_sensors
filename = "sensormonitor"
filedesc = "Suit Sensors Monitoring"
nanomodule_path = /datum/nano_module/crew_monitor
nanomodule_path = /datum/nano_module/program/crew_monitor
program_icon_state = "crew"
program_key_state = "med_key"
program_menu_icon = "heart"
@@ -12,13 +12,10 @@
size = 11
/datum/nano_module/crew_monitor
/datum/nano_module/program/crew_monitor
name = "Crew monitor"
/datum/nano_module/crew_monitor/Topic(href, href_list)
/datum/nano_module/program/crew_monitor/Topic(href, href_list)
if(..()) return 1
var/turf/T = get_turf(nano_host()) // TODO: Allow setting any using_map.contact_levels from the interface.
if (!T || !(T.z in using_map.player_levels))
@@ -32,20 +29,25 @@
AI.ai_actual_track(H)
return 1
/datum/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
/datum/nano_module/program/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
var/turf/T = get_turf(nano_host())
data["isAI"] = isAI(user)
data["map_levels"] = using_map.get_map_levels(T.z, FALSE)
var/z = get_z(nano_host())
var/list/map_levels = using_map.get_map_levels(z, TRUE)
data["map_levels"] = map_levels
data["crewmembers"] = list()
for(var/z in data["map_levels"]) // VOREStation Edit
data["crewmembers"] += crew_repository.health_data(z)
for(var/zlevel in map_levels)
data["crewmembers"] += crew_repository.health_data(zlevel)
if(!data["map_levels"].len)
to_chat(user, "<span class='warning'>The crew monitor doesn't seem like it'll work here.</span>")
if(ui) // VOREStation Addition
ui.close() // VOREStation Addition
if(program)
program.kill_program()
else if(ui)
ui.close()
return
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -65,7 +67,7 @@
// should make the UI auto-update; doesn't seem to?
ui.set_auto_update(1)
/*/datum/nano_module/crew_monitor/proc/scan()
/*/datum/nano_module/program/crew_monitor/proc/scan()
for(var/mob/living/carbon/human/H in mob_list)
if(istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/C = H.w_uniform

View File

@@ -0,0 +1,63 @@
/datum/computer_file/program/ship_nav
filename = "navviewer"
filedesc = "Ship Navigational Screen"
nanomodule_path = /datum/nano_module/program/ship/nav
program_icon_state = "helm"
program_key_state = "generic_key"
program_menu_icon = "search"
extended_desc = "Displays a ship's location in the sector."
required_access = null
requires_ntnet = 1
network_destination = "ship position sensors"
size = 4
/datum/nano_module/program/ship/nav
name = "Navigation Display"
/datum/nano_module/program/ship/nav/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
if(!linked)
to_chat(user, "<span class='warning'>You don't appear to be on a spaceship...</span>")
if(program)
program.kill_program()
else if(ui)
ui.close()
return
var/list/data = list()
if(program)
data = program.get_header_data()
var/turf/T = get_turf(linked)
var/obj/effect/overmap/visitable/sector/current_sector = locate() in T
data["sector"] = current_sector ? current_sector.name : "Deep Space"
data["sector_info"] = current_sector ? current_sector.desc : "Not Available"
data["s_x"] = linked.x
data["s_y"] = linked.y
data["speed"] = round(linked.get_speed()*1000, 0.01)
data["accel"] = round(linked.get_acceleration()*1000, 0.01)
data["heading"] = linked.get_heading_degrees()
data["viewing"] = viewing_overmap(user)
if(linked.get_speed())
data["ETAnext"] = "[round(linked.ETA()/10)] seconds"
else
data["ETAnext"] = "N/A"
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "nav.tmpl", "[linked.name] Navigation Screen", 380, 530, state = state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/datum/nano_module/program/ship/nav/OnTopic(var/mob/user, var/list/href_list)
if(..())
return TOPIC_HANDLED
if (!linked)
return TOPIC_NOACTION
if (href_list["viewing"])
viewing_overmap(user) ? unlook(user) : look(user)
return TOPIC_REFRESH

View File

@@ -0,0 +1,87 @@
/datum/nano_module/program/ship
var/obj/effect/overmap/visitable/ship/linked
var/list/viewers
var/extra_view = 0
/datum/nano_module/program/ship/New()
..()
sync_linked()
if(linked)
name = "[linked.name] [name]"
/datum/nano_module/program/ship/Destroy()
if(LAZYLEN(viewers))
for(var/weakref/W in viewers)
var/M = W.resolve()
if(M)
unlook(M)
. = ..()
/datum/nano_module/program/ship/proc/sync_linked()
var/obj/effect/overmap/visitable/ship/sector = get_overmap_sector(get_z(nano_host()))
if(!sector)
return
return attempt_hook_up_recursive(sector)
/datum/nano_module/program/ship/proc/attempt_hook_up_recursive(obj/effect/overmap/visitable/ship/sector)
if(attempt_hook_up(sector))
return sector
for(var/obj/effect/overmap/visitable/ship/candidate in sector)
if((. = .(candidate)))
return
/datum/nano_module/program/ship/proc/attempt_hook_up(obj/effect/overmap/visitable/ship/sector)
if(!istype(sector))
return
if(sector.check_ownership(nano_host()))
linked = sector
return 1
/datum/nano_module/program/ship/proc/look(var/mob/user)
if(linked)
user.machine = nano_host()
user.reset_view(linked)
user.set_viewsize(world.view + extra_view)
GLOB.moved_event.register(user, src, /datum/nano_module/program/ship/proc/unlook)
LAZYDISTINCTADD(viewers, weakref(user))
/datum/nano_module/program/ship/proc/unlook(var/mob/user)
user.reset_view()
user.set_viewsize() // reset to default
GLOB.moved_event.unregister(user, src, /datum/nano_module/program/ship/proc/unlook)
LAZYREMOVE(viewers, weakref(user))
/datum/nano_module/program/ship/proc/viewing_overmap(mob/user)
return (weakref(user) in viewers)
/datum/nano_module/program/ship/proc/DefaultTopicState()
return global.default_state
/datum/nano_module/program/ship/Topic(var/href, var/href_list = list(), var/datum/topic_state/state)
if((. = ..()))
return
state = state || DefaultTopicState() || global.default_state
if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE)
CouldUseTopic(usr)
return OnTopic(usr, href_list, state)
CouldNotUseTopic(usr)
return TRUE
/datum/nano_module/program/ship/proc/OnTopic(var/mob/user, var/href_list, var/datum/topic_state/state)
return TOPIC_NOACTION
/datum/nano_module/program/ship/proc/CouldNotUseTopic(mob/user)
. = ..()
unlook(user)
/datum/nano_module/program/ship/proc/CouldUseTopic(mob/user)
. = ..()
if(viewing_overmap(user))
look(user)
/datum/nano_module/program/ship/check_eye(var/mob/user)
if (!get_dist(user, nano_host()) > 1 || user.blinded || !linked )
unlook(user)
return -1
else
return 0

View File

@@ -79,20 +79,25 @@ var/global/ntnet_card_uid = 1
return 0
if(holder2)
var/turf/T = get_turf(holder2)
if(!istype(T)) //no reception in nullspace
var/holderz = get_z(holder2)
if(!holderz) //no reception in nullspace
return 0
if(T.z in using_map.station_levels)
// Computer is on station. Low/High signal depending on what type of network card you have
if(long_range)
return 2
else
return 1
if(T.z in using_map.contact_levels) //not on station, but close enough for radio signal to travel
if(long_range) // Computer is not on station, but it has upgraded network card. Low signal.
return 1
return 0 // Computer is not on station and does not have upgraded network card. No signal.
var/list/zlevels_in_range = using_map.get_map_levels(holderz, long_range)
var/best = 0
for(var/relay in ntnet_global.relays)
var/obj/machinery/ntnet_relay/R = relay
//Relay is down
if(!R.operable())
continue
//We're on the same z
if(R.z == holderz)
best = 2
break // No point in going further
//Not on the same z but within range anyway
if(R.z in zlevels_in_range)
best = 1
return best
return 0 // No computer!
/obj/item/weapon/computer_hardware/network_card/Destroy()
if(holder2 && (holder2.network_card == src))

View File

@@ -30,6 +30,11 @@
var/turf/below
/turf/simulated/open/vacuum
oxygen = 0
nitrogen = 0
temperature = TCMB
/turf/simulated/open/post_change()
..()
update()

View File

@@ -5,7 +5,7 @@
access = access_medical
cost = 625
p_drain = 0.025
var/datum/nano_module/crew_monitor/arscreen
var/datum/nano_module/program/crew_monitor/arscreen
New()
..()

View File

@@ -1,145 +0,0 @@
//How far from the edge of overmap zlevel could randomly placed objects spawn
#define OVERMAP_EDGE 2
#define SHIP_SIZE_TINY 1
#define SHIP_SIZE_SMALL 2
#define SHIP_SIZE_LARGE 3
//multipliers for max_speed to find 'slow' and 'fast' speeds for the ship
#define SHIP_SPEED_SLOW 1/(40 SECONDS)
#define SHIP_SPEED_FAST 3/(20 SECONDS)// 15 speed
#define OVERMAP_WEAKNESS_NONE 0
#define OVERMAP_WEAKNESS_FIRE 1
#define OVERMAP_WEAKNESS_EMP 2
#define OVERMAP_WEAKNESS_MINING 4
#define OVERMAP_WEAKNESS_EXPLOSIVE 8
//Dimension of overmap (squares 4 lyfe)
var/global/list/map_sectors = list()
/area/overmap/
name = "System Map"
icon_state = "start"
requires_power = 0
base_turf = /turf/unsimulated/map
/turf/unsimulated/map
icon = 'icons/turf/space.dmi'
icon_state = "map"
initialized = FALSE // TODO - Fix unsimulated turf initialization so this override is not necessary!
/turf/unsimulated/map/edge
opacity = 1
density = 1
/turf/unsimulated/map/Initialize()
. = ..()
name = "[x]-[y]"
var/list/numbers = list()
if(x == 1 || x == global.using_map.overmap_size)
numbers += list("[round(y/10)]","[round(y%10)]")
if(y == 1 || y == global.using_map.overmap_size)
numbers += "-"
if(y == 1 || y == global.using_map.overmap_size)
numbers += list("[round(x/10)]","[round(x%10)]")
for(var/i = 1 to numbers.len)
var/image/I = image('icons/effects/numbers.dmi',numbers[i])
I.pixel_x = 5*i - 2
I.pixel_y = world.icon_size/2 - 3
if(y == 1)
I.pixel_y = 3
I.pixel_x = 5*i + 4
if(y == global.using_map.overmap_size)
I.pixel_y = world.icon_size - 9
I.pixel_x = 5*i + 4
if(x == 1)
I.pixel_x = 5*i - 2
if(x == global.using_map.overmap_size)
I.pixel_x = 5*i + 2
add_overlay(I)
//list used to track which zlevels are being 'moved' by the proc below
var/list/moving_levels = list()
//Proc to 'move' stars in spess
//yes it looks ugly, but it should only fire when state actually change.
//null direction stops movement
proc/toggle_move_stars(zlevel, direction)
if(!zlevel)
return
if (moving_levels["[zlevel]"] != direction)
moving_levels["[zlevel]"] = direction
var/list/spaceturfs = block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel))
for(var/turf/space/T in spaceturfs)
T.toggle_transit(direction)
CHECK_TICK
/*
//list used to cache empty zlevels to avoid nedless map bloat
var/list/cached_space = list()
proc/overmap_spacetravel(var/turf/space/T, var/atom/movable/A)
var/obj/effect/map/M = map_sectors["[T.z]"]
if (!M)
return
var/mapx = M.x
var/mapy = M.y
var/nx = 1
var/ny = 1
var/nz = M.map_z
if(T.x <= TRANSITIONEDGE)
nx = world.maxx - TRANSITIONEDGE - 2
ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
mapx = max(1, mapx-1)
else if (A.x >= (world.maxx - TRANSITIONEDGE - 1))
nx = TRANSITIONEDGE + 2
ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
mapx = min(world.maxx, mapx+1)
else if (T.y <= TRANSITIONEDGE)
ny = world.maxy - TRANSITIONEDGE -2
nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
mapy = max(1, mapy-1)
else if (A.y >= (world.maxy - TRANSITIONEDGE - 1))
ny = TRANSITIONEDGE + 2
nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
mapy = min(world.maxy, mapy+1)
testing("[A] moving from [M] ([M.x], [M.y]) to ([mapx],[mapy]).")
var/turf/map = locate(mapx,mapy,OVERMAP_ZLEVEL)
var/obj/effect/map/TM = locate() in map
if(TM)
nz = TM.map_z
testing("Destination: [TM]")
else
if(cached_space.len)
var/obj/effect/map/sector/temporary/cache = cached_space[cached_space.len]
cached_space -= cache
nz = cache.map_z
cache.x = mapx
cache.y = mapy
testing("Destination: *cached* [TM]")
else
world.maxz++
nz = world.maxz
TM = new /obj/effect/map/sector/temporary(mapx, mapy, nz)
testing("Destination: *new* [TM]")
var/turf/dest = locate(nx,ny,nz)
if(dest)
A.loc = dest
if(istype(M, /obj/effect/map/sector/temporary))
var/obj/effect/map/sector/temporary/source = M
if (source.can_die())
testing("Catching [M] for future use")
source.loc = null
cached_space += source
*/

View File

@@ -0,0 +1,5 @@
/proc/get_overmap_sector(var/z)
if(using_map.use_overmap)
return map_sectors["[z]"]
else
return null

View File

@@ -1,4 +1,4 @@
#define waypoint_sector(waypoint) map_sectors["[waypoint.z]"]
#define waypoint_sector(waypoint) get_overmap_sector(get_z(waypoint))
/datum/shuttle/autodock/overmap
warmup_time = 10

View File

@@ -82,7 +82,7 @@
//Helper for init.
/obj/effect/overmap/visitable/proc/check_ownership(obj/object)
if((object.z in map_z) && !(get_area(object) in SSshuttles.shuttle_areas))
if((get_z(object) in map_z) && !(get_area(object) in SSshuttles.shuttle_areas))
return 1
//If shuttle_name is false, will add to generic waypoints; otherwise will add to restricted. Does not do checks.

View File

@@ -17,7 +17,7 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
return 1
/obj/machinery/computer/ship/proc/sync_linked()
var/obj/effect/overmap/visitable/ship/sector = map_sectors["[z]"]
var/obj/effect/overmap/visitable/ship/sector = get_overmap_sector(z)
if(!sector)
return
return attempt_hook_up_recursive(sector)

View File

@@ -80,7 +80,7 @@
. = ..()
/obj/effect/shuttle_landmark/ship/Destroy()
var/obj/effect/overmap/visitable/ship/landable/ship = map_sectors["[z]"]
var/obj/effect/overmap/visitable/ship/landable/ship = get_overmap_sector(z)
if(istype(ship) && ship.landmark == src)
ship.landmark = null
. = ..()
@@ -141,7 +141,7 @@
on_landing(from, into)
/obj/effect/overmap/visitable/ship/landable/proc/on_landing(obj/effect/shuttle_landmark/from, obj/effect/shuttle_landmark/into)
var/obj/effect/overmap/visitable/target = map_sectors["[into.z]"]
var/obj/effect/overmap/visitable/target = get_overmap_sector(get_z(into))
var/datum/shuttle/shuttle_datum = SSshuttles.shuttles[shuttle]
if(into.landmark_tag == shuttle_datum.motherdock) // If our motherdock is a landable ship, it won't be found properly here so we need to find it manually.
for(var/obj/effect/overmap/visitable/ship/landable/landable in SSshuttles.ships)

View File

@@ -57,7 +57,7 @@ proc/overmap_spacetravel(var/turf/space/T, var/atom/movable/A)
if (!T || !A)
return
var/obj/effect/overmap/visitable/M = map_sectors["[T.z]"]
var/obj/effect/overmap/visitable/M = get_overmap_sector(T.z)
if (!M)
return

View File

@@ -1,7 +1,7 @@
//Dimension of overmap (squares 4 lyfe)
var/global/list/map_sectors = list()
/area/overmap/
/area/overmap
name = "System Map"
icon_state = "start"
requires_power = 0

View File

@@ -55,14 +55,14 @@
if(!istype(docking_controller))
log_error("Could not find docking controller for shuttle waypoint '[name]', docking tag was '[docking_tag]'.")
if(using_map.use_overmap)
var/obj/effect/overmap/visitable/location = map_sectors["[z]"]
var/obj/effect/overmap/visitable/location = get_overmap_sector(z)
if(location && location.docking_codes)
docking_controller.docking_codes = location.docking_codes
/obj/effect/shuttle_landmark/forceMove()
var/obj/effect/overmap/visitable/map_origin = map_sectors["[z]"]
var/obj/effect/overmap/visitable/map_origin = get_overmap_sector(z)
. = ..()
var/obj/effect/overmap/visitable/map_destination = map_sectors["[z]"]
var/obj/effect/overmap/visitable/map_destination = get_overmap_sector(z)
if(map_origin != map_destination)
if(map_origin)
map_origin.remove_landmark(src, shuttle_restricted)

View File

@@ -30,7 +30,7 @@
if(active_docking_controller)
set_docking_codes(active_docking_controller.docking_codes)
else if(global.using_map.use_overmap)
var/obj/effect/overmap/visitable/location = map_sectors["[current_location.z]"]
var/obj/effect/overmap/visitable/location = get_overmap_sector(get_z(current_location))
if(location && location.docking_codes)
set_docking_codes(location.docking_codes)
dock()

View File

@@ -159,7 +159,7 @@ GLOBAL_LIST_BOILERPLATE(papers_dockingcode, /obj/item/weapon/paper/dockingcodes)
var/dockingcodes = null
var/z_to_check = codes_from_z ? codes_from_z : z
if(using_map.use_overmap)
var/obj/effect/overmap/visitable/location = map_sectors["[z_to_check]"]
var/obj/effect/overmap/visitable/location = get_overmap_sector(z_to_check)
if(location && location.docking_codes)
dockingcodes = location.docking_codes

View File

@@ -106,18 +106,8 @@
if(telepad.panel_open)
data["tempMsg"] = "Telepad undergoing physical maintenance operations."
data["sectorOptions"] = list()
//We'll base our options on overmap range
if(using_map.use_overmap)
data["sectorOptions"] += z //Definitely at least our own even if we're not in an overmap sector.
var/obj/effect/overmap/visitable/my_sector = map_sectors["[z]"]
if(my_sector)
for(var/obj/effect/overmap/visitable/S in range(get_turf(my_sector), overmap_range))
data["sectorOptions"] |= S.map_z
//We'll base our options on player_levels
else
for(var/z in using_map.player_levels)
data["sectorOptions"] += z
//We'll base our options on connected z's or overmap
data["sectorOptions"] = using_map.get_map_levels(z, TRUE, overmap_range)
if(last_tele_data)
data["lastTeleData"] = list()