Merge remote-tracking branch 'refs/remotes/Citadel-Station-13/master' into IHAVENOIDEAWHATTHEFUCKIMDOING
This commit is contained in:
@@ -41,7 +41,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
power_environ = FALSE
|
||||
valid_territory = FALSE
|
||||
outdoors = TRUE
|
||||
ambientsounds = list('sound/ambience/ambispace.ogg','sound/ambience/title2.ogg')
|
||||
ambientsounds = SPACE
|
||||
blob_allowed = FALSE //Eating up space doesn't count for victory as a blob.
|
||||
|
||||
/area/space/nearstation
|
||||
@@ -65,6 +65,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
has_gravity = TRUE
|
||||
blob_allowed = FALSE //Nope, no winning on the asteroid as a blob. Gotta eat the station.
|
||||
valid_territory = FALSE
|
||||
ambientsounds = MINING
|
||||
|
||||
/area/asteroid/cave
|
||||
name = "Asteroid - Underground"
|
||||
@@ -75,6 +76,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/asteroid/artifactroom
|
||||
name = "Asteroid - Artifact"
|
||||
icon_state = "cave"
|
||||
ambientsounds = RUINS
|
||||
|
||||
/area/asteroid/artifactroom/Initialize()
|
||||
. = ..()
|
||||
@@ -96,14 +98,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
//Maintenance
|
||||
|
||||
/area/maintenance
|
||||
ambientsounds = list('sound/ambience/ambimaint1.ogg',
|
||||
'sound/ambience/ambimaint2.ogg',
|
||||
'sound/ambience/ambimaint3.ogg',
|
||||
'sound/ambience/ambimaint4.ogg',
|
||||
'sound/ambience/ambimaint5.ogg',
|
||||
'sound/voice/lowHiss2.ogg', //Xeno Breathing Hisses, Hahahaha I'm not even sorry.
|
||||
'sound/voice/lowHiss3.ogg',
|
||||
'sound/voice/lowHiss4.ogg')
|
||||
ambientsounds = MAINTENANCE
|
||||
valid_territory = FALSE
|
||||
|
||||
|
||||
@@ -111,43 +106,43 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/maintenance/department/chapel
|
||||
name = "Chapel Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
icon_state = "maint_chapel"
|
||||
|
||||
/area/maintenance/department/chapel/monastery
|
||||
name = "Monastery Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
icon_state = "maint_monastery"
|
||||
|
||||
/area/maintenance/department/crew_quarters/bar
|
||||
name = "Bar Maintenance"
|
||||
icon_state = "fsmaint"
|
||||
icon_state = "maint_bar"
|
||||
|
||||
/area/maintenance/department/crew_quarters/dorms
|
||||
name = "Dormitory Maintenance"
|
||||
icon_state = "fsmaint"
|
||||
icon_state = "maint_dorms"
|
||||
|
||||
/area/maintenance/department/crew_quarters/locker
|
||||
name = "Locker Room Maintenance"
|
||||
icon_state = "pmaint"
|
||||
icon_state = "maint_locker"
|
||||
|
||||
/area/maintenance/department/eva
|
||||
name = "EVA Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
icon_state = "maint_eva"
|
||||
|
||||
/area/maintenance/department/electrical
|
||||
name = "Electrical Maintenance"
|
||||
icon_state = "yellow"
|
||||
icon_state = "maint_electrical"
|
||||
|
||||
/area/maintenance/department/engine/atmos
|
||||
name = "Atmospherics Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
icon_state = "maint_atmos"
|
||||
|
||||
/area/maintenance/department/security
|
||||
name = "Security Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
icon_state = "maint_sec"
|
||||
|
||||
/area/maintenance/department/security/brig
|
||||
name = "Brig Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
icon_state = "maint_brig"
|
||||
|
||||
/area/maintenance/department/medical
|
||||
name = "Medbay Maintenance"
|
||||
@@ -159,19 +154,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/maintenance/department/science
|
||||
name = "Science Maintenance"
|
||||
icon_state = "asmaint"
|
||||
icon_state = "maint_sci"
|
||||
|
||||
/area/maintenance/department/cargo
|
||||
name = "Cargo Maintenance"
|
||||
icon_state = "apmaint"
|
||||
icon_state = "maint_cargo"
|
||||
|
||||
/area/maintenance/department/bridge
|
||||
name = "Bridge Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
icon_state = "maint_bridge"
|
||||
|
||||
/area/maintenance/department/engine
|
||||
name = "Engineering Maintenance"
|
||||
icon_state = "amaint"
|
||||
icon_state = "maint_engi"
|
||||
|
||||
/area/maintenance/department/science/xenobiology
|
||||
name = "Xenobiology Maintenance"
|
||||
@@ -621,7 +616,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/crew_quarters/abandoned_gambling_den
|
||||
name = "Abandoned Gambling Den"
|
||||
icon_state = "bar"
|
||||
icon_state = "abandoned_g_den"
|
||||
|
||||
/area/crew_quarters/abandoned_gambling_den/secondary
|
||||
icon_state = "abandoned_g_den_2"
|
||||
|
||||
/area/crew_quarters/theatre
|
||||
name = "Theatre"
|
||||
@@ -647,7 +645,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/chapel
|
||||
icon_state = "chapel"
|
||||
ambientsounds = list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg','sound/ambience/ambicha4.ogg')
|
||||
ambientsounds = HOLY
|
||||
flags_1 = NONE
|
||||
clockwork_warp_allowed = FALSE
|
||||
clockwork_warp_fail = "The consecration here prevents you from warping in."
|
||||
@@ -678,7 +676,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
//Engineering
|
||||
|
||||
/area/engine
|
||||
ambientsounds = list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg')
|
||||
ambientsounds = ENGINEERING
|
||||
|
||||
/area/engine/engine_smes
|
||||
name = "Engineering SMES"
|
||||
@@ -732,6 +730,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
valid_territory = FALSE
|
||||
blob_allowed = FALSE
|
||||
flags_1 = NONE
|
||||
ambientsounds = ENGINEERING
|
||||
|
||||
/area/solar/asteroid/aft
|
||||
name = "Aft Asteroid Solar"
|
||||
@@ -858,37 +857,36 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Teleporter Room"
|
||||
icon_state = "teleporter"
|
||||
music = "signal"
|
||||
ambientsounds = ENGINEERING
|
||||
|
||||
/area/teleporter/quantum/cargo
|
||||
name = "Cargo Quantum Pad"
|
||||
icon_state = "teleporter"
|
||||
music = "signal"
|
||||
|
||||
/area/teleporter/quantum/docking
|
||||
name = "Docking Quantum Pad"
|
||||
icon_state = "teleporter"
|
||||
music = "signal"
|
||||
|
||||
/area/teleporter/quantum/research
|
||||
name = "Research Quantum Pad"
|
||||
icon_state = "teleporter"
|
||||
music = "signal"
|
||||
|
||||
/area/teleporter/quantum/security
|
||||
name = "Security Quantum Pad"
|
||||
icon_state = "teleporter"
|
||||
music = "signal"
|
||||
|
||||
/area/gateway
|
||||
name = "Gateway"
|
||||
icon_state = "teleporter"
|
||||
icon_state = "gateway"
|
||||
music = "signal"
|
||||
ambientsounds = ENGINEERING
|
||||
|
||||
//MedBay
|
||||
|
||||
/area/medical
|
||||
name = "Medical"
|
||||
icon_state = "medbay3"
|
||||
ambientsounds = MEDICAL
|
||||
|
||||
/area/medical/abandoned
|
||||
name = "Abandoned Medbay"
|
||||
@@ -952,7 +950,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/medical/morgue
|
||||
name = "Morgue"
|
||||
icon_state = "morgue"
|
||||
ambientsounds = list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg')
|
||||
ambientsounds = SPOOKY
|
||||
|
||||
/area/medical/chemistry
|
||||
name = "Chemistry"
|
||||
@@ -988,6 +986,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/security
|
||||
name = "Security"
|
||||
icon_state = "security"
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
/area/security/main
|
||||
name = "Security Office"
|
||||
@@ -1029,7 +1028,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/security/detectives_office/private_investigators_office
|
||||
name = "Private Investigator's Office"
|
||||
icon_state = "detective"
|
||||
ambientsounds = list('sound/ambience/ambidet1.ogg','sound/ambience/ambidet2.ogg')
|
||||
|
||||
/area/security/range
|
||||
name = "Firing Range"
|
||||
@@ -1056,33 +1054,41 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Security Checkpoint"
|
||||
icon_state = "checkpoint1"
|
||||
|
||||
/area/security/checkpoint/checkpoint2
|
||||
name = "Security Checkpoint"
|
||||
icon_state = "security"
|
||||
/area/security/checkpoint/auxiliary
|
||||
icon_state = "checkpoint_aux"
|
||||
|
||||
/area/security/checkpoint/tertiary
|
||||
icon_state = "checkpoint_tert"
|
||||
|
||||
/area/security/checkpoint/escape
|
||||
icon_state = "checkpoint_esc"
|
||||
|
||||
/area/security/checkpoint/supply
|
||||
name = "Security Post - Cargo Bay"
|
||||
icon_state = "checkpoint1"
|
||||
icon_state = "checkpoint_supp"
|
||||
|
||||
/area/security/checkpoint/engineering
|
||||
name = "Security Post - Engineering"
|
||||
icon_state = "checkpoint1"
|
||||
icon_state = "checkpoint_engi"
|
||||
|
||||
/area/security/checkpoint/medical
|
||||
name = "Security Post - Medbay"
|
||||
icon_state = "checkpoint1"
|
||||
icon_state = "checkpoint_med"
|
||||
|
||||
/area/security/checkpoint/science
|
||||
name = "Security Post - Science"
|
||||
icon_state = "checkpoint1"
|
||||
icon_state = "checkpoint_sci"
|
||||
|
||||
/area/security/checkpoint/science/research
|
||||
name = "Security Post - Research Division"
|
||||
icon_state = "checkpoint1"
|
||||
icon_state = "checkpoint_res"
|
||||
|
||||
/area/security/checkpoint/customs
|
||||
name = "Customs"
|
||||
icon_state = "bridge"
|
||||
icon_state = "customs_point"
|
||||
|
||||
/area/security/checkpoint/customs/auxiliary
|
||||
icon_state = "customs_point_aux"
|
||||
|
||||
/area/security/vacantoffice
|
||||
name = "Vacant Office"
|
||||
@@ -1310,6 +1316,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/construction
|
||||
name = "Construction Area"
|
||||
icon_state = "yellow"
|
||||
ambientsounds = ENGINEERING
|
||||
|
||||
/area/construction/minisat_exterior
|
||||
name = "Minisat Exterior"
|
||||
@@ -1361,27 +1368,32 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/ai_monitored/security/armory
|
||||
name = "Armory"
|
||||
icon_state = "armory"
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
/area/ai_monitored/storage/eva
|
||||
name = "EVA Storage"
|
||||
icon_state = "eva"
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
/area/ai_monitored/storage/secure
|
||||
name = "AI Satellite Storage"
|
||||
icon_state = "storage"
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
/area/ai_monitored/storage/emergency
|
||||
name = "Emergency Storage"
|
||||
icon_state = "storage"
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
/area/ai_monitored/storage/satellite
|
||||
name = "AI Satellite Maint"
|
||||
icon_state = "storage"
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
//Turret_protected
|
||||
|
||||
/area/ai_monitored/turret_protected
|
||||
ambientsounds = list('sound/ambience/ambimalf.ogg')
|
||||
ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg')
|
||||
|
||||
/area/ai_monitored/turret_protected/ai_upload
|
||||
name = "AI Upload Chamber"
|
||||
@@ -1450,7 +1462,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/tcommsat
|
||||
clockwork_warp_allowed = FALSE
|
||||
clockwork_warp_fail = "For safety reasons, warping here is disallowed; the radio and bluespace noise could cause catastrophic results."
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg', 'sound/ambience/ambitech.ogg',\
|
||||
'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg', 'sound/ambience/ambimystery.ogg')
|
||||
|
||||
/area/tcommsat/entrance
|
||||
name = "Telecomms Teleporter"
|
||||
@@ -1463,22 +1476,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/ai_monitored/turret_protected/tcomsat
|
||||
name = "Telecomms Satellite"
|
||||
icon_state = "tcomsatlob"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/ai_monitored/turret_protected/tcomfoyer
|
||||
name = "Telecomms Foyer"
|
||||
icon_state = "tcomsatentrance"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/ai_monitored/turret_protected/tcomwest
|
||||
name = "Telecommunications Satellite West Wing"
|
||||
icon_state = "tcomsatwest"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/ai_monitored/turret_protected/tcomeast
|
||||
name = "Telecommunications Satellite East Wing"
|
||||
icon_state = "tcomsateast"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/tcommsat/computer
|
||||
name = "Telecomms Control Room"
|
||||
@@ -1526,4 +1535,4 @@ GLOBAL_LIST_INIT(the_station_areas, list (
|
||||
/area/ai_monitored/turret_protected/ai_upload, //do not try to simplify to "/area/ai_monitored/turret_protected" --rastaf0
|
||||
/area/ai_monitored/turret_protected/ai_upload_foyer,
|
||||
/area/ai_monitored/turret_protected/ai,
|
||||
))
|
||||
))
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "AI Monitored Area"
|
||||
clockwork_warp_allowed = FALSE
|
||||
var/list/obj/machinery/camera/motioncameras = list()
|
||||
var/list/motionTargets = list()
|
||||
var/list/datum/weakref/motionTargets = list()
|
||||
|
||||
/area/ai_monitored/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -27,5 +27,5 @@
|
||||
if (ismob(O) && motioncameras.len)
|
||||
for(var/X in motioncameras)
|
||||
var/obj/machinery/camera/cam = X
|
||||
cam.lostTarget(O)
|
||||
cam.lostTargetRef(WEAKREF(O))
|
||||
return
|
||||
|
||||
+76
-37
@@ -54,15 +54,12 @@
|
||||
|
||||
var/global/global_uid = 0
|
||||
var/uid
|
||||
var/list/ambientsounds = list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg',\
|
||||
'sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg',\
|
||||
'sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg',\
|
||||
'sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg',\
|
||||
'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\
|
||||
'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
|
||||
var/list/ambientsounds = GENERIC
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
|
||||
var/list/firedoors
|
||||
var/list/cameras
|
||||
var/list/firealarms
|
||||
var/firedoors_last_closed_on = 0
|
||||
|
||||
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
|
||||
@@ -125,13 +122,32 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
|
||||
. = ..()
|
||||
|
||||
power_change() // all machines set to current power level, also updates icon
|
||||
|
||||
blend_mode = BLEND_MULTIPLY // Putting this in the constructor so that it stops the icons being screwed up in the map editor.
|
||||
|
||||
if(!IS_DYNAMIC_LIGHTING(src))
|
||||
add_overlay(/obj/effect/fullbright)
|
||||
|
||||
if(contents.len)
|
||||
var/list/areas_in_z = SSmapping.areas_in_z
|
||||
var/z
|
||||
for(var/i in 1 to contents.len)
|
||||
var/atom/thing = contents[i]
|
||||
if(!thing)
|
||||
continue
|
||||
z = thing.z
|
||||
break
|
||||
if(!z)
|
||||
WARNING("No z found for [src]")
|
||||
return
|
||||
if(!areas_in_z["[z]"])
|
||||
areas_in_z["[z]"] = list()
|
||||
areas_in_z["[z]"] += src
|
||||
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/area/LateInitialize()
|
||||
power_change() // all machines set to current power level, also updates icon
|
||||
|
||||
/area/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
@@ -140,27 +156,28 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if (state != poweralm)
|
||||
poweralm = state
|
||||
if(istype(source)) //Only report power alarms on the z-level where the source is located.
|
||||
var/list/cameras = list()
|
||||
for (var/obj/machinery/camera/C in src)
|
||||
cameras += C
|
||||
for (var/mob/living/silicon/aiPlayer in GLOB.player_list)
|
||||
for (var/item in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = item
|
||||
if (state == 1)
|
||||
aiPlayer.cancelAlarm("Power", src, source)
|
||||
else
|
||||
aiPlayer.triggerAlarm("Power", src, cameras, source)
|
||||
|
||||
for(var/obj/machinery/computer/station_alert/a in GLOB.machines)
|
||||
for (var/item in GLOB.alert_consoles)
|
||||
var/obj/machinery/computer/station_alert/a = item
|
||||
if(state == 1)
|
||||
a.cancelAlarm("Power", src, source)
|
||||
else
|
||||
a.triggerAlarm("Power", src, cameras, source)
|
||||
|
||||
for(var/mob/living/simple_animal/drone/D in GLOB.mob_list)
|
||||
for (var/item in GLOB.drones_list)
|
||||
var/mob/living/simple_animal/drone/D = item
|
||||
if(state == 1)
|
||||
D.cancelAlarm("Power", src, source)
|
||||
else
|
||||
D.triggerAlarm("Power", src, cameras, source)
|
||||
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
|
||||
for(var/item in GLOB.alarmdisplay)
|
||||
var/datum/computer_file/program/alarm_monitor/p = item
|
||||
if(state == 1)
|
||||
p.cancelAlarm("Power", src, source)
|
||||
else
|
||||
@@ -171,26 +188,35 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if (danger_level==2)
|
||||
var/list/cameras = list()
|
||||
for(var/area/RA in related)
|
||||
for(var/obj/machinery/camera/C in RA)
|
||||
for (var/item in RA.cameras)
|
||||
var/obj/machinery/camera/C = item
|
||||
cameras += C
|
||||
|
||||
for(var/mob/living/silicon/aiPlayer in GLOB.player_list)
|
||||
for (var/item in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = item
|
||||
aiPlayer.triggerAlarm("Atmosphere", src, cameras, source)
|
||||
for(var/obj/machinery/computer/station_alert/a in GLOB.machines)
|
||||
for (var/item in GLOB.alert_consoles)
|
||||
var/obj/machinery/computer/station_alert/a = item
|
||||
a.triggerAlarm("Atmosphere", src, cameras, source)
|
||||
for(var/mob/living/simple_animal/drone/D in GLOB.mob_list)
|
||||
for (var/item in GLOB.drones_list)
|
||||
var/mob/living/simple_animal/drone/D = item
|
||||
D.triggerAlarm("Atmosphere", src, cameras, source)
|
||||
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
|
||||
for(var/item in GLOB.alarmdisplay)
|
||||
var/datum/computer_file/program/alarm_monitor/p = item
|
||||
p.triggerAlarm("Atmosphere", src, cameras, source)
|
||||
|
||||
else if (src.atmosalm == 2)
|
||||
for(var/mob/living/silicon/aiPlayer in GLOB.player_list)
|
||||
for (var/item in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = item
|
||||
aiPlayer.cancelAlarm("Atmosphere", src, source)
|
||||
for(var/obj/machinery/computer/station_alert/a in GLOB.machines)
|
||||
for (var/item in GLOB.alert_consoles)
|
||||
var/obj/machinery/computer/station_alert/a = item
|
||||
a.cancelAlarm("Atmosphere", src, source)
|
||||
for(var/mob/living/simple_animal/drone/D in GLOB.mob_list)
|
||||
for (var/item in GLOB.drones_list)
|
||||
var/mob/living/simple_animal/drone/D = item
|
||||
D.cancelAlarm("Atmosphere", src, source)
|
||||
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
|
||||
for(var/item in GLOB.alarmdisplay)
|
||||
var/datum/computer_file/program/alarm_monitor/p = item
|
||||
p.cancelAlarm("Atmosphere", src, source)
|
||||
|
||||
src.atmosalm = danger_level
|
||||
@@ -225,18 +251,24 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if (!( RA.fire ))
|
||||
RA.set_fire_alarm_effect()
|
||||
RA.ModifyFiredoors(FALSE)
|
||||
for(var/obj/machinery/firealarm/F in RA)
|
||||
for(var/item in RA.firealarms)
|
||||
var/obj/machinery/firealarm/F = item
|
||||
F.update_icon()
|
||||
for (var/obj/machinery/camera/C in RA)
|
||||
for (var/item in RA.cameras)
|
||||
var/obj/machinery/camera/C = item
|
||||
cameras += C
|
||||
|
||||
for (var/obj/machinery/computer/station_alert/a in GLOB.machines)
|
||||
for (var/item in GLOB.alert_consoles)
|
||||
var/obj/machinery/computer/station_alert/a = item
|
||||
a.triggerAlarm("Fire", src, cameras, source)
|
||||
for (var/mob/living/silicon/aiPlayer in GLOB.player_list)
|
||||
for (var/item in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = item
|
||||
aiPlayer.triggerAlarm("Fire", src, cameras, source)
|
||||
for (var/mob/living/simple_animal/drone/D in GLOB.mob_list)
|
||||
for (var/item in GLOB.drones_list)
|
||||
var/mob/living/simple_animal/drone/D = item
|
||||
D.triggerAlarm("Fire", src, cameras, source)
|
||||
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
|
||||
for(var/item in GLOB.alarmdisplay)
|
||||
var/datum/computer_file/program/alarm_monitor/p = item
|
||||
p.triggerAlarm("Fire", src, cameras, source)
|
||||
|
||||
START_PROCESSING(SSobj, src)
|
||||
@@ -248,16 +280,21 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
RA.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
RA.updateicon()
|
||||
RA.ModifyFiredoors(TRUE)
|
||||
for(var/obj/machinery/firealarm/F in RA)
|
||||
for(var/item in RA.firealarms)
|
||||
var/obj/machinery/firealarm/F = item
|
||||
F.update_icon()
|
||||
|
||||
for (var/mob/living/silicon/aiPlayer in GLOB.player_list)
|
||||
for (var/item in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = item
|
||||
aiPlayer.cancelAlarm("Fire", src, source)
|
||||
for (var/obj/machinery/computer/station_alert/a in GLOB.machines)
|
||||
for (var/item in GLOB.alert_consoles)
|
||||
var/obj/machinery/computer/station_alert/a = item
|
||||
a.cancelAlarm("Fire", src, source)
|
||||
for (var/mob/living/simple_animal/drone/D in GLOB.mob_list)
|
||||
for (var/item in GLOB.drones_list)
|
||||
var/mob/living/simple_animal/drone/D = item
|
||||
D.cancelAlarm("Fire", src, source)
|
||||
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
|
||||
for(var/item in GLOB.alarmdisplay)
|
||||
var/datum/computer_file/program/alarm_monitor/p = item
|
||||
p.cancelAlarm("Fire", src, source)
|
||||
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
@@ -285,10 +322,12 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
//Lockdown airlocks
|
||||
for(var/obj/machinery/door/DOOR in RA)
|
||||
close_and_lock_door(DOOR)
|
||||
for (var/obj/machinery/camera/C in RA)
|
||||
for (var/item in RA.cameras)
|
||||
var/obj/machinery/camera/C = item
|
||||
cameras += C
|
||||
|
||||
for (var/mob/living/silicon/SILICON in GLOB.player_list)
|
||||
for (var/i in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/SILICON = i
|
||||
if(SILICON.triggerAlarm("Burglar", src, cameras, trigger))
|
||||
//Cancel silicon alert after 1 minute
|
||||
addtimer(CALLBACK(SILICON, /mob/living/silicon.proc/cancelAlarm,"Burglar",src,trigger), 600)
|
||||
|
||||
@@ -8,6 +8,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
|
||||
name = "Strange Location"
|
||||
icon_state = "away"
|
||||
has_gravity = TRUE
|
||||
ambientsounds = AWAY_MISSION
|
||||
|
||||
/area/awaymission/beach
|
||||
name = "Beach"
|
||||
@@ -15,7 +16,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
requires_power = FALSE
|
||||
has_gravity = TRUE
|
||||
ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg')
|
||||
ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg','sound/ambience/ambiodd.ogg','sound/ambience/ambinice.ogg')
|
||||
|
||||
/area/awaymission/errorroom
|
||||
name = "Super Secret Room"
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
noteleport = TRUE
|
||||
blob_allowed = FALSE //Not... entirely sure this will ever come up... but if the bus makes blobs AND ops, it shouldn't aim for the ops to win.
|
||||
flags_1 = NONE
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
/area/syndicate_mothership/control
|
||||
name = "Syndicate Control Room"
|
||||
@@ -153,6 +154,7 @@
|
||||
has_gravity = TRUE
|
||||
noteleport = TRUE
|
||||
hidden = TRUE
|
||||
ambientsounds = REEBE
|
||||
|
||||
/area/reebe/city_of_cogs
|
||||
name = "City of Cogs"
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
outdoors = TRUE
|
||||
ambientsounds = list('sound/ambience/ambimine.ogg')
|
||||
flags_1 = NONE
|
||||
ambientsounds = MINING
|
||||
|
||||
/area/mine/unexplored
|
||||
name = "Mine"
|
||||
@@ -29,8 +29,8 @@
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
outdoors = TRUE
|
||||
ambientsounds = list('sound/ambience/ambimine.ogg')
|
||||
flags_1 = NONE
|
||||
ambientsounds = MINING
|
||||
|
||||
/area/mine/lobby
|
||||
name = "Mining Station"
|
||||
@@ -77,6 +77,7 @@
|
||||
/area/mine/laborcamp/security
|
||||
name = "Labor Camp Security"
|
||||
icon_state = "security"
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
|
||||
|
||||
@@ -98,7 +99,7 @@
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
requires_power = TRUE
|
||||
ambientsounds = list('sound/ambience/ambilava.ogg')
|
||||
ambientsounds = MINING
|
||||
|
||||
/area/lavaland/underground
|
||||
name = "Lavaland Caves"
|
||||
@@ -110,7 +111,7 @@
|
||||
power_environ = FALSE
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
ambientsounds = list('sound/ambience/ambilava.ogg')
|
||||
ambientsounds = MINING
|
||||
|
||||
|
||||
/area/lavaland/surface/outdoors
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
//icon = "ICON FILENAME"
|
||||
//icon_state = "NAME OF ICON"
|
||||
requires_power = FALSE
|
||||
ambientsounds = SPOOKY
|
||||
|
||||
/area/hell/trial1
|
||||
name = "Hell Trial1"
|
||||
@@ -32,6 +33,7 @@
|
||||
/area/prison
|
||||
name = "Prison Station"
|
||||
icon_state = "brig"
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
/area/prison/arrival_airlock
|
||||
name = "Prison Station Airlock"
|
||||
@@ -73,7 +75,7 @@
|
||||
/area/prison/morgue
|
||||
name = "Prison Morgue"
|
||||
icon_state = "morgue"
|
||||
ambientsounds = list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg')
|
||||
ambientsounds = SPOOKY
|
||||
|
||||
/area/prison/medical_research
|
||||
name = "Prison Genetic Research"
|
||||
@@ -99,7 +101,7 @@
|
||||
/area/prison/solitary
|
||||
name = "Solitary Confinement"
|
||||
icon_state = "brig"
|
||||
|
||||
|
||||
/area/prison/execution_room
|
||||
name = "Prisoner Education Chamber"
|
||||
icon_state = "execution_room"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
has_gravity = TRUE
|
||||
hidden = TRUE
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
ambientsounds = RUINS
|
||||
|
||||
|
||||
/area/ruin/unpowered
|
||||
@@ -16,4 +17,3 @@
|
||||
|
||||
/area/ruin/powered
|
||||
requires_power = FALSE
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
power_environ = FALSE
|
||||
valid_territory = FALSE
|
||||
outdoors = TRUE
|
||||
ambientsounds = list('sound/ambience/ambispace.ogg','sound/ambience/title2.ogg')
|
||||
ambientsounds = SPACE
|
||||
blob_allowed = FALSE
|
||||
|
||||
/////////////
|
||||
@@ -434,4 +434,4 @@
|
||||
/area/ruin/space/has_grav/whiteship/box
|
||||
|
||||
name = "Abandoned Ship"
|
||||
icon_state = "red"
|
||||
icon_state = "red"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
/area/shuttle/syndicate
|
||||
name = "Syndicate Infiltrator"
|
||||
blob_allowed = FALSE
|
||||
ambientsounds = HIGHSEC
|
||||
|
||||
/area/shuttle/syndicate/bridge
|
||||
name = "Syndicate Infiltrator Control"
|
||||
@@ -42,6 +43,9 @@
|
||||
name = "Hyperspace"
|
||||
desc = "Weeeeee"
|
||||
|
||||
/area/shuttle/custom
|
||||
name = "Custom player shuttle"
|
||||
|
||||
/area/shuttle/arrival
|
||||
name = "Arrival Shuttle"
|
||||
|
||||
@@ -106,4 +110,13 @@
|
||||
|
||||
/area/shuttle/syndicate_scout
|
||||
name = "Syndicate Scout"
|
||||
blob_allowed = FALSE
|
||||
blob_allowed = FALSE
|
||||
|
||||
/area/shuttle/pirate
|
||||
name = "Pirate Shuttle"
|
||||
blob_allowed = FALSE
|
||||
requires_power = TRUE
|
||||
|
||||
/area/shuttle/pirate/vault
|
||||
name = "Pirate Shuttle Vault"
|
||||
requires_power = FALSE
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
/area/spacecontent
|
||||
name = "space"
|
||||
ambientsounds = AWAY_MISSION
|
||||
|
||||
/area/spacecontent/a1
|
||||
icon_state = "spacecontent1"
|
||||
|
||||
+21
-31
@@ -99,7 +99,6 @@
|
||||
|
||||
LAZYCLEARLIST(overlays)
|
||||
LAZYCLEARLIST(priority_overlays)
|
||||
//SSoverlays.processing -= src //we COULD do this, but it's better to just let it fall out of the processing queue
|
||||
|
||||
QDEL_NULL(light)
|
||||
|
||||
@@ -244,32 +243,6 @@
|
||||
else if(src in container)
|
||||
return 1
|
||||
|
||||
/*
|
||||
* atom/proc/search_contents_for(path,list/filter_path=null)
|
||||
* Recursevly searches all atom contens (including contents contents and so on).
|
||||
*
|
||||
* ARGS: path - search atom contents for atoms of this type
|
||||
* list/filter_path - if set, contents of atoms not of types in this list are excluded from search.
|
||||
*
|
||||
* RETURNS: list of found atoms
|
||||
*/
|
||||
|
||||
/atom/proc/search_contents_for(path,list/filter_path=null)
|
||||
var/list/found = list()
|
||||
for(var/atom/A in src)
|
||||
if(istype(A, path))
|
||||
found += A
|
||||
if(filter_path)
|
||||
var/pass = 0
|
||||
for(var/type in filter_path)
|
||||
pass |= istype(A, type)
|
||||
if(!pass)
|
||||
continue
|
||||
if(A.contents.len)
|
||||
found += A.search_contents_for(path,filter_path)
|
||||
return found
|
||||
|
||||
|
||||
/atom/proc/examine(mob/user)
|
||||
//This reformat names to get a/an properly working on item descriptions when they are bloody
|
||||
var/f_name = "\a [src]."
|
||||
@@ -335,7 +308,7 @@
|
||||
GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
|
||||
/atom/proc/blood_splatter_index()
|
||||
return "\ref[initial(icon)]-[initial(icon_state)]"
|
||||
return "[REF(initial(icon))]-[initial(icon_state)]"
|
||||
|
||||
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
|
||||
/mob/living/proc/get_blood_dna_list()
|
||||
@@ -631,9 +604,9 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
var/turf/curturf = get_turf(src)
|
||||
if (curturf)
|
||||
.["Jump to"] = "?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]"
|
||||
.["Add reagent"] = "?_src_=vars;[HrefToken()];addreagent=\ref[src]"
|
||||
.["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=\ref[src]"
|
||||
.["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=\ref[src]"
|
||||
.["Add reagent"] = "?_src_=vars;[HrefToken()];addreagent=[REF(src)]"
|
||||
.["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=[REF(src)]"
|
||||
.["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=[REF(src)]"
|
||||
|
||||
/atom/proc/drop_location()
|
||||
var/atom/L = loc
|
||||
@@ -646,3 +619,20 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
|
||||
/atom/proc/return_temperature()
|
||||
return
|
||||
|
||||
// Default tool behaviors proc
|
||||
|
||||
/atom/proc/crowbar_act(mob/user, obj/item/tool)
|
||||
return
|
||||
|
||||
/atom/proc/multitool_act(mob/user, obj/item/tool)
|
||||
return
|
||||
|
||||
/atom/proc/screwdriver_act(mob/user, obj/item/tool)
|
||||
return
|
||||
|
||||
/atom/proc/wrench_act(mob/user, obj/item/tool)
|
||||
return
|
||||
|
||||
/atom/proc/wirecutter_act(mob/user, obj/item/tool)
|
||||
return
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
/atom/movable/Move(atom/newloc, direct = 0)
|
||||
if(!loc || !newloc)
|
||||
return 0
|
||||
return FALSE
|
||||
var/atom/oldloc = loc
|
||||
|
||||
if(loc != newloc)
|
||||
@@ -113,7 +113,7 @@
|
||||
last_move = direct
|
||||
setDir(direct)
|
||||
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
|
||||
. = 0
|
||||
return FALSE
|
||||
|
||||
//Called after a successful Move(). By this point, we've already moved
|
||||
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
|
||||
@@ -325,9 +325,6 @@
|
||||
SSspacedrift.processing[src] = src
|
||||
return 1
|
||||
|
||||
/atom/movable/proc/checkpass(passflag)
|
||||
return pass_flags&passflag
|
||||
|
||||
/atom/movable/proc/throw_impact(atom/hit_atom, throwingdatum)
|
||||
set waitfor = 0
|
||||
SendSignal(COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
|
||||
@@ -523,7 +520,7 @@
|
||||
/atom/movable/vv_get_dropdown()
|
||||
. = ..()
|
||||
. -= "Jump to"
|
||||
.["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[src]"
|
||||
.["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]"
|
||||
|
||||
/atom/movable/proc/ex_check(ex_id)
|
||||
if(!ex_id)
|
||||
|
||||
+306
-306
@@ -1,309 +1,309 @@
|
||||
/*
|
||||
HOW IT WORKS
|
||||
|
||||
The SSradio is a global object maintaining all radio transmissions, think about it as about "ether".
|
||||
Note that walkie-talkie, intercoms and headsets handle transmission using nonstandard way.
|
||||
procs:
|
||||
|
||||
add_object(obj/device as obj, var/new_frequency as num, var/filter as text|null = null)
|
||||
Adds listening object.
|
||||
parameters:
|
||||
device - device receiving signals, must have proc receive_signal (see description below).
|
||||
one device may listen several frequencies, but not same frequency twice.
|
||||
new_frequency - see possibly frequencies below;
|
||||
filter - thing for optimization. Optional, but recommended.
|
||||
All filters should be consolidated in this file, see defines later.
|
||||
Device without listening filter will receive all signals (on specified frequency).
|
||||
Device with filter will receive any signals sent without filter.
|
||||
Device with filter will not receive any signals sent with different filter.
|
||||
returns:
|
||||
Reference to frequency object.
|
||||
|
||||
remove_object (obj/device, old_frequency)
|
||||
Obliviously, after calling this proc, device will not receive any signals on old_frequency.
|
||||
Other frequencies will left unaffected.
|
||||
|
||||
return_frequency(var/frequency as num)
|
||||
returns:
|
||||
Reference to frequency object. Use it if you need to send and do not need to listen.
|
||||
|
||||
radio_frequency is a global object maintaining list of devices that listening specific frequency.
|
||||
procs:
|
||||
|
||||
post_signal(obj/source as obj|null, datum/signal/signal, var/filter as text|null = null, var/range as num|null = null)
|
||||
Sends signal to all devices that wants such signal.
|
||||
parameters:
|
||||
source - object, emitted signal. Usually, devices will not receive their own signals.
|
||||
signal - see description below.
|
||||
filter - described above.
|
||||
range - radius of regular byond's square circle on that z-level. null means everywhere, on all z-levels.
|
||||
|
||||
obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param)
|
||||
Handler from received signals. By default does nothing. Define your own for your object.
|
||||
Avoid of sending signals directly from this proc, use spawn(0). Do not use sleep() here please.
|
||||
parameters:
|
||||
signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return!
|
||||
receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO.
|
||||
TRANSMISSION_WIRE is currently unused.
|
||||
receive_param - for TRANSMISSION_RADIO here comes frequency.
|
||||
|
||||
datum/signal
|
||||
vars:
|
||||
source
|
||||
an object that emitted signal. Used for debug and bearing.
|
||||
data
|
||||
list with transmitting data. Usual use pattern:
|
||||
data["msg"] = "hello world"
|
||||
encryption
|
||||
Some number symbolizing "encryption key".
|
||||
Note that game actually do not use any cryptography here.
|
||||
If receiving object don't know right key, it must ignore encrypted signal in its receive_signal.
|
||||
|
||||
*/
|
||||
/* the radio controller is a confusing piece of shit and didnt work
|
||||
so i made radios not use the radio controller.
|
||||
*/
|
||||
GLOBAL_LIST_EMPTY(all_radios)
|
||||
/proc/add_radio(obj/item/radio, freq)
|
||||
if(!freq || !radio)
|
||||
return
|
||||
if(!GLOB.all_radios["[freq]"])
|
||||
GLOB.all_radios["[freq]"] = list(radio)
|
||||
return freq
|
||||
|
||||
GLOB.all_radios["[freq]"] |= radio
|
||||
return freq
|
||||
|
||||
/proc/remove_radio(obj/item/radio, freq)
|
||||
if(!freq || !radio)
|
||||
return
|
||||
if(!GLOB.all_radios["[freq]"])
|
||||
return
|
||||
|
||||
GLOB.all_radios["[freq]"] -= radio
|
||||
|
||||
/proc/remove_radio_all(obj/item/radio)
|
||||
for(var/freq in GLOB.all_radios)
|
||||
GLOB.all_radios["[freq]"] -= radio
|
||||
|
||||
/*
|
||||
Frequency range: 1200 to 1600
|
||||
Radiochat range: 1441 to 1489 (most devices refuse to be tune to other frequency, even during mapmaking)
|
||||
|
||||
Radio:
|
||||
1459 - standard radio chat
|
||||
1351 - Science
|
||||
1353 - Command
|
||||
1355 - Medical
|
||||
1357 - Engineering
|
||||
1359 - Security
|
||||
1337 - death squad
|
||||
1443 - Confession Intercom
|
||||
1349 - Miners
|
||||
1347 - Cargo techs
|
||||
1447 - AI Private
|
||||
|
||||
Devices:
|
||||
1451 - tracking implant
|
||||
1457 - RSD default
|
||||
|
||||
On the map:
|
||||
1311 for prison shuttle console (in fact, it is not used)
|
||||
1435 for status displays
|
||||
1437 for atmospherics/fire alerts
|
||||
1439 for engine components
|
||||
1439 for air pumps, air scrubbers, atmo control
|
||||
1441 for atmospherics - supply tanks
|
||||
1443 for atmospherics - distribution loop/mixed air tank
|
||||
1445 for bot nav beacons
|
||||
1447 for mulebot, secbot and ed209 control
|
||||
1449 for airlock controls, electropack, magnets
|
||||
1451 for toxin lab access
|
||||
1453 for engineering access
|
||||
1455 for AI access
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(radiochannels, list(
|
||||
"Common" = 1459,
|
||||
"Science" = 1351,
|
||||
"Command" = 1353,
|
||||
"Medical" = 1355,
|
||||
"Engineering" = 1357,
|
||||
"Security" = 1359,
|
||||
/*
|
||||
HOW IT WORKS
|
||||
|
||||
The SSradio is a global object maintaining all radio transmissions, think about it as about "ether".
|
||||
Note that walkie-talkie, intercoms and headsets handle transmission using nonstandard way.
|
||||
procs:
|
||||
|
||||
add_object(obj/device as obj, var/new_frequency as num, var/filter as text|null = null)
|
||||
Adds listening object.
|
||||
parameters:
|
||||
device - device receiving signals, must have proc receive_signal (see description below).
|
||||
one device may listen several frequencies, but not same frequency twice.
|
||||
new_frequency - see possibly frequencies below;
|
||||
filter - thing for optimization. Optional, but recommended.
|
||||
All filters should be consolidated in this file, see defines later.
|
||||
Device without listening filter will receive all signals (on specified frequency).
|
||||
Device with filter will receive any signals sent without filter.
|
||||
Device with filter will not receive any signals sent with different filter.
|
||||
returns:
|
||||
Reference to frequency object.
|
||||
|
||||
remove_object (obj/device, old_frequency)
|
||||
Obliviously, after calling this proc, device will not receive any signals on old_frequency.
|
||||
Other frequencies will left unaffected.
|
||||
|
||||
return_frequency(var/frequency as num)
|
||||
returns:
|
||||
Reference to frequency object. Use it if you need to send and do not need to listen.
|
||||
|
||||
radio_frequency is a global object maintaining list of devices that listening specific frequency.
|
||||
procs:
|
||||
|
||||
post_signal(obj/source as obj|null, datum/signal/signal, var/filter as text|null = null, var/range as num|null = null)
|
||||
Sends signal to all devices that wants such signal.
|
||||
parameters:
|
||||
source - object, emitted signal. Usually, devices will not receive their own signals.
|
||||
signal - see description below.
|
||||
filter - described above.
|
||||
range - radius of regular byond's square circle on that z-level. null means everywhere, on all z-levels.
|
||||
|
||||
obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param)
|
||||
Handler from received signals. By default does nothing. Define your own for your object.
|
||||
Avoid of sending signals directly from this proc, use spawn(0). Do not use sleep() here please.
|
||||
parameters:
|
||||
signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return!
|
||||
receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO.
|
||||
TRANSMISSION_WIRE is currently unused.
|
||||
receive_param - for TRANSMISSION_RADIO here comes frequency.
|
||||
|
||||
datum/signal
|
||||
vars:
|
||||
source
|
||||
an object that emitted signal. Used for debug and bearing.
|
||||
data
|
||||
list with transmitting data. Usual use pattern:
|
||||
data["msg"] = "hello world"
|
||||
encryption
|
||||
Some number symbolizing "encryption key".
|
||||
Note that game actually do not use any cryptography here.
|
||||
If receiving object don't know right key, it must ignore encrypted signal in its receive_signal.
|
||||
|
||||
*/
|
||||
/* the radio controller is a confusing piece of shit and didnt work
|
||||
so i made radios not use the radio controller.
|
||||
*/
|
||||
GLOBAL_LIST_EMPTY(all_radios)
|
||||
/proc/add_radio(obj/item/radio, freq)
|
||||
if(!freq || !radio)
|
||||
return
|
||||
if(!GLOB.all_radios["[freq]"])
|
||||
GLOB.all_radios["[freq]"] = list(radio)
|
||||
return freq
|
||||
|
||||
GLOB.all_radios["[freq]"] |= radio
|
||||
return freq
|
||||
|
||||
/proc/remove_radio(obj/item/radio, freq)
|
||||
if(!freq || !radio)
|
||||
return
|
||||
if(!GLOB.all_radios["[freq]"])
|
||||
return
|
||||
|
||||
GLOB.all_radios["[freq]"] -= radio
|
||||
|
||||
/proc/remove_radio_all(obj/item/radio)
|
||||
for(var/freq in GLOB.all_radios)
|
||||
GLOB.all_radios["[freq]"] -= radio
|
||||
|
||||
/*
|
||||
Frequency range: 1200 to 1600
|
||||
Radiochat range: 1441 to 1489 (most devices refuse to be tune to other frequency, even during mapmaking)
|
||||
|
||||
Radio:
|
||||
1459 - standard radio chat
|
||||
1351 - Science
|
||||
1353 - Command
|
||||
1355 - Medical
|
||||
1357 - Engineering
|
||||
1359 - Security
|
||||
1337 - death squad
|
||||
1443 - Confession Intercom
|
||||
1349 - Miners
|
||||
1347 - Cargo techs
|
||||
1447 - AI Private
|
||||
|
||||
Devices:
|
||||
1451 - tracking implant
|
||||
1457 - RSD default
|
||||
|
||||
On the map:
|
||||
1311 for prison shuttle console (in fact, it is not used)
|
||||
1435 for status displays
|
||||
1437 for atmospherics/fire alerts
|
||||
1439 for engine components
|
||||
1439 for air pumps, air scrubbers, atmo control
|
||||
1441 for atmospherics - supply tanks
|
||||
1443 for atmospherics - distribution loop/mixed air tank
|
||||
1445 for bot nav beacons
|
||||
1447 for mulebot, secbot and ed209 control
|
||||
1449 for airlock controls, electropack, magnets
|
||||
1451 for toxin lab access
|
||||
1453 for engineering access
|
||||
1455 for AI access
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(radiochannels, list(
|
||||
"Common" = 1459,
|
||||
"Science" = 1351,
|
||||
"Command" = 1353,
|
||||
"Medical" = 1355,
|
||||
"Engineering" = 1357,
|
||||
"Security" = 1359,
|
||||
"CentCom" = 1337,
|
||||
"Syndicate" = 1213,
|
||||
"Supply" = 1347,
|
||||
"Service" = 1349,
|
||||
"AI Private" = 1447,
|
||||
"Red Team" = 1215,
|
||||
"Blue Team" = 1217
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(reverseradiochannels, list(
|
||||
"1459" = "Common",
|
||||
"1351" = "Science",
|
||||
"1353" = "Command",
|
||||
"1355" = "Medical",
|
||||
"1357" = "Engineering",
|
||||
"1359" = "Security",
|
||||
"Syndicate" = 1213,
|
||||
"Supply" = 1347,
|
||||
"Service" = 1349,
|
||||
"AI Private" = 1447,
|
||||
"Red Team" = 1215,
|
||||
"Blue Team" = 1217
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(reverseradiochannels, list(
|
||||
"1459" = "Common",
|
||||
"1351" = "Science",
|
||||
"1353" = "Command",
|
||||
"1355" = "Medical",
|
||||
"1357" = "Engineering",
|
||||
"1359" = "Security",
|
||||
"1337" = "CentCom",
|
||||
"1213" = "Syndicate",
|
||||
"1347" = "Supply",
|
||||
"1349" = "Service",
|
||||
"1447" = "AI Private",
|
||||
"1215" = "Red Team",
|
||||
"1217" = "Blue Team"
|
||||
))
|
||||
|
||||
//depenging helpers
|
||||
GLOBAL_VAR_CONST(SYND_FREQ, 1213) //nuke op frequency, coloured dark brown in chat window
|
||||
GLOBAL_VAR_CONST(SUPP_FREQ, 1347) //supply, coloured light brown in chat window
|
||||
GLOBAL_VAR_CONST(SERV_FREQ, 1349) //service, coloured green in chat window
|
||||
GLOBAL_VAR_CONST(SCI_FREQ, 1351) //science, coloured plum in chat window
|
||||
GLOBAL_VAR_CONST(COMM_FREQ, 1353) //command, colored gold in chat window
|
||||
GLOBAL_VAR_CONST(MED_FREQ, 1355) //medical, coloured blue in chat window
|
||||
GLOBAL_VAR_CONST(ENG_FREQ, 1357) //engineering, coloured orange in chat window
|
||||
GLOBAL_VAR_CONST(SEC_FREQ, 1359) //security, coloured red in chat window
|
||||
GLOBAL_VAR_CONST(CENTCOM_FREQ, 1337) //centcom frequency, coloured grey in chat window
|
||||
GLOBAL_VAR_CONST(AIPRIV_FREQ, 1447) //AI private, colored magenta in chat window
|
||||
GLOBAL_VAR_CONST(REDTEAM_FREQ, 1215) // red team (CTF) frequency, coloured red
|
||||
GLOBAL_VAR_CONST(BLUETEAM_FREQ, 1217) // blue team (CTF) frequency, coloured blue
|
||||
|
||||
#define TRANSMISSION_WIRE 0
|
||||
#define TRANSMISSION_RADIO 1
|
||||
|
||||
/* filters */
|
||||
GLOBAL_VAR_INIT(RADIO_TO_AIRALARM, "1")
|
||||
GLOBAL_VAR_INIT(RADIO_FROM_AIRALARM, "2")
|
||||
GLOBAL_VAR_INIT(RADIO_CHAT, "3") //deprecated
|
||||
GLOBAL_VAR_INIT(RADIO_ATMOSIA, "4")
|
||||
GLOBAL_VAR_INIT(RADIO_NAVBEACONS, "5")
|
||||
GLOBAL_VAR_INIT(RADIO_AIRLOCK, "6")
|
||||
GLOBAL_VAR_INIT(RADIO_MAGNETS, "9")
|
||||
|
||||
/datum/radio_frequency
|
||||
|
||||
var/frequency as num
|
||||
var/list/list/obj/devices = list()
|
||||
|
||||
//If range > 0, only post to devices on the same z_level and within range
|
||||
//Use range = -1, to restrain to the same z_level without limiting range
|
||||
/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, filter = null as text|null, range = null as num|null)
|
||||
|
||||
//Apply filter to the signal. If none supply, broadcast to every devices
|
||||
//_default channel is always checked
|
||||
var/list/filter_list
|
||||
|
||||
if(filter)
|
||||
filter_list = list(filter,"_default")
|
||||
else
|
||||
filter_list = devices
|
||||
|
||||
//If checking range, find the source turf
|
||||
var/turf/start_point
|
||||
if(range)
|
||||
start_point = get_turf(source)
|
||||
if(!start_point)
|
||||
return 0
|
||||
|
||||
//Send the data
|
||||
for(var/current_filter in filter_list)
|
||||
for(var/obj/device in devices[current_filter])
|
||||
if(device == source)
|
||||
continue
|
||||
if(range)
|
||||
var/turf/end_point = get_turf(device)
|
||||
if(!end_point)
|
||||
continue
|
||||
if(start_point.z != end_point.z || (range > 0 && get_dist(start_point, end_point) > range))
|
||||
continue
|
||||
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
|
||||
|
||||
/datum/radio_frequency/proc/add_listener(obj/device, filter as text|null)
|
||||
if (!filter)
|
||||
filter = "_default"
|
||||
|
||||
var/list/devices_line = devices[filter]
|
||||
if(!devices_line)
|
||||
devices_line = list()
|
||||
devices[filter] = devices_line
|
||||
devices_line += device
|
||||
|
||||
|
||||
/datum/radio_frequency/proc/remove_listener(obj/device)
|
||||
for(var/devices_filter in devices)
|
||||
var/list/devices_line = devices[devices_filter]
|
||||
if(!devices_line)
|
||||
devices -= devices_filter
|
||||
devices_line -= device
|
||||
if(!devices_line.len)
|
||||
devices -= devices_filter
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/client/proc/print_pointers()
|
||||
set name = "Debug Signals"
|
||||
set category = "Debug"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
var/datum/signal/S
|
||||
to_chat(src, "There are [S.pointers.len] pointers:")
|
||||
for(var/p in S.pointers)
|
||||
to_chat(src, p)
|
||||
S = locate(p)
|
||||
if(istype(S))
|
||||
to_chat(src, S.debug_print())
|
||||
|
||||
/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
|
||||
return
|
||||
|
||||
/datum/signal
|
||||
var/obj/source
|
||||
|
||||
var/transmission_method = 0
|
||||
//0 = wire
|
||||
//1 = radio transmission
|
||||
//2 = subspace transmission
|
||||
|
||||
var/data = list()
|
||||
var/encryption
|
||||
|
||||
var/frequency = 0
|
||||
var/static/list/pointers = list()
|
||||
|
||||
/datum/signal/New()
|
||||
..()
|
||||
pointers += "\ref[src]"
|
||||
|
||||
/datum/signal/Destroy()
|
||||
pointers -= "\ref[src]"
|
||||
return ..()
|
||||
|
||||
/datum/signal/proc/copy_from(datum/signal/model)
|
||||
source = model.source
|
||||
transmission_method = model.transmission_method
|
||||
data = model.data
|
||||
encryption = model.encryption
|
||||
frequency = model.frequency
|
||||
|
||||
/datum/signal/proc/debug_print()
|
||||
if (source)
|
||||
"1213" = "Syndicate",
|
||||
"1347" = "Supply",
|
||||
"1349" = "Service",
|
||||
"1447" = "AI Private",
|
||||
"1215" = "Red Team",
|
||||
"1217" = "Blue Team"
|
||||
))
|
||||
|
||||
//depenging helpers
|
||||
GLOBAL_VAR_CONST(SYND_FREQ, 1213) //nuke op frequency, coloured dark brown in chat window
|
||||
GLOBAL_VAR_CONST(SUPP_FREQ, 1347) //supply, coloured light brown in chat window
|
||||
GLOBAL_VAR_CONST(SERV_FREQ, 1349) //service, coloured green in chat window
|
||||
GLOBAL_VAR_CONST(SCI_FREQ, 1351) //science, coloured plum in chat window
|
||||
GLOBAL_VAR_CONST(COMM_FREQ, 1353) //command, colored gold in chat window
|
||||
GLOBAL_VAR_CONST(MED_FREQ, 1355) //medical, coloured blue in chat window
|
||||
GLOBAL_VAR_CONST(ENG_FREQ, 1357) //engineering, coloured orange in chat window
|
||||
GLOBAL_VAR_CONST(SEC_FREQ, 1359) //security, coloured red in chat window
|
||||
GLOBAL_VAR_CONST(CENTCOM_FREQ, 1337) //centcom frequency, coloured grey in chat window
|
||||
GLOBAL_VAR_CONST(AIPRIV_FREQ, 1447) //AI private, colored magenta in chat window
|
||||
GLOBAL_VAR_CONST(REDTEAM_FREQ, 1215) // red team (CTF) frequency, coloured red
|
||||
GLOBAL_VAR_CONST(BLUETEAM_FREQ, 1217) // blue team (CTF) frequency, coloured blue
|
||||
|
||||
#define TRANSMISSION_WIRE 0
|
||||
#define TRANSMISSION_RADIO 1
|
||||
|
||||
/* filters */
|
||||
GLOBAL_VAR_INIT(RADIO_TO_AIRALARM, "1")
|
||||
GLOBAL_VAR_INIT(RADIO_FROM_AIRALARM, "2")
|
||||
GLOBAL_VAR_INIT(RADIO_CHAT, "3") //deprecated
|
||||
GLOBAL_VAR_INIT(RADIO_ATMOSIA, "4")
|
||||
GLOBAL_VAR_INIT(RADIO_NAVBEACONS, "5")
|
||||
GLOBAL_VAR_INIT(RADIO_AIRLOCK, "6")
|
||||
GLOBAL_VAR_INIT(RADIO_MAGNETS, "9")
|
||||
|
||||
/datum/radio_frequency
|
||||
|
||||
var/frequency as num
|
||||
var/list/list/obj/devices = list()
|
||||
|
||||
//If range > 0, only post to devices on the same z_level and within range
|
||||
//Use range = -1, to restrain to the same z_level without limiting range
|
||||
/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, filter = null as text|null, range = null as num|null)
|
||||
|
||||
//Apply filter to the signal. If none supply, broadcast to every devices
|
||||
//_default channel is always checked
|
||||
var/list/filter_list
|
||||
|
||||
if(filter)
|
||||
filter_list = list(filter,"_default")
|
||||
else
|
||||
filter_list = devices
|
||||
|
||||
//If checking range, find the source turf
|
||||
var/turf/start_point
|
||||
if(range)
|
||||
start_point = get_turf(source)
|
||||
if(!start_point)
|
||||
return 0
|
||||
|
||||
//Send the data
|
||||
for(var/current_filter in filter_list)
|
||||
for(var/obj/device in devices[current_filter])
|
||||
if(device == source)
|
||||
continue
|
||||
if(range)
|
||||
var/turf/end_point = get_turf(device)
|
||||
if(!end_point)
|
||||
continue
|
||||
if(start_point.z != end_point.z || (range > 0 && get_dist(start_point, end_point) > range))
|
||||
continue
|
||||
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
|
||||
|
||||
/datum/radio_frequency/proc/add_listener(obj/device, filter as text|null)
|
||||
if (!filter)
|
||||
filter = "_default"
|
||||
|
||||
var/list/devices_line = devices[filter]
|
||||
if(!devices_line)
|
||||
devices_line = list()
|
||||
devices[filter] = devices_line
|
||||
devices_line += device
|
||||
|
||||
|
||||
/datum/radio_frequency/proc/remove_listener(obj/device)
|
||||
for(var/devices_filter in devices)
|
||||
var/list/devices_line = devices[devices_filter]
|
||||
if(!devices_line)
|
||||
devices -= devices_filter
|
||||
devices_line -= device
|
||||
if(!devices_line.len)
|
||||
devices -= devices_filter
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/client/proc/print_pointers()
|
||||
set name = "Debug Signals"
|
||||
set category = "Debug"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
var/datum/signal/S
|
||||
to_chat(src, "There are [S.pointers.len] pointers:")
|
||||
for(var/p in S.pointers)
|
||||
to_chat(src, p)
|
||||
S = locate(p)
|
||||
if(istype(S))
|
||||
to_chat(src, S.debug_print())
|
||||
|
||||
/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
|
||||
return
|
||||
|
||||
/datum/signal
|
||||
var/obj/source
|
||||
|
||||
var/transmission_method = 0
|
||||
//0 = wire
|
||||
//1 = radio transmission
|
||||
//2 = subspace transmission
|
||||
|
||||
var/data = list()
|
||||
var/encryption
|
||||
|
||||
var/frequency = 0
|
||||
var/static/list/pointers = list()
|
||||
|
||||
/datum/signal/New()
|
||||
..()
|
||||
pointers += "[REF(src)]"
|
||||
|
||||
/datum/signal/Destroy()
|
||||
pointers -= "[REF(src)]"
|
||||
return ..()
|
||||
|
||||
/datum/signal/proc/copy_from(datum/signal/model)
|
||||
source = model.source
|
||||
transmission_method = model.transmission_method
|
||||
data = model.data
|
||||
encryption = model.encryption
|
||||
frequency = model.frequency
|
||||
|
||||
/datum/signal/proc/debug_print()
|
||||
if (source)
|
||||
. = "signal = {source = '[source]' [COORD(source)]\n"
|
||||
else
|
||||
. = "signal = {source = '[source]' ()\n"
|
||||
for (var/i in data)
|
||||
. += "data\[\"[i]\"\] = \"[data[i]]\"\n"
|
||||
if(islist(data[i]))
|
||||
var/list/L = data[i]
|
||||
for(var/t in L)
|
||||
. += "data\[\"[i]\"\] list has: [t]"
|
||||
|
||||
/datum/signal/proc/sanitize_data()
|
||||
for(var/d in data)
|
||||
var/val = data[d]
|
||||
if(istext(val))
|
||||
data[d] = html_encode(val)
|
||||
else
|
||||
. = "signal = {source = '[source]' ()\n"
|
||||
for (var/i in data)
|
||||
. += "data\[\"[i]\"\] = \"[data[i]]\"\n"
|
||||
if(islist(data[i]))
|
||||
var/list/L = data[i]
|
||||
for(var/t in L)
|
||||
. += "data\[\"[i]\"\] list has: [t]"
|
||||
|
||||
/datum/signal/proc/sanitize_data()
|
||||
for(var/d in data)
|
||||
var/val = data[d]
|
||||
if(istext(val))
|
||||
data[d] = html_encode(val)
|
||||
|
||||
@@ -29,13 +29,13 @@
|
||||
dat += "<I>Using this contract, you may summon an apprentice to aid you on your mission.</I><BR>"
|
||||
dat += "<I>If you are unable to establish contact with your apprentice, you can feed the contract back to the spellbook to refund your points.</I><BR>"
|
||||
dat += "<B>Which school of magic is your apprentice studying?:</B><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=[APPRENTICE_DESTRUCTION]'>Destruction</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_DESTRUCTION]'>Destruction</A><BR>"
|
||||
dat += "<I>Your apprentice is skilled in offensive magic. They know Magic Missile and Fireball.</I><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=[APPRENTICE_BLUESPACE]'>Bluespace Manipulation</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_BLUESPACE]'>Bluespace Manipulation</A><BR>"
|
||||
dat += "<I>Your apprentice is able to defy physics, melting through solid objects and travelling great distances in the blink of an eye. They know Teleport and Ethereal Jaunt.</I><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=[APPRENTICE_HEALING]'>Healing</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_HEALING]'>Healing</A><BR>"
|
||||
dat += "<I>Your apprentice is training to cast spells that will aid your survival. They know Forcewall and Charge and come with a Staff of Healing.</I><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=[APPRENTICE_ROBELESS]'>Robeless</A><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_ROBELESS]'>Robeless</A><BR>"
|
||||
dat += "<I>Your apprentice is training to cast spells without their robes. They know Knock and Mindswap.</I><BR>"
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
|
||||
@@ -6,56 +6,47 @@
|
||||
var/door = 0
|
||||
var/grille = 0
|
||||
var/mach = 0
|
||||
var/num_territories = 1//Number of total valid territories for gang mode
|
||||
|
||||
/datum/station_state/proc/count()
|
||||
for(var/Z in GLOB.station_z_levels)
|
||||
for(var/turf/T in block(locate(1,1,Z), locate(world.maxx,world.maxy,Z)))
|
||||
// don't count shuttles since they may have just left
|
||||
if(istype(T.loc, /area/shuttle))
|
||||
continue
|
||||
|
||||
if(isfloorturf(T))
|
||||
var/turf/open/floor/TF = T
|
||||
if(!(TF.burnt))
|
||||
floor += 12
|
||||
else
|
||||
floor += 1
|
||||
|
||||
if(iswallturf(T))
|
||||
var/turf/closed/wall/TW = T
|
||||
if(TW.intact)
|
||||
wall += 2
|
||||
else
|
||||
wall += 1
|
||||
|
||||
if(istype(T, /turf/closed/wall/r_wall))
|
||||
var/turf/closed/wall/r_wall/TRW = T
|
||||
if(TRW.intact)
|
||||
r_wall += 2
|
||||
else
|
||||
r_wall += 1
|
||||
|
||||
|
||||
/datum/station_state/proc/count(count_territories)
|
||||
for(var/turf/T in block(locate(1,1,1), locate(world.maxx,world.maxy,1)))
|
||||
|
||||
if(isfloorturf(T))
|
||||
var/turf/open/floor/TF = T
|
||||
if(!(TF.burnt))
|
||||
src.floor += 12
|
||||
else
|
||||
src.floor += 1
|
||||
|
||||
if(iswallturf(T))
|
||||
var/turf/closed/wall/TW = T
|
||||
if(TW.intact)
|
||||
src.wall += 2
|
||||
else
|
||||
src.wall += 1
|
||||
|
||||
if(istype(T, /turf/closed/wall/r_wall))
|
||||
var/turf/closed/wall/r_wall/TRW = T
|
||||
if(TRW.intact)
|
||||
src.r_wall += 2
|
||||
else
|
||||
src.r_wall += 1
|
||||
|
||||
|
||||
for(var/obj/O in T.contents)
|
||||
if(istype(O, /obj/structure/window))
|
||||
src.window += 1
|
||||
else if(istype(O, /obj/structure/grille))
|
||||
var/obj/structure/grille/GR = O
|
||||
if(!GR.broken)
|
||||
src.grille += 1
|
||||
else if(istype(O, /obj/machinery/door))
|
||||
src.door += 1
|
||||
else if(ismachinery(O))
|
||||
src.mach += 1
|
||||
|
||||
if(count_territories)
|
||||
var/list/valid_territories = list()
|
||||
for(var/area/A in world) //First, collect all area types on the station zlevel
|
||||
if(A.z in GLOB.station_z_levels)
|
||||
if(!(A.type in valid_territories) && A.valid_territory)
|
||||
valid_territories |= A.type
|
||||
if(valid_territories.len)
|
||||
num_territories = valid_territories.len //Add them all up to make the total number of area types
|
||||
else
|
||||
to_chat(world, "ERROR: NO VALID TERRITORIES")
|
||||
for(var/obj/O in T.contents)
|
||||
if(istype(O, /obj/structure/window))
|
||||
window += 1
|
||||
else if(istype(O, /obj/structure/grille))
|
||||
var/obj/structure/grille/GR = O
|
||||
if(!GR.broken)
|
||||
grille += 1
|
||||
else if(istype(O, /obj/machinery/door))
|
||||
door += 1
|
||||
else if(ismachinery(O))
|
||||
mach += 1
|
||||
|
||||
/datum/station_state/proc/score(datum/station_state/result)
|
||||
if(!result)
|
||||
|
||||
@@ -226,6 +226,8 @@
|
||||
. = ..()
|
||||
if(!independent) //no pulling people deep into the blob
|
||||
verbs -= /mob/living/verb/pulled
|
||||
else
|
||||
pass_flags &= ~PASSBLOB
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/Life()
|
||||
if(..())
|
||||
|
||||
@@ -79,12 +79,13 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
/mob/camera/blob/proc/victory()
|
||||
sound_to_playing_players('sound/machines/alarm.ogg')
|
||||
sleep(100)
|
||||
for(var/mob/living/L in GLOB.mob_list)
|
||||
for(var/i in GLOB.mob_living_list)
|
||||
var/mob/living/L = i
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T || !(T.z in GLOB.station_z_levels))
|
||||
continue
|
||||
|
||||
if(L in GLOB.overminds || L.checkpass(PASSBLOB))
|
||||
if(L in GLOB.overminds || (L.pass_flags & PASSBLOB))
|
||||
continue
|
||||
|
||||
var/area/Ablob = get_area(T)
|
||||
@@ -92,9 +93,12 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
if(!Ablob.blob_allowed)
|
||||
continue
|
||||
|
||||
playsound(L, 'sound/effects/splat.ogg', 50, 1)
|
||||
L.death()
|
||||
new/mob/living/simple_animal/hostile/blob/blobspore(T)
|
||||
if(!("blob" in L.faction))
|
||||
playsound(L, 'sound/effects/splat.ogg', 50, 1)
|
||||
L.death()
|
||||
new/mob/living/simple_animal/hostile/blob/blobspore(T)
|
||||
else
|
||||
L.fully_heal()
|
||||
|
||||
for(var/V in GLOB.sortedAreas)
|
||||
var/area/A = V
|
||||
|
||||
@@ -154,33 +154,34 @@
|
||||
return
|
||||
if(!can_buy(40))
|
||||
return
|
||||
B.max_integrity = initial(B.max_integrity) * 0.25 //factories that produced a blobbernaut have much lower health
|
||||
B.obj_integrity = min(B.obj_integrity, B.max_integrity)
|
||||
B.update_icon()
|
||||
B.visible_message("<span class='warning'><b>The blobbernaut [pick("rips", "tears", "shreds")] its way out of the factory blob!</b></span>")
|
||||
playsound(B.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
var/mob/living/simple_animal/hostile/blob/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blob/blobbernaut(get_turf(B))
|
||||
flick("blobbernaut_produce", blobber)
|
||||
B.naut = blobber
|
||||
blobber.factory = B
|
||||
blobber.overmind = src
|
||||
blobber.update_icons()
|
||||
blobber.notransform = 1 //stop the naut from moving around
|
||||
blobber.adjustHealth(blobber.maxHealth * 0.5)
|
||||
blob_mobs += blobber
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50, blobber) //players must answer rapidly
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
|
||||
if(candidates.len) //if we got at least one candidate, they're a blobbernaut now.
|
||||
B.max_integrity = initial(B.max_integrity) * 0.25 //factories that produced a blobbernaut have much lower health
|
||||
B.obj_integrity = min(B.obj_integrity, B.max_integrity)
|
||||
B.update_icon()
|
||||
B.visible_message("<span class='warning'><b>The blobbernaut [pick("rips", "tears", "shreds")] its way out of the factory blob!</b></span>")
|
||||
playsound(B.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
var/mob/living/simple_animal/hostile/blob/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blob/blobbernaut(get_turf(B))
|
||||
flick("blobbernaut_produce", blobber)
|
||||
B.naut = blobber
|
||||
blobber.factory = B
|
||||
blobber.overmind = src
|
||||
blobber.update_icons()
|
||||
blobber.adjustHealth(blobber.maxHealth * 0.5)
|
||||
blob_mobs += blobber
|
||||
var/client/C = pick(candidates)
|
||||
blobber.key = C.key
|
||||
SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg'))
|
||||
SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg'))
|
||||
to_chat(blobber, "<b>You are a blobbernaut!</b>")
|
||||
to_chat(blobber, "You are powerful, hard to kill, and slowly regenerate near nodes and cores, but will slowly die if not near the blob or if the factory that made you is killed.")
|
||||
to_chat(blobber, "You are powerful, hard to kill, and slowly regenerate near nodes and cores, <span class='cultlarge'>but will slowly die if not near the blob</span> or if the factory that made you is killed.")
|
||||
to_chat(blobber, "You can communicate with other blobbernauts and overminds via <b>:b</b>")
|
||||
to_chat(blobber, "Your overmind's blob reagent is: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!")
|
||||
to_chat(blobber, "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.shortdesc ? "[blob_reagent_datum.shortdesc]" : "[blob_reagent_datum.description]"]")
|
||||
if(blobber)
|
||||
blobber.notransform = 0
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You could not conjure a sentience for your blobbernaut. Your points have been refunded. Try again later.</span>")
|
||||
add_points(40)
|
||||
|
||||
/mob/camera/blob/verb/relocate_core()
|
||||
set category = "Blob"
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
return atmosblock
|
||||
|
||||
/obj/structure/blob/CanPass(atom/movable/mover, turf/target)
|
||||
if(istype(mover) && mover.checkpass(PASSBLOB))
|
||||
if(istype(mover) && (mover.pass_flags & PASSBLOB))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
. = 0
|
||||
if(ismovableatom(caller))
|
||||
var/atom/movable/mover = caller
|
||||
. = . || mover.checkpass(PASSBLOB)
|
||||
. = . || (mover.pass_flags & PASSBLOB)
|
||||
|
||||
/obj/structure/blob/update_icon() //Updates color based on overmind color if we have an overmind.
|
||||
if(overmind)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
/datum/cellular_emporium
|
||||
var/name = "cellular emporium"
|
||||
var/datum/changeling/changeling
|
||||
var/datum/antagonist/changeling/changeling
|
||||
|
||||
/datum/cellular_emporium/New(my_changeling)
|
||||
. = ..()
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
var/list/abilities = list()
|
||||
|
||||
for(var/path in subtypesof(/obj/effect/proc_holder/changeling))
|
||||
for(var/path in changeling.all_powers)
|
||||
var/obj/effect/proc_holder/changeling/ability = path
|
||||
|
||||
var/dna_cost = initial(ability.dna_cost)
|
||||
@@ -61,10 +61,10 @@
|
||||
switch(action)
|
||||
if("readapt")
|
||||
if(changeling.canrespec)
|
||||
changeling.lingRespec(usr)
|
||||
changeling.readapt()
|
||||
if("evolve")
|
||||
var/sting_name = params["name"]
|
||||
changeling.purchasePower(usr, sting_name)
|
||||
changeling.purchase_power(sting_name)
|
||||
|
||||
/datum/action/innate/cellular_emporium
|
||||
name = "Cellular Emporium"
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
#define LING_FAKEDEATH_TIME 400 //40 seconds
|
||||
#define LING_DEAD_GENETICDAMAGE_HEAL_CAP 50 //The lowest value of geneticdamage handle_changeling() can take it to while dead.
|
||||
#define LING_ABSORB_RECENT_SPEECH 8 //The amount of recent spoken lines to gain on absorbing a mob
|
||||
|
||||
GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega"))
|
||||
GLOBAL_LIST_INIT(slots, list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store"))
|
||||
GLOBAL_LIST_INIT(slot2slot, list("head" = slot_head, "wear_mask" = slot_wear_mask, "neck" = slot_neck, "back" = slot_back, "wear_suit" = slot_wear_suit, "w_uniform" = slot_w_uniform, "shoes" = slot_shoes, "belt" = slot_belt, "gloves" = slot_gloves, "glasses" = slot_glasses, "ears" = slot_ears, "wear_id" = slot_wear_id, "s_store" = slot_s_store))
|
||||
GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "wear_mask" = /obj/item/clothing/mask/changeling, "back" = /obj/item/changeling, "wear_suit" = /obj/item/clothing/suit/changeling, "w_uniform" = /obj/item/clothing/under/changeling, "shoes" = /obj/item/clothing/shoes/changeling, "belt" = /obj/item/changeling, "gloves" = /obj/item/clothing/gloves/changeling, "glasses" = /obj/item/clothing/glasses/changeling, "ears" = /obj/item/changeling, "wear_id" = /obj/item/changeling, "s_store" = /obj/item/changeling))
|
||||
|
||||
|
||||
/datum/game_mode
|
||||
var/list/datum/mind/changelings = list()
|
||||
GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our this objective to all lings
|
||||
|
||||
|
||||
/datum/game_mode/changeling
|
||||
@@ -29,26 +22,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
||||
<span class='green'>Changelings</span>: Accomplish the objectives assigned to you.\n\
|
||||
<span class='notice'>Crew</span>: Root out and eliminate the changeling menace."
|
||||
|
||||
var/const/prob_int_murder_target = 50 // intercept names the assassination target half the time
|
||||
var/const/prob_right_murder_target_l = 25 // lower bound on probability of naming right assassination target
|
||||
var/const/prob_right_murder_target_h = 50 // upper bound on probability of naimg the right assassination target
|
||||
|
||||
var/const/prob_int_item = 50 // intercept names the theft target half the time
|
||||
var/const/prob_right_item_l = 25 // lower bound on probability of naming right theft target
|
||||
var/const/prob_right_item_h = 50 // upper bound on probability of naming the right theft target
|
||||
|
||||
var/const/prob_int_sab_target = 50 // intercept names the sabotage target half the time
|
||||
var/const/prob_right_sab_target_l = 25 // lower bound on probability of naming right sabotage target
|
||||
var/const/prob_right_sab_target_h = 50 // upper bound on probability of naming right sabotage target
|
||||
|
||||
var/const/prob_right_killer_l = 25 //lower bound on probability of naming the right operative
|
||||
var/const/prob_right_killer_h = 50 //upper bound on probability of naming the right operative
|
||||
var/const/prob_right_objective_l = 25 //lower bound on probability of determining the objective correctly
|
||||
var/const/prob_right_objective_h = 50 //upper bound on probability of determining the objective correctly
|
||||
|
||||
var/const/changeling_amount = 4 //hard limit on changelings if scaling is turned off
|
||||
|
||||
var/changeling_team_objective_type = null //If this is not null, we hand our this objective to all lings
|
||||
var/list/changelings = list()
|
||||
|
||||
/datum/game_mode/changeling/pre_setup()
|
||||
|
||||
@@ -80,7 +55,6 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
||||
return 0
|
||||
|
||||
/datum/game_mode/changeling/post_setup()
|
||||
|
||||
//Decide if it's ok for the lings to have a team objective
|
||||
//And then set it up to be handed out in forge_changeling_objectives
|
||||
var/list/team_objectives = subtypesof(/datum/objective/changeling_team_objective)
|
||||
@@ -92,116 +66,27 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
||||
possible_team_objectives += T
|
||||
|
||||
if(possible_team_objectives.len && prob(20*changelings.len))
|
||||
changeling_team_objective_type = pick(possible_team_objectives)
|
||||
GLOB.changeling_team_objective_type = pick(possible_team_objectives)
|
||||
|
||||
for(var/datum/mind/changeling in changelings)
|
||||
log_game("[changeling.key] (ckey) has been selected as a changeling")
|
||||
changeling.current.make_changeling()
|
||||
forge_changeling_objectives(changeling)
|
||||
greet_changeling(changeling)
|
||||
SSticker.mode.update_changeling_icons_added(changeling)
|
||||
var/datum/antagonist/changeling/new_antag = new(changeling)
|
||||
new_antag.team_mode = TRUE
|
||||
changeling.add_antag_datum(new_antag)
|
||||
..()
|
||||
|
||||
/datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
|
||||
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
|
||||
var/changelingcap = min(round(GLOB.joined_player_list.len / (csc * 2)) + 2, round(GLOB.joined_player_list.len / csc))
|
||||
if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
|
||||
if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
|
||||
return
|
||||
if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2)))
|
||||
if(changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2)))
|
||||
if(ROLE_CHANGELING in character.client.prefs.be_special)
|
||||
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
|
||||
if(age_check(character.client))
|
||||
if(!(character.job in restricted_jobs))
|
||||
character.mind.make_Changling()
|
||||
|
||||
/datum/game_mode/proc/forge_changeling_objectives(datum/mind/changeling, var/team_mode = 0)
|
||||
//OBJECTIVES - random traitor objectives. Unique objectives "steal brain" and "identity theft".
|
||||
//No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
|
||||
//If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
|
||||
|
||||
var/escape_objective_possible = TRUE
|
||||
|
||||
//if there's a team objective, check if it's compatible with escape objectives
|
||||
for(var/datum/objective/changeling_team_objective/CTO in changeling.objectives)
|
||||
if(!CTO.escape_objective_compatible)
|
||||
escape_objective_possible = FALSE
|
||||
break
|
||||
|
||||
var/datum/objective/absorb/absorb_objective = new
|
||||
absorb_objective.owner = changeling
|
||||
absorb_objective.gen_amount_goal(6, 8)
|
||||
changeling.objectives += absorb_objective
|
||||
|
||||
if(prob(60))
|
||||
if(prob(85))
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = changeling
|
||||
steal_objective.find_target()
|
||||
changeling.objectives += steal_objective
|
||||
else
|
||||
var/datum/objective/download/download_objective = new
|
||||
download_objective.owner = changeling
|
||||
download_objective.gen_amount_goal()
|
||||
changeling.objectives += download_objective
|
||||
|
||||
var/list/active_ais = active_ais()
|
||||
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
|
||||
var/datum/objective/destroy/destroy_objective = new
|
||||
destroy_objective.owner = changeling
|
||||
destroy_objective.find_target()
|
||||
changeling.objectives += destroy_objective
|
||||
else
|
||||
if(prob(70))
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = changeling
|
||||
if(team_mode) //No backstabbing while in a team
|
||||
kill_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
||||
else
|
||||
kill_objective.find_target()
|
||||
changeling.objectives += kill_objective
|
||||
else
|
||||
var/datum/objective/maroon/maroon_objective = new
|
||||
maroon_objective.owner = changeling
|
||||
if(team_mode)
|
||||
maroon_objective.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
||||
else
|
||||
maroon_objective.find_target()
|
||||
changeling.objectives += maroon_objective
|
||||
|
||||
if (!(locate(/datum/objective/escape) in changeling.objectives) && escape_objective_possible)
|
||||
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
||||
identity_theft.owner = changeling
|
||||
identity_theft.target = maroon_objective.target
|
||||
identity_theft.update_explanation_text()
|
||||
changeling.objectives += identity_theft
|
||||
escape_objective_possible = FALSE
|
||||
|
||||
if (!(locate(/datum/objective/escape) in changeling.objectives) && escape_objective_possible)
|
||||
if(prob(50))
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = changeling
|
||||
changeling.objectives += escape_objective
|
||||
else
|
||||
var/datum/objective/escape/escape_with_identity/identity_theft = new
|
||||
identity_theft.owner = changeling
|
||||
if(team_mode)
|
||||
identity_theft.find_target_by_role(role = "Changeling", role_type = 1, invert = 1)
|
||||
else
|
||||
identity_theft.find_target()
|
||||
changeling.objectives += identity_theft
|
||||
escape_objective_possible = FALSE
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/changeling/forge_changeling_objectives(datum/mind/changeling)
|
||||
if(changeling_team_objective_type)
|
||||
var/datum/objective/changeling_team_objective/team_objective = new changeling_team_objective_type
|
||||
team_objective.owner = changeling
|
||||
changeling.objectives += team_objective
|
||||
|
||||
..(changeling,1)
|
||||
else
|
||||
..(changeling,0)
|
||||
changelings += character.mind
|
||||
|
||||
/datum/game_mode/changeling/generate_report()
|
||||
return "The Gorlex Marauders have announced the successful raid and destruction of Central Command containment ship #S-[rand(1111, 9999)]. This ship housed only a single prisoner - \
|
||||
@@ -209,29 +94,12 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
||||
of the Thing being sent to a station in this sector is highly likely. It may be in the guise of any crew member. Trust nobody - suspect everybody. Do not announce this to the crew, \
|
||||
as paranoia may spread and inhibit workplace efficiency."
|
||||
|
||||
/datum/game_mode/proc/greet_changeling(datum/mind/changeling, you_are=1)
|
||||
if (you_are)
|
||||
to_chat(changeling.current, "<span class='boldannounce'>You are [changeling.changeling.changelingID], a changeling! You have absorbed and taken the form of a human.</span>")
|
||||
to_chat(changeling.current, "<span class='boldannounce'>Use say \":g message\" to communicate with your fellow changelings.</span>")
|
||||
to_chat(changeling.current, "<b>You must complete the following tasks:</b>")
|
||||
changeling.current.playsound_local(get_turf(changeling.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||
|
||||
if (changeling.current.mind)
|
||||
var/mob/living/carbon/human/H = changeling.current
|
||||
if(H.mind.assigned_role == "Clown")
|
||||
to_chat(H, "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
H.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
var/obj_count = 1
|
||||
for(var/datum/objective/objective in changeling.objectives)
|
||||
to_chat(changeling.current, "<b>Objective #[obj_count]</b>: [objective.explanation_text]")
|
||||
obj_count++
|
||||
return
|
||||
|
||||
/datum/game_mode/proc/auto_declare_completion_changeling()
|
||||
var/list/changelings = get_antagonists(/datum/antagonist/changeling,TRUE) //Only real lings get a mention
|
||||
if(changelings.len)
|
||||
var/text = "<br><font size=3><b>The changelings were:</b></font>"
|
||||
for(var/datum/mind/changeling in changelings)
|
||||
var/datum/antagonist/changeling/ling = changeling.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/changelingwin = 1
|
||||
if(!changeling.current)
|
||||
changelingwin = 0
|
||||
@@ -239,8 +107,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
||||
text += printplayer(changeling)
|
||||
|
||||
//Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed.
|
||||
text += "<br><b>Changeling ID:</b> [changeling.changeling.changelingID]."
|
||||
text += "<br><b>Genomes Extracted:</b> [changeling.changeling.absorbedcount]"
|
||||
text += "<br><b>Changeling ID:</b> [ling.changelingID]."
|
||||
text += "<br><b>Genomes Extracted:</b> [ling.absorbedcount]"
|
||||
|
||||
if(changeling.objectives.len)
|
||||
var/count = 1
|
||||
@@ -265,176 +133,8 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
||||
|
||||
to_chat(world, text)
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind)
|
||||
var/list/stored_profiles = list() //list of datum/changelingprofile
|
||||
var/datum/changelingprofile/first_prof = null
|
||||
//var/list/absorbed_dna = list()
|
||||
//var/list/protected_dna = list() //dna that is not lost when capacity is otherwise full
|
||||
var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation.
|
||||
var/absorbedcount = 0
|
||||
var/chem_charges = 20
|
||||
var/chem_storage = 75
|
||||
var/chem_recharge_rate = 1
|
||||
var/chem_recharge_slowdown = 0
|
||||
var/sting_range = 2
|
||||
var/changelingID = "Changeling"
|
||||
var/geneticdamage = 0
|
||||
var/isabsorbing = 0
|
||||
var/islinking = 0
|
||||
var/geneticpoints = 10
|
||||
var/purchasedpowers = list()
|
||||
var/mimicing = ""
|
||||
var/canrespec = 0
|
||||
var/changeling_speak = 0
|
||||
var/datum/dna/chosen_dna
|
||||
var/obj/effect/proc_holder/changeling/sting/chosen_sting
|
||||
var/datum/cellular_emporium/cellular_emporium
|
||||
var/datum/action/innate/cellular_emporium/emporium_action
|
||||
|
||||
/datum/changeling/New(var/gender=FEMALE)
|
||||
..()
|
||||
var/honorific
|
||||
if(gender == FEMALE)
|
||||
honorific = "Ms."
|
||||
else
|
||||
honorific = "Mr."
|
||||
if(GLOB.possible_changeling_IDs.len)
|
||||
changelingID = pick(GLOB.possible_changeling_IDs)
|
||||
GLOB.possible_changeling_IDs -= changelingID
|
||||
changelingID = "[honorific] [changelingID]"
|
||||
else
|
||||
changelingID = "[honorific] [rand(1,999)]"
|
||||
|
||||
cellular_emporium = new(src)
|
||||
emporium_action = new(cellular_emporium)
|
||||
|
||||
/datum/changeling/Destroy()
|
||||
qdel(cellular_emporium)
|
||||
cellular_emporium = null
|
||||
qdel(emporium_action)
|
||||
emporium_action = null
|
||||
. = ..()
|
||||
|
||||
/datum/changeling/proc/regenerate(var/mob/living/carbon/the_ling)
|
||||
if(istype(the_ling))
|
||||
emporium_action.Grant(the_ling)
|
||||
if(the_ling.stat == DEAD)
|
||||
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), (chem_storage*0.5))
|
||||
geneticdamage = max(LING_DEAD_GENETICDAMAGE_HEAL_CAP,geneticdamage-1)
|
||||
else //not dead? no chem/geneticdamage caps.
|
||||
chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage)
|
||||
geneticdamage = max(0, geneticdamage-1)
|
||||
|
||||
|
||||
/datum/changeling/proc/get_dna(dna_owner)
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(dna_owner == prof.name)
|
||||
return prof
|
||||
|
||||
/datum/changeling/proc/has_dna(datum/dna/tDNA)
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(tDNA.is_same_as(prof.dna))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/changeling/proc/can_absorb_dna(mob/living/carbon/user, mob/living/carbon/human/target, var/verbose=1)
|
||||
if(stored_profiles.len)
|
||||
var/datum/changelingprofile/prof = stored_profiles[1]
|
||||
if(prof.dna == user.dna && stored_profiles.len >= dna_max)//If our current DNA is the stalest, we gotta ditch it.
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||
return
|
||||
if(!target)
|
||||
return
|
||||
if(NO_DNA_COPY in target.dna.species.species_traits)
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
||||
return
|
||||
if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
|
||||
return
|
||||
if(!ishuman(target))//Absorbing monkeys is entirely possible, but it can cause issues with transforming. That's what lesser form is for anyway!
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We could gain no benefit from absorbing a lesser creature.</span>")
|
||||
return
|
||||
if(has_dna(target.dna))
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We already have this DNA in storage!</span>")
|
||||
return
|
||||
if(!target.has_dna())
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
/datum/changeling/proc/create_profile(mob/living/carbon/human/H, mob/living/carbon/human/user, protect = 0)
|
||||
var/datum/changelingprofile/prof = new
|
||||
|
||||
H.dna.real_name = H.real_name //Set this again, just to be sure that it's properly set.
|
||||
var/datum/dna/new_dna = new H.dna.type
|
||||
H.dna.copy_dna(new_dna)
|
||||
prof.dna = new_dna
|
||||
prof.name = H.real_name
|
||||
prof.protected = protect
|
||||
|
||||
prof.underwear = H.underwear
|
||||
prof.undershirt = H.undershirt
|
||||
prof.socks = H.socks
|
||||
|
||||
var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
|
||||
for(var/slot in slots)
|
||||
if(slot in H.vars)
|
||||
var/obj/item/I = H.vars[slot]
|
||||
if(!I)
|
||||
continue
|
||||
prof.name_list[slot] = I.name
|
||||
prof.appearance_list[slot] = I.appearance
|
||||
prof.flags_cover_list[slot] = I.flags_cover
|
||||
prof.item_color_list[slot] = I.item_color
|
||||
prof.item_state_list[slot] = I.item_state
|
||||
prof.exists_list[slot] = 1
|
||||
else
|
||||
continue
|
||||
|
||||
return prof
|
||||
|
||||
/datum/changeling/proc/add_profile(datum/changelingprofile/prof)
|
||||
if(stored_profiles.len > dna_max)
|
||||
if(!push_out_profile())
|
||||
return
|
||||
|
||||
stored_profiles += prof
|
||||
absorbedcount++
|
||||
|
||||
/datum/changeling/proc/add_new_profile(mob/living/carbon/human/H, mob/living/carbon/human/user, protect = 0)
|
||||
var/datum/changelingprofile/prof = create_profile(H, protect)
|
||||
add_profile(prof)
|
||||
return prof
|
||||
|
||||
/datum/changeling/proc/remove_profile(mob/living/carbon/human/H, force = 0)
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(H.real_name == prof.name)
|
||||
if(prof.protected && !force)
|
||||
continue
|
||||
stored_profiles -= prof
|
||||
qdel(prof)
|
||||
|
||||
/datum/changeling/proc/get_profile_to_remove()
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(!prof.protected)
|
||||
return prof
|
||||
|
||||
/datum/changeling/proc/push_out_profile()
|
||||
var/datum/changelingprofile/removeprofile = get_profile_to_remove()
|
||||
if(removeprofile)
|
||||
stored_profiles -= removeprofile
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof)
|
||||
var/datum/dna/chosen_dna = chosen_prof.dna
|
||||
user.real_name = chosen_prof.name
|
||||
@@ -474,50 +174,4 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
||||
if(equip)
|
||||
user.equip_to_slot_or_del(C, GLOB.slot2slot[slot])
|
||||
|
||||
user.regenerate_icons()
|
||||
|
||||
/datum/changelingprofile
|
||||
var/name = "a bug"
|
||||
|
||||
var/protected = 0
|
||||
|
||||
var/datum/dna/dna = null
|
||||
var/list/name_list = list() //associative list of slotname = itemname
|
||||
var/list/appearance_list = list()
|
||||
var/list/flags_cover_list = list()
|
||||
var/list/exists_list = list()
|
||||
var/list/item_color_list = list()
|
||||
var/list/item_state_list = list()
|
||||
|
||||
var/underwear
|
||||
var/undershirt
|
||||
var/socks
|
||||
|
||||
/datum/changelingprofile/Destroy()
|
||||
qdel(dna)
|
||||
. = ..()
|
||||
|
||||
/datum/changelingprofile/proc/copy_profile(datum/changelingprofile/newprofile)
|
||||
newprofile.name = name
|
||||
newprofile.protected = protected
|
||||
newprofile.dna = new dna.type
|
||||
dna.copy_dna(newprofile.dna)
|
||||
newprofile.name_list = name_list.Copy()
|
||||
newprofile.appearance_list = appearance_list.Copy()
|
||||
newprofile.flags_cover_list = flags_cover_list.Copy()
|
||||
newprofile.exists_list = exists_list.Copy()
|
||||
newprofile.item_color_list = item_color_list.Copy()
|
||||
newprofile.item_state_list = item_state_list.Copy()
|
||||
newprofile.underwear = underwear
|
||||
newprofile.undershirt = undershirt
|
||||
newprofile.socks = socks
|
||||
|
||||
/datum/game_mode/proc/update_changeling_icons_added(datum/mind/changling_mind)
|
||||
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
||||
hud.join_hud(changling_mind.current)
|
||||
set_antag_hud(changling_mind.current, "changling")
|
||||
|
||||
/datum/game_mode/proc/update_changeling_icons_removed(datum/mind/changling_mind)
|
||||
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
|
||||
hud.leave_hud(changling_mind.current)
|
||||
set_antag_hud(changling_mind.current, null)
|
||||
user.regenerate_icons()
|
||||
@@ -26,14 +26,14 @@
|
||||
|
||||
/obj/effect/proc_holder/changeling/Click()
|
||||
var/mob/user = usr
|
||||
if(!user || !user.mind || !user.mind.changeling)
|
||||
if(!user || !user.mind || !user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
return
|
||||
try_to_sting(user)
|
||||
|
||||
/obj/effect/proc_holder/changeling/proc/try_to_sting(mob/user, mob/target)
|
||||
if(!can_sting(user, target))
|
||||
return
|
||||
var/datum/changeling/c = user.mind.changeling
|
||||
var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(sting_action(user, target))
|
||||
SSblackbox.add_details("changeling_powers",name)
|
||||
sting_feedback(user, target)
|
||||
@@ -52,7 +52,7 @@
|
||||
if(req_human && !ishuman(user))
|
||||
to_chat(user, "<span class='warning'>We cannot do that in this form!</span>")
|
||||
return 0
|
||||
var/datum/changeling/c = user.mind.changeling
|
||||
var/datum/antagonist/changeling/c = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(c.chem_charges < chemical_cost)
|
||||
to_chat(user, "<span class='warning'>We require at least [chemical_cost] unit\s of chemicals to do that!</span>")
|
||||
return 0
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/datum/changeling/proc/purchasePower(mob/living/carbon/user, sting_name)
|
||||
|
||||
var/obj/effect/proc_holder/changeling/thepower = null
|
||||
|
||||
for(var/path in subtypesof(/obj/effect/proc_holder/changeling))
|
||||
var/obj/effect/proc_holder/changeling/S = path
|
||||
if(initial(S.name) == sting_name)
|
||||
thepower = new path()
|
||||
break
|
||||
|
||||
if(!thepower)
|
||||
to_chat(user, "This is awkward. Changeling power purchase failed, please report this bug to a coder!")
|
||||
return
|
||||
|
||||
if(absorbedcount < thepower.req_dna)
|
||||
to_chat(user, "We lack the energy to evolve this ability!")
|
||||
return
|
||||
|
||||
if(has_sting(thepower))
|
||||
to_chat(user, "We have already evolved this ability!")
|
||||
return
|
||||
|
||||
if(thepower.dna_cost < 0)
|
||||
to_chat(user, "We cannot evolve this ability.")
|
||||
return
|
||||
|
||||
if(geneticpoints < thepower.dna_cost)
|
||||
to_chat(user, "We have reached our capacity for abilities.")
|
||||
return
|
||||
|
||||
if(user.status_flags & FAKEDEATH)//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
|
||||
to_chat(user, "We lack the energy to evolve new abilities right now.")
|
||||
return
|
||||
|
||||
geneticpoints -= thepower.dna_cost
|
||||
purchasedpowers += thepower
|
||||
thepower.on_purchase(user)
|
||||
|
||||
//Reselect powers
|
||||
/datum/changeling/proc/lingRespec(mob/user)
|
||||
if(!ishuman(user))
|
||||
to_chat(user, "<span class='danger'>We can't remove our evolutions in this form!</span>")
|
||||
return
|
||||
if(canrespec)
|
||||
to_chat(user, "<span class='notice'>We have removed our evolutions from this form, and are now ready to readapt.</span>")
|
||||
user.remove_changeling_powers(1)
|
||||
canrespec = 0
|
||||
user.make_changeling(TRUE)
|
||||
return 1
|
||||
else
|
||||
to_chat(user, "<span class='danger'>You lack the power to readapt your evolutions!</span>")
|
||||
return 0
|
||||
|
||||
/mob/proc/make_changeling(is_respec)
|
||||
if(!mind)
|
||||
return
|
||||
if(!ishuman(src) && !ismonkey(src))
|
||||
return
|
||||
if(!mind.changeling)
|
||||
mind.changeling = new /datum/changeling(gender)
|
||||
if(mind.changeling.purchasedpowers)
|
||||
remove_changeling_powers(1)
|
||||
// purchase free powers.
|
||||
for(var/path in subtypesof(/obj/effect/proc_holder/changeling))
|
||||
var/obj/effect/proc_holder/changeling/S = new path()
|
||||
if(!S.dna_cost)
|
||||
if(!mind.changeling.has_sting(S))
|
||||
mind.changeling.purchasedpowers+=S
|
||||
S.on_purchase(src, is_respec)
|
||||
if(is_respec)
|
||||
SSblackbox.add_details("changeling_power_purchase","Readapt")
|
||||
|
||||
var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste
|
||||
if(ishuman(C))
|
||||
var/datum/changelingprofile/prof = mind.changeling.add_new_profile(C, src)
|
||||
mind.changeling.first_prof = prof
|
||||
|
||||
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B)
|
||||
B.vital = FALSE
|
||||
B.decoy_override = TRUE
|
||||
return 1
|
||||
|
||||
/datum/changeling/proc/reset()
|
||||
chosen_sting = null
|
||||
geneticpoints = initial(geneticpoints)
|
||||
sting_range = initial(sting_range)
|
||||
chem_storage = initial(chem_storage)
|
||||
chem_recharge_rate = initial(chem_recharge_rate)
|
||||
chem_charges = min(chem_charges, chem_storage)
|
||||
chem_recharge_slowdown = initial(chem_recharge_slowdown)
|
||||
mimicing = ""
|
||||
|
||||
/mob/proc/remove_changeling_powers(keep_free_powers=0)
|
||||
if(ishuman(src) || ismonkey(src))
|
||||
if(mind && mind.changeling)
|
||||
mind.changeling.changeling_speak = 0
|
||||
mind.changeling.reset()
|
||||
for(var/obj/effect/proc_holder/changeling/p in mind.changeling.purchasedpowers)
|
||||
if((p.dna_cost == 0 && keep_free_powers) || p.always_keep)
|
||||
continue
|
||||
mind.changeling.purchasedpowers -= p
|
||||
p.on_refund(src)
|
||||
if(hud_used)
|
||||
hud_used.lingstingdisplay.icon_state = null
|
||||
hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
/datum/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power)
|
||||
for(var/obj/effect/proc_holder/changeling/P in purchasedpowers)
|
||||
if(initial(power.name) == P.name)
|
||||
return 1
|
||||
return 0
|
||||
@@ -9,7 +9,7 @@
|
||||
if(!..())
|
||||
return
|
||||
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling.isabsorbing)
|
||||
to_chat(user, "<span class='warning'>We are already absorbing!</span>")
|
||||
return
|
||||
@@ -22,12 +22,12 @@
|
||||
return
|
||||
|
||||
var/mob/living/carbon/target = user.pulling
|
||||
return changeling.can_absorb_dna(user,target)
|
||||
return changeling.can_absorb_dna(target)
|
||||
|
||||
|
||||
|
||||
/obj/effect/proc_holder/changeling/absorbDNA/sting_action(mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/mob/living/carbon/human/target = user.pulling
|
||||
changeling.isabsorbing = 1
|
||||
for(var/i in 1 to 3)
|
||||
@@ -52,7 +52,7 @@
|
||||
to_chat(target, "<span class='userdanger'>You are absorbed by the changeling!</span>")
|
||||
|
||||
if(!changeling.has_dna(target.dna))
|
||||
changeling.add_new_profile(target, user)
|
||||
changeling.add_new_profile(target)
|
||||
|
||||
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
|
||||
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
|
||||
@@ -84,12 +84,14 @@
|
||||
user.mind.store_memory("<B>We have no more knowledge of [target]'s speech patterns.</B>")
|
||||
to_chat(user, "<span class='boldnotice'>We have no more knowledge of [target]'s speech patterns.</span>")
|
||||
|
||||
if(target.mind.changeling)//If the target was a changeling, suck out their extra juice and objective points!
|
||||
changeling.chem_charges += min(target.mind.changeling.chem_charges, changeling.chem_storage)
|
||||
changeling.absorbedcount += (target.mind.changeling.absorbedcount)
|
||||
|
||||
target.mind.changeling.stored_profiles.len = 1
|
||||
target.mind.changeling.absorbedcount = 0
|
||||
var/datum/antagonist/changeling/target_ling = target.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(target_ling)//If the target was a changeling, suck out their extra juice and objective points!
|
||||
changeling.chem_charges += min(target_ling.chem_charges, changeling.chem_storage)
|
||||
changeling.absorbedcount += (target_ling.absorbedcount)
|
||||
|
||||
target_ling.stored_profiles.len = 1
|
||||
target_ling.absorbedcount = 0
|
||||
|
||||
|
||||
changeling.chem_charges=min(changeling.chem_charges+10, changeling.chem_storage)
|
||||
|
||||
@@ -1,35 +1,37 @@
|
||||
/obj/effect/proc_holder/changeling/fakedeath
|
||||
name = "Reviving Stasis"
|
||||
desc = "We fall into a stasis, allowing us to regenerate and trick our enemies."
|
||||
chemical_cost = 15
|
||||
dna_cost = 0
|
||||
req_dna = 1
|
||||
req_stat = DEAD
|
||||
|
||||
//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay.
|
||||
/obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user)
|
||||
to_chat(user, "<span class='notice'>We begin our stasis, preparing energy to arise once more.</span>")
|
||||
if(user.stat != DEAD)
|
||||
user.emote("deathgasp")
|
||||
user.tod = worldtime2text()
|
||||
user.status_flags |= FAKEDEATH //play dead
|
||||
user.update_stat()
|
||||
user.update_canmove()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME, TIMER_UNIQUE)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/fakedeath/proc/ready_to_regenerate(mob/user)
|
||||
if(user && user.mind && user.mind.changeling && user.mind.changeling.purchasedpowers)
|
||||
to_chat(user, "<span class='notice'>We are ready to revive.</span>")
|
||||
user.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/revive(null)
|
||||
|
||||
/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/user)
|
||||
if(user.status_flags & FAKEDEATH)
|
||||
to_chat(user, "<span class='warning'>We are already reviving.</span>")
|
||||
return
|
||||
if(!user.stat) //Confirmation for living changelings if they want to fake their death
|
||||
switch(alert("Are we sure we wish to fake our own death?",,"Yes", "No"))
|
||||
if("No")
|
||||
return
|
||||
return ..()
|
||||
/obj/effect/proc_holder/changeling/fakedeath
|
||||
name = "Reviving Stasis"
|
||||
desc = "We fall into a stasis, allowing us to regenerate and trick our enemies."
|
||||
chemical_cost = 15
|
||||
dna_cost = 0
|
||||
req_dna = 1
|
||||
req_stat = DEAD
|
||||
|
||||
//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay.
|
||||
/obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user)
|
||||
to_chat(user, "<span class='notice'>We begin our stasis, preparing energy to arise once more.</span>")
|
||||
if(user.stat != DEAD)
|
||||
user.emote("deathgasp")
|
||||
user.tod = worldtime2text()
|
||||
user.status_flags |= FAKEDEATH //play dead
|
||||
user.update_stat()
|
||||
user.update_canmove()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/ready_to_regenerate, user), LING_FAKEDEATH_TIME, TIMER_UNIQUE)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/fakedeath/proc/ready_to_regenerate(mob/user)
|
||||
if(user && user.mind)
|
||||
var/datum/antagonist/changeling/C = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(C && C.purchasedpowers)
|
||||
to_chat(user, "<span class='notice'>We are ready to revive.</span>")
|
||||
C.purchasedpowers += new /obj/effect/proc_holder/changeling/revive(null)
|
||||
|
||||
/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/user)
|
||||
if(user.status_flags & FAKEDEATH)
|
||||
to_chat(user, "<span class='warning'>We are already reviving.</span>")
|
||||
return
|
||||
if(!user.stat) //Confirmation for living changelings if they want to fake their death
|
||||
switch(alert("Are we sure we wish to fake our own death?",,"Yes", "No"))
|
||||
if("No")
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -1,93 +1,93 @@
|
||||
//HIVEMIND COMMUNICATION (:g)
|
||||
/obj/effect/proc_holder/changeling/hivemind_comms
|
||||
name = "Hivemind Communication"
|
||||
desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings."
|
||||
helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives."
|
||||
dna_cost = 0
|
||||
chemical_cost = -1
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(mob/user, is_respec)
|
||||
..()
|
||||
var/datum/changeling/changeling=user.mind.changeling
|
||||
changeling.changeling_speak = 1
|
||||
to_chat(user, "<i><font color=#800080>Use say \":g message\" to communicate with the other changelings.</font></i>")
|
||||
var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
|
||||
if(!changeling.has_sting(S1))
|
||||
changeling.purchasedpowers+=S1
|
||||
var/obj/effect/proc_holder/changeling/hivemind_download/S2 = new
|
||||
if(!changeling.has_sting(S2))
|
||||
changeling.purchasedpowers+=S2
|
||||
|
||||
// HIVE MIND UPLOAD/DOWNLOAD DNA
|
||||
GLOBAL_LIST_EMPTY(hivemind_bank)
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_upload
|
||||
name = "Hive Channel DNA"
|
||||
desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it."
|
||||
chemical_cost = 10
|
||||
dna_cost = -1
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/list/names = list()
|
||||
for(var/datum/changelingprofile/prof in changeling.stored_profiles)
|
||||
if(!(prof in GLOB.hivemind_bank))
|
||||
names += prof.name
|
||||
|
||||
if(names.len <= 0)
|
||||
to_chat(user, "<span class='notice'>The airwaves already have all of our DNA.</span>")
|
||||
return
|
||||
|
||||
var/chosen_name = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names
|
||||
if(!chosen_name)
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/chosen_dna = changeling.get_dna(chosen_name)
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/uploaded_dna = new chosen_dna.type
|
||||
chosen_dna.copy_profile(uploaded_dna)
|
||||
GLOB.hivemind_bank += uploaded_dna
|
||||
to_chat(user, "<span class='notice'>We channel the DNA of [chosen_name] to the air.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_download
|
||||
name = "Hive Absorb DNA"
|
||||
desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives."
|
||||
chemical_cost = 10
|
||||
dna_cost = -1
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user)
|
||||
if(!..())
|
||||
return
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/datum/changelingprofile/first_prof = changeling.stored_profiles[1]
|
||||
if(first_prof.name == user.real_name)//If our current DNA is the stalest, we gotta ditch it.
|
||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_download/sting_action(mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/list/names = list()
|
||||
for(var/datum/changelingprofile/prof in GLOB.hivemind_bank)
|
||||
if(!(prof in changeling.stored_profiles))
|
||||
names[prof.name] = prof
|
||||
|
||||
if(names.len <= 0)
|
||||
to_chat(user, "<span class='notice'>There's no new DNA to absorb from the air.</span>")
|
||||
return
|
||||
|
||||
var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names
|
||||
if(!S)
|
||||
return
|
||||
var/datum/changelingprofile/chosen_prof = names[S]
|
||||
if(!chosen_prof)
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/downloaded_prof = new chosen_prof.type
|
||||
chosen_prof.copy_profile(downloaded_prof)
|
||||
changeling.add_profile(downloaded_prof)
|
||||
to_chat(user, "<span class='notice'>We absorb the DNA of [S] from the air.</span>")
|
||||
return TRUE
|
||||
//HIVEMIND COMMUNICATION (:g)
|
||||
/obj/effect/proc_holder/changeling/hivemind_comms
|
||||
name = "Hivemind Communication"
|
||||
desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings."
|
||||
helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives."
|
||||
dna_cost = 0
|
||||
chemical_cost = -1
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(mob/user, is_respec)
|
||||
..()
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.changeling_speak = 1
|
||||
to_chat(user, "<i><font color=#800080>Use say \":g message\" to communicate with the other changelings.</font></i>")
|
||||
var/obj/effect/proc_holder/changeling/hivemind_upload/S1 = new
|
||||
if(!changeling.has_sting(S1))
|
||||
changeling.purchasedpowers+=S1
|
||||
var/obj/effect/proc_holder/changeling/hivemind_download/S2 = new
|
||||
if(!changeling.has_sting(S2))
|
||||
changeling.purchasedpowers+=S2
|
||||
|
||||
// HIVE MIND UPLOAD/DOWNLOAD DNA
|
||||
GLOBAL_LIST_EMPTY(hivemind_bank)
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_upload
|
||||
name = "Hive Channel DNA"
|
||||
desc = "Allows us to channel DNA in the airwaves to allow other changelings to absorb it."
|
||||
chemical_cost = 10
|
||||
dna_cost = -1
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/list/names = list()
|
||||
for(var/datum/changelingprofile/prof in changeling.stored_profiles)
|
||||
if(!(prof in GLOB.hivemind_bank))
|
||||
names += prof.name
|
||||
|
||||
if(names.len <= 0)
|
||||
to_chat(user, "<span class='notice'>The airwaves already have all of our DNA.</span>")
|
||||
return
|
||||
|
||||
var/chosen_name = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names
|
||||
if(!chosen_name)
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/chosen_dna = changeling.get_dna(chosen_name)
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/uploaded_dna = new chosen_dna.type
|
||||
chosen_dna.copy_profile(uploaded_dna)
|
||||
GLOB.hivemind_bank += uploaded_dna
|
||||
to_chat(user, "<span class='notice'>We channel the DNA of [chosen_name] to the air.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_download
|
||||
name = "Hive Absorb DNA"
|
||||
desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives."
|
||||
chemical_cost = 10
|
||||
dna_cost = -1
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user)
|
||||
if(!..())
|
||||
return
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/datum/changelingprofile/first_prof = changeling.stored_profiles[1]
|
||||
if(first_prof.name == user.real_name)//If our current DNA is the stalest, we gotta ditch it.
|
||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/hivemind_download/sting_action(mob/user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/list/names = list()
|
||||
for(var/datum/changelingprofile/prof in GLOB.hivemind_bank)
|
||||
if(!(prof in changeling.stored_profiles))
|
||||
names[prof.name] = prof
|
||||
|
||||
if(names.len <= 0)
|
||||
to_chat(user, "<span class='notice'>There's no new DNA to absorb from the air.</span>")
|
||||
return
|
||||
|
||||
var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names
|
||||
if(!S)
|
||||
return
|
||||
var/datum/changelingprofile/chosen_prof = names[S]
|
||||
if(!chosen_prof)
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/downloaded_prof = new chosen_prof.type
|
||||
chosen_prof.copy_profile(downloaded_prof)
|
||||
changeling.add_profile(downloaded_prof)
|
||||
to_chat(user, "<span class='notice'>We absorb the DNA of [S] from the air.</span>")
|
||||
return TRUE
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
/obj/effect/proc_holder/changeling/humanform
|
||||
name = "Human Form"
|
||||
desc = "We change into a human."
|
||||
chemical_cost = 5
|
||||
req_dna = 1
|
||||
|
||||
//Transform into a human.
|
||||
/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/list/names = list()
|
||||
for(var/datum/changelingprofile/prof in changeling.stored_profiles)
|
||||
names += "[prof.name]"
|
||||
|
||||
var/chosen_name = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
|
||||
if(!chosen_name)
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/chosen_prof = changeling.get_dna(chosen_name)
|
||||
if(!chosen_prof)
|
||||
return
|
||||
if(!user || user.notransform)
|
||||
return 0
|
||||
to_chat(user, "<span class='notice'>We transform our appearance.</span>")
|
||||
|
||||
changeling.purchasedpowers -= src
|
||||
|
||||
var/newmob = user.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS)
|
||||
|
||||
changeling_transform(newmob, chosen_prof)
|
||||
return TRUE
|
||||
/obj/effect/proc_holder/changeling/humanform
|
||||
name = "Human Form"
|
||||
desc = "We change into a human."
|
||||
chemical_cost = 5
|
||||
req_dna = 1
|
||||
|
||||
//Transform into a human.
|
||||
/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/list/names = list()
|
||||
for(var/datum/changelingprofile/prof in changeling.stored_profiles)
|
||||
names += "[prof.name]"
|
||||
|
||||
var/chosen_name = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
|
||||
if(!chosen_name)
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/chosen_prof = changeling.get_dna(chosen_name)
|
||||
if(!chosen_prof)
|
||||
return
|
||||
if(!user || user.notransform)
|
||||
return 0
|
||||
to_chat(user, "<span class='notice'>We transform our appearance.</span>")
|
||||
|
||||
changeling.purchasedpowers -= src
|
||||
|
||||
var/newmob = user.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS)
|
||||
|
||||
changeling_transform(newmob, chosen_prof)
|
||||
return TRUE
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user)
|
||||
if(!..())
|
||||
return
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling.islinking)
|
||||
to_chat(user, "<span class='warning'>We have already formed a link with the victim!</span>")
|
||||
return
|
||||
@@ -19,22 +19,23 @@
|
||||
to_chat(user, "<span class='warning'>We cannot link with this creature!</span>")
|
||||
return
|
||||
var/mob/living/carbon/target = user.pulling
|
||||
|
||||
if(!target.mind)
|
||||
to_chat(user, "<span class='warning'>The victim has no mind to link to!</span>")
|
||||
return
|
||||
if(target.stat == DEAD)
|
||||
to_chat(user, "<span class='warning'>The victim is dead, you cannot link to a dead mind!</span>")
|
||||
return
|
||||
if(target.mind.changeling)
|
||||
if(target.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='warning'>The victim is already a part of the hivemind!</span>")
|
||||
return
|
||||
if(user.grab_state <= GRAB_AGGRESSIVE)
|
||||
to_chat(user, "<span class='warning'>We must have a tighter grip to link with this creature!</span>")
|
||||
return
|
||||
return changeling.can_absorb_dna(user,target)
|
||||
return changeling.can_absorb_dna(target)
|
||||
|
||||
/obj/effect/proc_holder/changeling/linglink/sting_action(mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/mob/living/carbon/human/target = user.pulling
|
||||
changeling.islinking = 1
|
||||
for(var/i in 1 to 3)
|
||||
@@ -47,7 +48,8 @@
|
||||
if(3)
|
||||
to_chat(user, "<span class='notice'>We mold the [target]'s mind like clay, granting [target.p_them()] the ability to speak in the hivemind!</span>")
|
||||
to_chat(target, "<span class='userdanger'>A migraine throbs behind your eyes, you hear yourself screaming - but your mouth has not opened!</span>")
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
for(var/mi in GLOB.mob_list)
|
||||
var/mob/M = mi
|
||||
if(M.lingcheck() == 2)
|
||||
to_chat(M, "<i><font color=#800080>We can sense a foreign presence in the hivemind...</font></i>")
|
||||
target.mind.linglink = 1
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
/obj/effect/proc_holder/changeling/mimicvoice
|
||||
name = "Mimic Voice"
|
||||
desc = "We shape our vocal glands to sound like a desired voice."
|
||||
helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this."
|
||||
chemical_cost = 0 //constant chemical drain hardcoded
|
||||
dna_cost = 1
|
||||
req_human = 1
|
||||
|
||||
|
||||
// Fake Voice
|
||||
/obj/effect/proc_holder/changeling/mimicvoice/sting_action(mob/user)
|
||||
var/datum/changeling/changeling=user.mind.changeling
|
||||
if(changeling.mimicing)
|
||||
changeling.mimicing = ""
|
||||
changeling.chem_recharge_slowdown -= 0.5
|
||||
to_chat(user, "<span class='notice'>We return our vocal glands to their original position.</span>")
|
||||
return
|
||||
|
||||
var/mimic_voice = stripped_input(user, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN)
|
||||
if(!mimic_voice)
|
||||
return
|
||||
|
||||
changeling.mimicing = mimic_voice
|
||||
changeling.chem_recharge_slowdown += 0.5
|
||||
to_chat(user, "<span class='notice'>We shape our glands to take the voice of <b>[mimic_voice]</b>, this will slow down regenerating chemicals while active.</span>")
|
||||
to_chat(user, "<span class='notice'>Use this power again to return to our original voice and return chemical production to normal levels.</span>")
|
||||
return TRUE
|
||||
/obj/effect/proc_holder/changeling/mimicvoice
|
||||
name = "Mimic Voice"
|
||||
desc = "We shape our vocal glands to sound like a desired voice."
|
||||
helptext = "Will turn your voice into the name that you enter. We must constantly expend chemicals to maintain our form like this."
|
||||
chemical_cost = 0 //constant chemical drain hardcoded
|
||||
dna_cost = 1
|
||||
req_human = 1
|
||||
|
||||
|
||||
// Fake Voice
|
||||
/obj/effect/proc_holder/changeling/mimicvoice/sting_action(mob/user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling.mimicing)
|
||||
changeling.mimicing = ""
|
||||
changeling.chem_recharge_slowdown -= 0.5
|
||||
to_chat(user, "<span class='notice'>We return our vocal glands to their original position.</span>")
|
||||
return
|
||||
|
||||
var/mimic_voice = stripped_input(user, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN)
|
||||
if(!mimic_voice)
|
||||
return
|
||||
|
||||
changeling.mimicing = mimic_voice
|
||||
changeling.chem_recharge_slowdown += 0.5
|
||||
to_chat(user, "<span class='notice'>We shape our glands to take the voice of <b>[mimic_voice]</b>, this will slow down regenerating chemicals while active.</span>")
|
||||
to_chat(user, "<span class='notice'>Use this power again to return to our original voice and return chemical production to normal levels.</span>")
|
||||
return TRUE
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
//checks if we already have an organic suit and casts it off.
|
||||
/obj/effect/proc_holder/changeling/suit/proc/check_suit(mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!ishuman(user) || !changeling)
|
||||
return 1
|
||||
var/mob/living/carbon/human/H = user
|
||||
@@ -122,7 +122,7 @@
|
||||
user.equip_to_slot_if_possible(new suit_type(user), slot_wear_suit, 1, 1, 1)
|
||||
user.equip_to_slot_if_possible(new helmet_type(user), slot_head, 1, 1, 1)
|
||||
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.chem_recharge_slowdown += recharge_slowdown
|
||||
return TRUE
|
||||
|
||||
@@ -385,7 +385,7 @@
|
||||
weapon_name_simple = "shield"
|
||||
|
||||
/obj/effect/proc_holder/changeling/weapon/shield/sting_action(mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling //So we can read the absorbedcount.
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) //So we can read the absorbedcount.
|
||||
if(!changeling)
|
||||
return
|
||||
|
||||
|
||||
@@ -1,35 +1,37 @@
|
||||
/obj/effect/proc_holder/changeling/revive
|
||||
name = "Revive"
|
||||
desc = "We regenerate, healing all damage from our form."
|
||||
helptext = "Does not regrow lost organs or a missing head."
|
||||
req_stat = DEAD
|
||||
always_keep = TRUE
|
||||
ignores_fakedeath = TRUE
|
||||
|
||||
//Revive from revival stasis
|
||||
/obj/effect/proc_holder/changeling/revive/sting_action(mob/living/carbon/user)
|
||||
user.status_flags &= ~(FAKEDEATH)
|
||||
user.tod = null
|
||||
user.revive(full_heal = 1)
|
||||
var/list/missing = user.get_missing_limbs()
|
||||
missing -= "head" // headless changelings are funny
|
||||
if(missing.len)
|
||||
playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
|
||||
user.visible_message("<span class='warning'>[user]'s missing limbs \
|
||||
reform, making a loud, grotesque sound!</span>",
|
||||
"<span class='userdanger'>Your limbs regrow, making a \
|
||||
loud, crunchy sound and giving you great pain!</span>",
|
||||
"<span class='italics'>You hear organic matter ripping \
|
||||
and tearing!</span>")
|
||||
user.emote("scream")
|
||||
user.regenerate_limbs(0, list("head"))
|
||||
/obj/effect/proc_holder/changeling/revive
|
||||
name = "Revive"
|
||||
desc = "We regenerate, healing all damage from our form."
|
||||
helptext = "Does not regrow lost organs or a missing head."
|
||||
req_stat = DEAD
|
||||
always_keep = TRUE
|
||||
ignores_fakedeath = TRUE
|
||||
|
||||
//Revive from revival stasis
|
||||
/obj/effect/proc_holder/changeling/revive/sting_action(mob/living/carbon/user)
|
||||
user.status_flags &= ~(FAKEDEATH)
|
||||
user.tod = null
|
||||
user.revive(full_heal = 1)
|
||||
var/list/missing = user.get_missing_limbs()
|
||||
missing -= "head" // headless changelings are funny
|
||||
if(missing.len)
|
||||
playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
|
||||
user.visible_message("<span class='warning'>[user]'s missing limbs \
|
||||
reform, making a loud, grotesque sound!</span>",
|
||||
"<span class='userdanger'>Your limbs regrow, making a \
|
||||
loud, crunchy sound and giving you great pain!</span>",
|
||||
"<span class='italics'>You hear organic matter ripping \
|
||||
and tearing!</span>")
|
||||
user.emote("scream")
|
||||
user.regenerate_limbs(0, list("head"))
|
||||
user.regenerate_organs()
|
||||
to_chat(user, "<span class='notice'>We have revived ourselves.</span>")
|
||||
user.mind.changeling.purchasedpowers -= src
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/user)
|
||||
if((user.stat != DEAD) && !(user.status_flags & FAKEDEATH))
|
||||
user.mind.changeling.purchasedpowers -= src
|
||||
return 0
|
||||
. = ..()
|
||||
to_chat(user, "<span class='notice'>We have revived ourselves.</span>")
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.purchasedpowers -= src
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/revive/can_be_used_by(mob/user)
|
||||
if((user.stat != DEAD) && !(user.status_flags & FAKEDEATH))
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.purchasedpowers -= src
|
||||
return 0
|
||||
. = ..()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
for(var/mob/living/M in get_hearers_in_view(4, user))
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(!C.mind || !C.mind.changeling)
|
||||
if(!C.mind || !C.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
C.adjustEarDamage(0, 30)
|
||||
C.confused += 25
|
||||
C.Jitter(50)
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/Click()
|
||||
var/mob/user = usr
|
||||
if(!user || !user.mind || !user.mind.changeling)
|
||||
if(!user || !user.mind)
|
||||
return
|
||||
if(!(user.mind.changeling.chosen_sting))
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!changeling)
|
||||
return
|
||||
if(!changeling.chosen_sting)
|
||||
set_sting(user)
|
||||
else
|
||||
unset_sting(user)
|
||||
@@ -15,41 +18,48 @@
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/proc/set_sting(mob/user)
|
||||
to_chat(user, "<span class='notice'>We prepare our sting, use alt+click or middle mouse button on target to sting them.</span>")
|
||||
user.mind.changeling.chosen_sting = src
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.chosen_sting = src
|
||||
|
||||
user.hud_used.lingstingdisplay.icon_state = sting_icon
|
||||
user.hud_used.lingstingdisplay.invisibility = 0
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/proc/unset_sting(mob/user)
|
||||
to_chat(user, "<span class='warning'>We retract our sting, we can't sting anyone for now.</span>")
|
||||
user.mind.changeling.chosen_sting = null
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
changeling.chosen_sting = null
|
||||
|
||||
user.hud_used.lingstingdisplay.icon_state = null
|
||||
user.hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
/mob/living/carbon/proc/unset_sting()
|
||||
if(mind && mind.changeling && mind.changeling.chosen_sting)
|
||||
src.mind.changeling.chosen_sting.unset_sting(src)
|
||||
if(mind)
|
||||
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling && changeling.chosen_sting)
|
||||
changeling.chosen_sting.unset_sting(src)
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/can_sting(mob/user, mob/target)
|
||||
if(!..())
|
||||
return
|
||||
if(!user.mind.changeling.chosen_sting)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!changeling.chosen_sting)
|
||||
to_chat(user, "We haven't prepared our sting yet!")
|
||||
if(!iscarbon(target))
|
||||
return
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
if(!AStar(user, target.loc, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0))
|
||||
if(!AStar(user, target.loc, /turf/proc/Distance, changeling.sting_range, simulated_only = 0))
|
||||
return
|
||||
if(target.mind && target.mind.changeling)
|
||||
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
sting_feedback(user, target)
|
||||
user.mind.changeling.chem_charges -= chemical_cost
|
||||
changeling.chem_charges -= chemical_cost //??
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/sting_feedback(mob/user, mob/target)
|
||||
if(!target)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>We stealthily sting [target.name].</span>")
|
||||
if(target.mind && target.mind.changeling)
|
||||
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(target, "<span class='warning'>You feel a tiny prick.</span>")
|
||||
return 1
|
||||
|
||||
@@ -65,7 +75,7 @@
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/transformation/Click()
|
||||
var/mob/user = usr
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling.chosen_sting)
|
||||
unset_sting(user)
|
||||
return
|
||||
@@ -163,12 +173,14 @@
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/extract_dna/can_sting(mob/user, mob/target)
|
||||
if(..())
|
||||
return user.mind.changeling.can_absorb_dna(user, target)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
return changeling.can_absorb_dna(target)
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target)
|
||||
add_logs(user, target, "stung", "extraction sting")
|
||||
if(!(user.mind.changeling.has_dna(target.dna)))
|
||||
user.mind.changeling.add_new_profile(target, user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!(changeling.has_dna(target.dna)))
|
||||
changeling.add_new_profile(target)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/mute
|
||||
|
||||
@@ -1,126 +1,129 @@
|
||||
/obj/effect/proc_holder/changeling/transform
|
||||
name = "Transform"
|
||||
desc = "We take on the appearance and voice of one we have absorbed."
|
||||
chemical_cost = 5
|
||||
dna_cost = 0
|
||||
req_dna = 1
|
||||
req_human = 1
|
||||
|
||||
/obj/item/clothing/glasses/changeling
|
||||
name = "flesh"
|
||||
/obj/effect/proc_holder/changeling/transform
|
||||
name = "Transform"
|
||||
desc = "We take on the appearance and voice of one we have absorbed."
|
||||
chemical_cost = 5
|
||||
dna_cost = 0
|
||||
req_dna = 1
|
||||
req_human = 1
|
||||
|
||||
/obj/item/clothing/glasses/changeling
|
||||
name = "flesh"
|
||||
flags_1 = NODROP_1
|
||||
|
||||
/obj/item/clothing/glasses/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.changeling)
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/under/changeling
|
||||
name = "flesh"
|
||||
|
||||
/obj/item/clothing/glasses/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/under/changeling
|
||||
name = "flesh"
|
||||
flags_1 = NODROP_1
|
||||
|
||||
/obj/item/clothing/under/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.changeling)
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/suit/changeling
|
||||
name = "flesh"
|
||||
|
||||
/obj/item/clothing/under/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/suit/changeling
|
||||
name = "flesh"
|
||||
flags_1 = NODROP_1
|
||||
allowed = list(/obj/item/changeling)
|
||||
|
||||
/obj/item/clothing/suit/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.changeling)
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/head/changeling
|
||||
name = "flesh"
|
||||
allowed = list(/obj/item/changeling)
|
||||
|
||||
/obj/item/clothing/suit/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/head/changeling
|
||||
name = "flesh"
|
||||
flags_1 = NODROP_1
|
||||
|
||||
/obj/item/clothing/head/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.changeling)
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/shoes/changeling
|
||||
name = "flesh"
|
||||
|
||||
/obj/item/clothing/head/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/shoes/changeling
|
||||
name = "flesh"
|
||||
flags_1 = NODROP_1
|
||||
|
||||
/obj/item/clothing/shoes/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.changeling)
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/gloves/changeling
|
||||
name = "flesh"
|
||||
|
||||
/obj/item/clothing/shoes/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/gloves/changeling
|
||||
name = "flesh"
|
||||
flags_1 = NODROP_1
|
||||
|
||||
/obj/item/clothing/gloves/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.changeling)
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/mask/changeling
|
||||
name = "flesh"
|
||||
|
||||
/obj/item/clothing/gloves/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/mask/changeling
|
||||
name = "flesh"
|
||||
flags_1 = NODROP_1
|
||||
|
||||
/obj/item/clothing/mask/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.changeling)
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/changeling
|
||||
name = "flesh"
|
||||
|
||||
/obj/item/clothing/mask/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/changeling
|
||||
name = "flesh"
|
||||
flags_1 = NODROP_1
|
||||
slot_flags = ALL
|
||||
allowed = list(/obj/item/changeling)
|
||||
|
||||
/obj/item/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.changeling)
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
//Change our DNA to that of somebody we've absorbed.
|
||||
/obj/effect/proc_holder/changeling/transform/sting_action(mob/living/carbon/human/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
var/datum/changelingprofile/chosen_prof = changeling.select_dna("Select the target DNA: ", "Target DNA", user)
|
||||
|
||||
if(!chosen_prof)
|
||||
return
|
||||
|
||||
changeling_transform(user, chosen_prof)
|
||||
return TRUE
|
||||
|
||||
/datum/changeling/proc/select_dna(var/prompt, var/title, var/mob/living/carbon/user)
|
||||
var/list/names = list("Drop Flesh Disguise")
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
names += "[prof.name]"
|
||||
|
||||
var/chosen_name = input(prompt, title, null) as null|anything in names
|
||||
if(!chosen_name)
|
||||
return
|
||||
|
||||
if(chosen_name == "Drop Flesh Disguise")
|
||||
for(var/slot in GLOB.slots)
|
||||
if(istype(user.vars[slot], GLOB.slot2type[slot]))
|
||||
qdel(user.vars[slot])
|
||||
|
||||
var/datum/changelingprofile/prof = get_dna(chosen_name)
|
||||
return prof
|
||||
slot_flags = ALL
|
||||
allowed = list(/obj/item/changeling)
|
||||
|
||||
/obj/item/changeling/attack_hand(mob/user)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
//Change our DNA to that of somebody we've absorbed.
|
||||
/obj/effect/proc_holder/changeling/transform/sting_action(mob/living/carbon/human/user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/datum/changelingprofile/chosen_prof = changeling.select_dna("Select the target DNA: ", "Target DNA")
|
||||
|
||||
if(!chosen_prof)
|
||||
return
|
||||
|
||||
changeling_transform(user, chosen_prof)
|
||||
return TRUE
|
||||
|
||||
/datum/antagonist/changeling/proc/select_dna(var/prompt, var/title)
|
||||
var/mob/living/carbon/user = owner.current
|
||||
if(!istype(user))
|
||||
return
|
||||
var/list/names = list("Drop Flesh Disguise")
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
names += "[prof.name]"
|
||||
|
||||
var/chosen_name = input(prompt, title, null) as null|anything in names
|
||||
if(!chosen_name)
|
||||
return
|
||||
|
||||
if(chosen_name == "Drop Flesh Disguise")
|
||||
for(var/slot in GLOB.slots)
|
||||
if(istype(user.vars[slot], GLOB.slot2type[slot]))
|
||||
qdel(user.vars[slot])
|
||||
|
||||
var/datum/changelingprofile/prof = get_dna(chosen_name)
|
||||
return prof
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
reroll_friendly = 1
|
||||
|
||||
var/list/possible_changelings = list()
|
||||
var/list/changelings = list()
|
||||
var/const/changeling_amount = 1 //hard limit on changelings if scaling is turned off
|
||||
|
||||
/datum/game_mode/traitor/changeling/announce()
|
||||
@@ -57,25 +58,22 @@
|
||||
|
||||
/datum/game_mode/traitor/changeling/post_setup()
|
||||
for(var/datum/mind/changeling in changelings)
|
||||
changeling.current.make_changeling()
|
||||
forge_changeling_objectives(changeling)
|
||||
greet_changeling(changeling)
|
||||
SSticker.mode.update_changeling_icons_added(changeling)
|
||||
..()
|
||||
return
|
||||
changeling.add_antag_datum(/datum/antagonist/changeling)
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners
|
||||
var/csc = CONFIG_GET(number/changeling_scaling_coeff)
|
||||
var/changelingcap = min( round(GLOB.joined_player_list.len / (csc * 4)) + 2, round(GLOB.joined_player_list.len / (csc * 2)))
|
||||
if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists
|
||||
if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
|
||||
..()
|
||||
return
|
||||
if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4)))
|
||||
if(changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4)))
|
||||
if(ROLE_CHANGELING in character.client.prefs.be_special)
|
||||
if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate"))
|
||||
if(age_check(character.client))
|
||||
if(!(character.job in restricted_jobs))
|
||||
character.mind.make_Changling()
|
||||
changelings += character.mind
|
||||
..()
|
||||
|
||||
/datum/game_mode/traitor/changeling/generate_report()
|
||||
|
||||
@@ -273,6 +273,7 @@ Credit where due:
|
||||
if(plasmaman && !visualsOnly) //If we need to breathe from the plasma tank, we should probably start doing that
|
||||
H.internal = H.get_item_for_held_index(2)
|
||||
H.update_internals_hud_icon(1)
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
/obj/item/paper/servant_primer
|
||||
name = "The Ark And You: A Primer On Servitude"
|
||||
|
||||
@@ -38,8 +38,11 @@
|
||||
beckon(AM)
|
||||
|
||||
/obj/effect/clockwork/city_of_cogs_rift/proc/beckon(atom/movable/AM)
|
||||
var/turf/T = get_turf(pick(GLOB.city_of_cogs_spawns))
|
||||
if(is_servant_of_ratvar(AM))
|
||||
T = GLOB.ark_of_the_clockwork_justiciar ? get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH) : get_turf(pick(GLOB.servant_spawns))
|
||||
AM.visible_message("<span class='danger'>[AM] passes through [src]!</span>", ignored_mob = AM)
|
||||
AM.forceMove(pick(!is_servant_of_ratvar(AM) ? GLOB.city_of_cogs_spawns : GLOB.servant_spawns))
|
||||
AM.forceMove(T)
|
||||
AM.visible_message("<span class='danger'>[AM] materializes from the air!</span>", \
|
||||
"<span class='boldannounce'>You pass through [src] and appear [is_servant_of_ratvar(AM) ? "back at the City of Cogs" : "somewhere unfamiliar. Looks like it was a one-way trip.."].</span>")
|
||||
do_sparks(5, TRUE, src)
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
var/locname = initial(A.name)
|
||||
possible_targets[avoid_assoc_duplicate_keys("[locname] [O.name]", teleportnames)] = O
|
||||
|
||||
for(var/mob/living/L in GLOB.living_mob_list)
|
||||
for(var/mob/living/L in GLOB.alive_mob_list)
|
||||
if(!L.stat && is_servant_of_ratvar(L) && !L.Adjacent(invoker) && (L.z <= ZLEVEL_SPACEMAX)) //People right next to the invoker can't be portaled to, for obvious reasons
|
||||
possible_targets[avoid_assoc_duplicate_keys("[L.name] ([L.real_name])", teleportnames)] = L
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ List of nuances:
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!whisper)
|
||||
L.say(message, "clock", spans, language=/datum/language/common)
|
||||
L.say(message, "clock", spans, language=/datum/language/common, ignore_spam = TRUE)
|
||||
else
|
||||
L.whisper(message, "clock", spans, language=/datum/language/common)
|
||||
else
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/obj/item/clockwork/slab //Clockwork slab: The most important tool in Ratvar's arsenal. Allows scripture recital, tutorials, and generates components.
|
||||
name = "clockwork slab"
|
||||
desc = "A strange metal tablet. A clock in the center turns around and around."
|
||||
clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant.\n\
|
||||
Hitting a slab, a Servant with a slab, or a cache will <b>transfer</b> this slab's components into the target, the target's slab, or the global cache, respectively."
|
||||
clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant."
|
||||
icon_state = "dread_ipad"
|
||||
lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi'
|
||||
@@ -231,7 +230,7 @@
|
||||
this will cause you to whisper your message aloud, so doing so in a public place is very suspicious and you should try to restrict it to private use.<br><br>"
|
||||
dat += "If you aren't willing or don't have the time to read through every section, you can still help your teammates! Ask if they've set up a base. If they have, head there \
|
||||
and ask however you can help; chances are there's always something. If not, it's your job as a Servant to get one up and running! Try to find a secluded, low-traffic area, \
|
||||
like the auxilary base or somewhere deep in maintenance. You'll want to go into the Drivers section of the slab and look for <i>Tinkerer's Cache.</i> Find a nice spot and \
|
||||
like the auxiliary base or somewhere deep in maintenance. You'll want to go into the Drivers section of the slab and look for <i>Tinkerer's Cache.</i> Find a nice spot and \
|
||||
create one. This serves as a storage for <i>components,</i> the cult's primary resource. (Your slab's probably produced a few by now.) By attacking that cache with this \
|
||||
slab, you'll offload all your components into it, and all Servants will be able to use those components from any distance - all Tinkerer's Caches are linked!<br><br>"
|
||||
dat += "Once you have a base up and running, contact your fellows and let them know. You should come back here often to drop off the slab's components, and your fellows \
|
||||
@@ -250,7 +249,7 @@
|
||||
teamwork is an instrumental component of your success.<br><br>" //get it? component? ha!
|
||||
dat += "As a Servant of Ratvar, the tools you are given focus around building and maintaining bases and outposts. A great deal of your power comes from stationary \
|
||||
structures, and without constructing a base somewhere, it's essentially impossible to succeed. Finding a good spot to build a base can be difficult, and it's recommended \
|
||||
that you choose an area in low-traffic part of the station (such as the auxilary base). Make sure to disconnect any cameras in the area beforehand.<br><br>"
|
||||
that you choose an area in low-traffic part of the station (such as the auxiliary base). Make sure to disconnect any cameras in the area beforehand.<br><br>"
|
||||
dat += "Because of how complex being a Servant is, it isn't possible to fit much information into this section. It's highly recommended that you read the <b>Components</b> \
|
||||
and <b>Scripture</b> sections next. Not knowing how these two systems work will cripple both you and your fellows, and lead to a frustrating experience for everyone.<br><br>"
|
||||
dat += "<font color=#BE8700 size=3>-=-=-=-=-=-</font>"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
weather_immunities = list("lava")
|
||||
movement_type = FLYING
|
||||
a_intent = INTENT_HARM
|
||||
loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor)
|
||||
light_range = 2
|
||||
light_power = 1.1
|
||||
@@ -24,7 +25,6 @@
|
||||
unique abilities, you're a fearsome fighter in one-on-one combat, and your shield protects from projectiles!<br><br>Obey the Servants and do as they \
|
||||
tell you. Your primary goal is to defend the Ark from destruction; they are your allies in this, and should be protected from harm.</b>"
|
||||
empower_string = "<span class='neovgre'>The Anima Bulwark's power flows through you! Your weapon will strike harder, your armor is sturdier, and your shield is more durable.</span>"
|
||||
var/deflect_chance = 40 //Chance to deflect any given projectile (non-damaging energy projectiles are always deflected)
|
||||
var/max_shield_health = 3
|
||||
var/shield_health = 3 //Amount of projectiles that can be deflected within
|
||||
var/shield_health_regen = 0 //When world.time equals this, shield health will regenerate
|
||||
@@ -55,8 +55,6 @@
|
||||
obj_damage = 100
|
||||
max_shield_health = INFINITY
|
||||
else if(GLOB.ratvar_approaches) //Hefty health bonus and slight attack damage increase
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
melee_damage_upper = 15
|
||||
melee_damage_lower = 15
|
||||
attacktext = "carves"
|
||||
|
||||
@@ -53,6 +53,7 @@ Applications: 8 servants, 3 caches, and 100 CV
|
||||
if(slab.busy)
|
||||
to_chat(invoker, "<span class='warning'>[slab] refuses to work, displaying the message: \"[slab.busy]!\"</span>")
|
||||
return FALSE
|
||||
pre_recital()
|
||||
slab.busy = "Invocation ([name]) in progress"
|
||||
if(GLOB.ratvar_awakens)
|
||||
channel_time *= 0.5 //if ratvar has awoken, half channel time and no cost
|
||||
@@ -176,6 +177,9 @@ Applications: 8 servants, 3 caches, and 100 CV
|
||||
/datum/clockwork_scripture/proc/scripture_fail() //Called if the scripture fails to invoke.
|
||||
|
||||
|
||||
/datum/clockwork_scripture/proc/pre_recital() //Called before the scripture is recited
|
||||
|
||||
|
||||
/datum/clockwork_scripture/proc/post_recital() //Called after the scripture is recited
|
||||
|
||||
//Channeled scripture begins instantly but runs constantly
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
/datum/clockwork_scripture/create_object/construct/clockwork_marauder
|
||||
descname = "Well-Rounded Combat Construct"
|
||||
name = "Clockwork Marauder"
|
||||
desc = "Creates a shell for a clockwork marauder, a balanced frontline construct."
|
||||
desc = "Creates a shell for a clockwork marauder, a balanced frontline construct that can deflect projectiles with its shield."
|
||||
invocations = list("Arise, avatar of Arbiter!", "Defend the Ark with vengeful zeal.")
|
||||
channel_time = 50
|
||||
power_cost = 1000
|
||||
creator_message = "<span class='brass'>Your slab disgorges several chunks of replicant alloy that form into a suit of thrumming armor.</span>"
|
||||
usage_tip = "The marauder's shield can effectively deflect energy-based projectiles."
|
||||
usage_tip = "Reciting this scripture multiple times in a short period will cause it to take longer!"
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
primary_component = BELLIGERENT_EYE
|
||||
@@ -22,6 +22,9 @@
|
||||
object_path = /obj/item/clockwork/construct_chassis/clockwork_marauder
|
||||
construct_type = /mob/living/simple_animal/hostile/clockwork/marauder
|
||||
combat_construct = TRUE
|
||||
var/static/recent_marauders = 0
|
||||
var/static/time_since_last_marauder = 0
|
||||
var/static/scaled_recital_time = 0
|
||||
|
||||
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/update_construct_limit()
|
||||
var/human_servants = 0
|
||||
@@ -32,15 +35,30 @@
|
||||
construct_limit = human_servants / 4 //1 per 4 human servants, and a maximum of 3 marauders
|
||||
construct_limit = Clamp(construct_limit, 1, 3)
|
||||
|
||||
/datum/clockwork_scripture/create_object/prolonging_prism/check_special_requirements()
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
|
||||
to_chat(invoker, "<span class='inathneq'>\"It is too late to construct one of these, champion.\"</span>")
|
||||
return FALSE
|
||||
var/turf/T = get_turf(invoker)
|
||||
if(!T || !(T.z in GLOB.station_z_levels))
|
||||
to_chat(invoker, "<span class='inathneq'>\"You must be on the station to construct one of these, champion.\"</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/pre_recital()
|
||||
channel_time = initial(channel_time)
|
||||
calculate_scaling()
|
||||
if(scaled_recital_time)
|
||||
to_chat(invoker, "<span class='warning'>The Hierophant Network is under strain from repeated summoning, making this scripture [scaled_recital_time / 10] seconds slower!</span>")
|
||||
channel_time += scaled_recital_time
|
||||
return TRUE
|
||||
|
||||
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/scripture_effects()
|
||||
. = ..()
|
||||
time_since_last_marauder = world.time
|
||||
recent_marauders++
|
||||
calculate_scaling()
|
||||
|
||||
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/proc/calculate_scaling()
|
||||
var/WT = world.time
|
||||
var/MT = time_since_last_marauder //Cast it for quicker reference
|
||||
var/marauders_to_exclude = 0
|
||||
if(world.time >= time_since_last_marauder + MARAUDER_SCRIPTURE_SCALING_THRESHOLD)
|
||||
marauders_to_exclude = round(WT - MT) / MARAUDER_SCRIPTURE_SCALING_THRESHOLD //If at least 20 seconds have passed, lose one marauder for each 20 seconds
|
||||
//i.e. world.time = 10000, last marauder = 9000, so we lose 5 marauders from the recent count since 10k - 9k = 1k, 1k / 200 = 5
|
||||
time_since_last_marauder = world.time //So that it can't be spammed to make the marauder exclusion plummet; this emulates "ticking"
|
||||
recent_marauders = max(0, recent_marauders - marauders_to_exclude)
|
||||
scaled_recital_time = min(recent_marauders * MARAUDER_SCRIPTURE_SCALING_TIME, MARAUDER_SCRIPTURE_SCALING_MAX)
|
||||
|
||||
|
||||
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
|
||||
/datum/clockwork_scripture/abscond/scripture_effects()
|
||||
var/take_pulling = invoker.pulling && isliving(invoker.pulling) && get_clockwork_power(ABSCOND_ABDUCTION_COST)
|
||||
var/turf/T = get_turf(pick(GLOB.servant_spawns))
|
||||
var/turf/T
|
||||
if(GLOB.ark_of_the_clockwork_justiciar)
|
||||
T = get_step(GLOB.ark_of_the_clockwork_justiciar, SOUTH)
|
||||
else
|
||||
T = get_turf(pick(GLOB.servant_spawns))
|
||||
invoker.visible_message("<span class='warning'>[invoker] flickers and phases out of existence!</span>", \
|
||||
"<span class='bold sevtug_small'>You feel a dizzying sense of vertigo as you're yanked back to Reebe!</span>")
|
||||
T.visible_message("<span class='warning'>[invoker] flickers and phases into existence!</span>")
|
||||
|
||||
@@ -322,7 +322,7 @@
|
||||
to_chat(invoker, "<span class='warning'>You must not be inside an object to use this scripture!</span>")
|
||||
return FALSE
|
||||
var/other_servants = 0
|
||||
for(var/mob/living/L in GLOB.living_mob_list)
|
||||
for(var/mob/living/L in GLOB.alive_mob_list)
|
||||
if(is_servant_of_ratvar(L) && !L.stat && L != invoker)
|
||||
other_servants++
|
||||
for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in GLOB.all_clockwork_objects)
|
||||
|
||||
@@ -134,11 +134,21 @@
|
||||
var/damage = max((obj_integrity * 0.7) / severity, 100) //requires multiple bombs to take down
|
||||
take_damage(damage, BRUTE, "bomb", 0)
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_time(var/deciseconds = TRUE)
|
||||
if(seconds_until_activation)
|
||||
. = seconds_until_activation
|
||||
else if(grace_period)
|
||||
. = grace_period
|
||||
else if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0)
|
||||
. = round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE), 0), 1)
|
||||
if(deciseconds)
|
||||
. *= 10
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_text(s_on_time)
|
||||
if(seconds_until_activation)
|
||||
return "[seconds_until_activation][s_on_time ? "S" : ""]"
|
||||
return "[get_arrival_time()][s_on_time ? "S" : ""]"
|
||||
if(grace_period)
|
||||
return "[grace_period][s_on_time ? "S" : ""]"
|
||||
return "[get_arrival_time()][s_on_time ? "S" : ""]"
|
||||
. = "IMMINENT"
|
||||
if(!obj_integrity)
|
||||
. = "DETONATING"
|
||||
@@ -151,12 +161,12 @@
|
||||
icon_state = initial(icon_state)
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
if(!active)
|
||||
to_chat(user, "<span class='big'><b>Seconds until the Ark's activation:</b> [get_arrival_text(TRUE)]</span>")
|
||||
to_chat(user, "<span class='big'><b>Time until the Ark's activation:</b> [DisplayTimeText(get_arrival_time())]</span>")
|
||||
else
|
||||
if(grace_period)
|
||||
to_chat(user, "<span class='big'><b>Crew grace period time remaining:</b> [get_arrival_text(TRUE)]</span>")
|
||||
to_chat(user, "<span class='big'><b>Crew grace period time remaining:</b> [DisplayTimeText(get_arrival_time())]</span>")
|
||||
else
|
||||
to_chat(user, "<span class='big'><b>Seconds until Ratvar's arrival:</b> [get_arrival_text(TRUE)]</span>")
|
||||
to_chat(user, "<span class='big'><b>Time until Ratvar's arrival:</b> [DisplayTimeText(get_arrival_time())]</span>")
|
||||
switch(progress_in_seconds)
|
||||
if(-INFINITY to GATEWAY_REEBE_FOUND)
|
||||
to_chat(user, "<span class='heavy_brass'>The Ark is feeding power into the bluespace field.</span>")
|
||||
@@ -266,15 +276,16 @@
|
||||
CHECK_TICK
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/attack_ghost(mob/user)
|
||||
if(!user.client || !user.client.holder)
|
||||
return
|
||||
if(!IsAdminGhost(user))
|
||||
return ..()
|
||||
if(GLOB.servants_active)
|
||||
to_chat(user, "<span class='danger'>The Ark is already counting down.</span>")
|
||||
return
|
||||
return ..()
|
||||
if(alert(user, "Activate the Ark's countdown?", name, "Yes", "No") == "Yes")
|
||||
if(alert(user, "REALLY activate the Ark's countdown?", name, "Yes", "No") == "Yes")
|
||||
if(alert(user, "You're REALLY SURE? This cannot be undone.", name, "Yes - Activate the Ark", "No") == "Yes - Activate the Ark")
|
||||
message_admins("<span class='danger'>Admin [key_name_admin(user)] started the Ark's countdown!</span>")
|
||||
log_admin("Admin [key_name(user)] started the Ark's countdown on a non-clockcult mode!")
|
||||
to_chat(user, "<span class='userdanger'>The gamemode is now being treated as clockwork cult, and the Ark is counting down from 30 \
|
||||
minutes. You will need to create servant players yourself.</span>")
|
||||
final_countdown(35)
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
continue
|
||||
C.update_values()
|
||||
to_chat(C, C.empower_string)
|
||||
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
if(is_servant_of_ratvar(H))
|
||||
to_chat(H, "<span class='bold alloy'>The beacon's power warps your body into a clockwork form! You are now immune to many hazards, and your body is more robust against damage!</span>")
|
||||
H.set_species(/datum/species/golem/clockwork/no_scrap)
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
T.ratvar_act(TRUE)
|
||||
var/dir_to_step_in = pick(GLOB.cardinals)
|
||||
var/list/meals = list()
|
||||
for(var/mob/living/L in GLOB.living_mob_list) //we want to know who's alive so we don't lose and retarget a single person
|
||||
for(var/mob/living/L in GLOB.alive_mob_list) //we want to know who's alive so we don't lose and retarget a single person
|
||||
if(L.z == z && !is_servant_of_ratvar(L) && L.mind)
|
||||
meals += L
|
||||
if(GLOB.cult_narsie && GLOB.cult_narsie.z == z)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define CULT_SCALING_COEFFICIENT 9.3 //Roughly one new cultist at roundstart per this many players
|
||||
|
||||
/datum/game_mode
|
||||
var/list/datum/mind/cult = list()
|
||||
var/list/cult_objectives = list()
|
||||
@@ -64,7 +66,10 @@
|
||||
restricted_jobs += "Assistant"
|
||||
|
||||
//cult scaling goes here
|
||||
recommended_enemies = 3 + round(num_players()/15)
|
||||
recommended_enemies = 1 + round(num_players()/CULT_SCALING_COEFFICIENT)
|
||||
var/remaining = (num_players() % CULT_SCALING_COEFFICIENT) * 10 //Basically the % of how close the population is toward adding another cultis
|
||||
if(prob(remaining))
|
||||
recommended_enemies++
|
||||
|
||||
|
||||
for(var/cultists_number = 1 to recommended_enemies)
|
||||
@@ -256,6 +261,10 @@
|
||||
SSticker.news_report = CULT_FAILURE
|
||||
|
||||
text += "<br><B>Objective #[obj_count]</B>: [explanation]"
|
||||
if(cult.len)
|
||||
text += "<br><b>The cultists were:</b>"
|
||||
for(var/datum/mind/M in cult)
|
||||
text += printplayer(M)
|
||||
to_chat(world, text)
|
||||
..()
|
||||
return 1
|
||||
@@ -303,3 +312,5 @@
|
||||
SSticker.news_report = CULT_FAILURE
|
||||
text += "<br><B>Objective #[obj_count]</B>: [explanation]"
|
||||
to_chat(world, text)
|
||||
|
||||
#undef CULT_SCALING_COEFFICIENT
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
else if(!ishuman(user))
|
||||
title = "Construct"
|
||||
my_message = "<span class='[span]'><b>[title] [findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]:</b> [message]</span>"
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
for(var/i in GLOB.player_list)
|
||||
var/mob/M = i
|
||||
if(iscultist(M))
|
||||
to_chat(M, my_message)
|
||||
else if(M in GLOB.dead_mob_list)
|
||||
|
||||
@@ -324,7 +324,7 @@
|
||||
icon_state = "cult_armor"
|
||||
item_state = "cult_armor"
|
||||
desc = "A heavily-armored exosuit worn by warriors of the Nar-Sien cult. It can withstand hard vacuum."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
allowed = list(/obj/item/tome, /obj/item/melee/cultblade, /obj/item/tank/internals/)
|
||||
armor = list(melee = 70, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30, fire = 40, acid = 75)
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/cult
|
||||
|
||||
@@ -137,7 +137,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
for(var/M in invokers)
|
||||
var/mob/living/L = M
|
||||
if(invocation)
|
||||
L.say(invocation, language = /datum/language/common)
|
||||
L.say(invocation, language = /datum/language/common, ignore_spam = TRUE)
|
||||
if(invoke_damage)
|
||||
L.apply_damage(invoke_damage, BRUTE)
|
||||
to_chat(L, "<span class='cultitalic'>[src] saps your strength!</span>")
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
dat += "<HR>"
|
||||
for(var/s in possible_summons)
|
||||
var/datum/cult_supply/S = s
|
||||
dat += "<a href='?src=\ref[src];id=[initial(S.id)]'>[initial(S.invocation)]</a> - [initial(S.desc)]<br>"
|
||||
dat += "<a href='?src=[REF(src)];id=[initial(S.id)]'>[initial(S.invocation)]</a> - [initial(S.desc)]<br>"
|
||||
var/datum/browser/popup = new(user, "talisman", "", 400, 400)
|
||||
popup.set_content(dat.Join(""))
|
||||
popup.open()
|
||||
|
||||
@@ -225,8 +225,8 @@
|
||||
|
||||
/obj/item/paper/talisman/horror/afterattack(mob/living/target, mob/living/user)
|
||||
if(iscultist(user) && (get_dist(user, target) < 7))
|
||||
to_chat(user, "<span class='cultitalic'>You disturb [target] with visions of madness!</span>")
|
||||
if(iscarbon(target))
|
||||
to_chat(user, "<span class='cultitalic'>You disturb [target] with visions of madness!</span>")
|
||||
var/mob/living/carbon/H = target
|
||||
H.reagents.add_reagent("mindbreaker", 12)
|
||||
if(is_servant_of_ratvar(target))
|
||||
@@ -234,8 +234,7 @@
|
||||
target.emote("scream")
|
||||
target.confused = max(0, target.confused + 3)
|
||||
target.flash_act()
|
||||
qdel(src)
|
||||
|
||||
qdel(src)
|
||||
|
||||
//Talisman of Fabrication: Creates a construct shell out of 25 metal sheets, or converts plasteel into runed metal up to 25 times
|
||||
/obj/item/paper/talisman/construction
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/ascended = FALSE
|
||||
sight = (SEE_TURFS | SEE_OBJS)
|
||||
status_flags = CANPUSH
|
||||
spacewalk = TRUE
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
var/mob/living/oldform
|
||||
var/list/devil_overlays[DEVIL_TOTAL_LAYERS]
|
||||
@@ -135,9 +136,6 @@
|
||||
"<span class='userdanger'>[attack_message]</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/true_devil/Process_Spacemove(movement_dir = 0)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/true_devil/singularity_act()
|
||||
if(ascended)
|
||||
return 0
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
|
||||
replacementmode.restricted_jobs += "Assistant"
|
||||
|
||||
message_admins("The roundtype will be converted. If you have other plans for the station or feel the station is too messed up to inhabit <A HREF='?_src_=holder;[HrefToken()];toggle_midround_antag=\ref[usr]'>stop the creation of antags</A> or <A HREF='?_src_=holder;[HrefToken()];end_round=\ref[usr]'>end the round now</A>.")
|
||||
message_admins("The roundtype will be converted. If you have other plans for the station or feel the station is too messed up to inhabit <A HREF='?_src_=holder;[HrefToken()];toggle_midround_antag=[REF(usr)]'>stop the creation of antags</A> or <A HREF='?_src_=holder;[HrefToken()];end_round=[REF(usr)]'>end the round now</A>.")
|
||||
|
||||
. = 1
|
||||
sleep(rand(600,1800))
|
||||
@@ -217,7 +217,7 @@
|
||||
if(living_antag_player && living_antag_player.mind && isliving(living_antag_player) && living_antag_player.stat != DEAD && !isnewplayer(living_antag_player) &&!isbrain(living_antag_player))
|
||||
return 0 //A resource saver: once we find someone who has to die for all antags to be dead, we can just keep checking them, cycling over everyone only when we lose our mark.
|
||||
|
||||
for(var/mob/Player in GLOB.living_mob_list)
|
||||
for(var/mob/Player in GLOB.alive_mob_list)
|
||||
if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) &&!isbrain(Player) && Player.client)
|
||||
if(Player.mind.special_role || LAZYLEN(Player.mind.antag_datums)) //Someone's still antaging!
|
||||
living_antag_player = Player
|
||||
@@ -407,16 +407,11 @@
|
||||
//////////////////////////
|
||||
/proc/display_roundstart_logout_report()
|
||||
var/msg = "<span class='boldnotice'>Roundstart logout report\n\n</span>"
|
||||
for(var/mob/living/L in GLOB.mob_list)
|
||||
for(var/i in GLOB.mob_living_list)
|
||||
var/mob/living/L = i
|
||||
|
||||
if(L.ckey)
|
||||
var/found = 0
|
||||
for(var/client/C in GLOB.clients)
|
||||
if(C.ckey == L.ckey)
|
||||
found = 1
|
||||
break
|
||||
if(!found)
|
||||
msg += "<b>[L.name]</b> ([L.ckey]), the [L.job] (<font color='#ffcc00'><b>Disconnected</b></font>)\n"
|
||||
if(L.ckey && !GLOB.directory[L.ckey])
|
||||
msg += "<b>[L.name]</b> ([L.ckey]), the [L.job] (<font color='#ffcc00'><b>Disconnected</b></font>)\n"
|
||||
|
||||
|
||||
if(L.ckey && L.client)
|
||||
@@ -452,10 +447,8 @@
|
||||
continue //Ghosted while alive
|
||||
|
||||
|
||||
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
if(M.client && M.client.holder)
|
||||
to_chat(M, msg)
|
||||
for (var/C in GLOB.admins)
|
||||
to_chat(C, msg)
|
||||
|
||||
/datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck)
|
||||
var/text = "<br><b>[ply.key]</b> was <b>[ply.name]</b> the <b>[ply.assigned_role]</b> and"
|
||||
@@ -464,8 +457,10 @@
|
||||
text += " <span class='boldannounce'>died</span>"
|
||||
else
|
||||
text += " <span class='greenannounce'>survived</span>"
|
||||
if(fleecheck && (!(ply.current.z in GLOB.station_z_levels)))
|
||||
text += " while <span class='boldannounce'>fleeing the station</span>"
|
||||
if(fleecheck)
|
||||
var/turf/T = get_turf(ply.current)
|
||||
if(!T || !(T.z in GLOB.station_z_levels))
|
||||
text += " while <span class='boldannounce'>fleeing the station</span>"
|
||||
if(ply.current.real_name != ply.name)
|
||||
text += " as <b>[ply.current.real_name]</b>"
|
||||
else
|
||||
@@ -533,4 +528,4 @@
|
||||
//By default nuke just ends the round
|
||||
/datum/game_mode/proc/OnNukeExplosion(off_station)
|
||||
if(off_station < 2)
|
||||
station_was_nuked = TRUE //Will end the round on next check.
|
||||
station_was_nuked = TRUE //Will end the round on next check.
|
||||
|
||||
@@ -133,9 +133,9 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
dat += "<B>Install Module:</B><BR>"
|
||||
dat += "<I>The number afterwards is the amount of processing time it consumes.</I><BR>"
|
||||
for(var/datum/AI_Module/large/module in possible_modules)
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A><A href='byond://?src=\ref[src];showdesc=[module.mod_pick_name]'>\[?\]</A> ([module.cost])<BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];[module.mod_pick_name]=1'>[module.module_name]</A><A href='byond://?src=[REF(src)];showdesc=[module.mod_pick_name]'>\[?\]</A> ([module.cost])<BR>"
|
||||
for(var/datum/AI_Module/small/module in possible_modules)
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A><A href='byond://?src=\ref[src];showdesc=[module.mod_pick_name]'>\[?\]</A> ([module.cost])<BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];[module.mod_pick_name]=1'>[module.module_name]</A><A href='byond://?src=[REF(src)];showdesc=[module.mod_pick_name]'>\[?\]</A> ([module.cost])<BR>"
|
||||
dat += "<HR>"
|
||||
if(temp)
|
||||
dat += "[temp]"
|
||||
@@ -375,7 +375,8 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
/obj/machinery/doomsday_device/proc/detonate(z_level = ZLEVEL_STATION_PRIMARY)
|
||||
sound_to_playing_players('sound/machines/alarm.ogg')
|
||||
sleep(100)
|
||||
for(var/mob/living/L in GLOB.mob_list)
|
||||
for(var/i in GLOB.mob_living_list)
|
||||
var/mob/living/L = i
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T || !(T.z in GLOB.station_z_levels))
|
||||
continue
|
||||
@@ -679,7 +680,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
C.images -= I
|
||||
|
||||
/mob/living/silicon/ai/proc/can_place_transformer(datum/action/innate/ai/place_transformer/action)
|
||||
if(!eyeobj || !isturf(loc) || !canUseTopic() || !action)
|
||||
if(!eyeobj || !isturf(loc) || incapacitated() || !action)
|
||||
return
|
||||
var/turf/middle = get_turf(eyeobj)
|
||||
var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z))
|
||||
|
||||
@@ -477,7 +477,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
species = "<span class='notice'>[H.dna.species.name]</span>"
|
||||
if(L.mind && L.mind.changeling)
|
||||
if(L.mind && L.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
species = "<span class='warning'>Changeling lifeform</span>"
|
||||
var/obj/item/organ/heart/gland/temp = locate() in H.internal_organs
|
||||
if(temp)
|
||||
|
||||
@@ -43,20 +43,20 @@
|
||||
dat += "Collected Samples : [points] <br>"
|
||||
dat += "Gear Credits: [credits] <br>"
|
||||
dat += "<b>Transfer data in exchange for supplies:</b><br>"
|
||||
dat += "<a href='?src=\ref[src];dispense=baton'>Advanced Baton</A><br>"
|
||||
dat += "<a href='?src=\ref[src];dispense=helmet'>Agent Helmet</A><br>"
|
||||
dat += "<a href='?src=\ref[src];dispense=vest'>Agent Vest</A><br>"
|
||||
dat += "<a href='?src=\ref[src];dispense=silencer'>Radio Silencer</A><br>"
|
||||
dat += "<a href='?src=\ref[src];dispense=tool'>Science Tool</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=baton'>Advanced Baton</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=helmet'>Agent Helmet</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=vest'>Agent Vest</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=silencer'>Radio Silencer</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];dispense=tool'>Science Tool</A><br>"
|
||||
else
|
||||
dat += "<span class='bad'>NO EXPERIMENT MACHINE DETECTED</span> <br>"
|
||||
|
||||
if(pad)
|
||||
dat += "<span class='bad'>Emergency Teleporter System.</span>"
|
||||
dat += "<span class='bad'>Consider using primary observation console first.</span>"
|
||||
dat += "<a href='?src=\ref[src];teleporter_send=1'>Activate Teleporter</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];teleporter_send=1'>Activate Teleporter</A><br>"
|
||||
if(gizmo && gizmo.marked)
|
||||
dat += "<a href='?src=\ref[src];teleporter_retrieve=1'>Retrieve Mark</A><br>"
|
||||
dat += "<a href='?src=[REF(src)];teleporter_retrieve=1'>Retrieve Mark</A><br>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Retrieve Mark</span><br>"
|
||||
else
|
||||
@@ -66,15 +66,15 @@
|
||||
dat += "<h4> Agent Vest Mode </h4><br>"
|
||||
var/mode = vest.mode
|
||||
if(mode == VEST_STEALTH)
|
||||
dat += "<a href='?src=\ref[src];flip_vest=1'>Combat</A>"
|
||||
dat += "<a href='?src=[REF(src)];flip_vest=1'>Combat</A>"
|
||||
dat += "<span class='linkOff'>Stealth</span>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Combat</span>"
|
||||
dat += "<a href='?src=\ref[src];flip_vest=1'>Stealth</A>"
|
||||
dat += "<a href='?src=[REF(src)];flip_vest=1'>Stealth</A>"
|
||||
|
||||
dat+="<br>"
|
||||
dat += "<a href='?src=\ref[src];select_disguise=1'>Select Agent Vest Disguise</a><br>"
|
||||
dat += "<a href='?src=\ref[src];toggle_vest=1'>[vest.flags_1 & NODROP_1 ? "Unlock" : "Lock"] Vest</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];select_disguise=1'>Select Agent Vest Disguise</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];toggle_vest=1'>[vest.flags_1 & NODROP_1 ? "Unlock" : "Lock"] Vest</a><br>"
|
||||
else
|
||||
dat += "<span class='bad'>NO AGENT VEST DETECTED</span>"
|
||||
var/datum/browser/popup = new(user, "computer", "Abductor Console", 400, 500)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
item_count++
|
||||
var/g_color = gland_colors[i]
|
||||
var/amount = amounts[i]
|
||||
dat += "<a class='box gland' style='background-color:[g_color]' href='?src=\ref[src];dispense=[i]'>[amount]</a>"
|
||||
dat += "<a class='box gland' style='background-color:[g_color]' href='?src=[REF(src)];dispense=[i]'>[amount]</a>"
|
||||
if(item_count == 4) // Four boxes per line
|
||||
dat +="</br></br>"
|
||||
item_count = 0
|
||||
|
||||
@@ -104,9 +104,9 @@
|
||||
dat += "<table><tr><td>"
|
||||
dat += "<img src=dissection_img height=80 width=80>" //Avert your eyes
|
||||
dat += "</td><td>"
|
||||
dat += "<a href='?src=\ref[src];experiment=1'>Probe</a><br>"
|
||||
dat += "<a href='?src=\ref[src];experiment=2'>Dissect</a><br>"
|
||||
dat += "<a href='?src=\ref[src];experiment=3'>Analyze</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];experiment=1'>Probe</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];experiment=2'>Dissect</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];experiment=3'>Analyze</a><br>"
|
||||
dat += "</td></tr></table>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Experiment </span>"
|
||||
@@ -127,8 +127,8 @@
|
||||
dat += "<br>"
|
||||
dat += "[flash]"
|
||||
dat += "<br>"
|
||||
dat += "<a href='?src=\ref[src];refresh=1'>Scan</a>"
|
||||
dat += "<a href='?src=\ref[src];[state_open ? "close=1'>Close</a>" : "open=1'>Open</a>"]"
|
||||
dat += "<a href='?src=[REF(src)];refresh=1'>Scan</a>"
|
||||
dat += "<a href='?src=[REF(src)];[state_open ? "close=1'>Close</a>" : "open=1'>Open</a>"]"
|
||||
var/datum/browser/popup = new(user, "experiment", "Probing Console", 300, 300)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.set_content(dat)
|
||||
|
||||
@@ -654,7 +654,8 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/proc/swarmer_chat(msg)
|
||||
var/rendered = "<B>Swarm communication - [src]</b> [say_quote(msg, get_spans())]"
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
for(var/i in GLOB.mob_list)
|
||||
var/mob/M = i
|
||||
if(isswarmer(M))
|
||||
to_chat(M, rendered)
|
||||
if(isobserver(M))
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
print_command_report(swarmer_report, announce=TRUE)
|
||||
|
||||
/datum/round_event/spawn_swarmer/proc/find_swarmer()
|
||||
for(var/mob/living/M in GLOB.mob_list)
|
||||
if(istype(M, /mob/living/simple_animal/hostile/swarmer) && M.client) //If there is a swarmer with an active client, we've found our swarmer
|
||||
for(var/i in GLOB.mob_living_list)
|
||||
var/mob/living/L = i
|
||||
if(istype(L, /mob/living/simple_animal/hostile/swarmer) && L.client) //If there is a swarmer with an active client, we've found our swarmer
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
return 0
|
||||
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever() //ugly but unfortunately needed
|
||||
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
if(H.mind && H.stat != DEAD)
|
||||
if(H.HasDisease(D))
|
||||
return 0
|
||||
@@ -87,7 +87,7 @@
|
||||
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
||||
return 0
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
|
||||
for(var/mob/living/carbon/monkey/M in GLOB.living_mob_list)
|
||||
for(var/mob/living/carbon/monkey/M in GLOB.alive_mob_list)
|
||||
if (M.HasDisease(D))
|
||||
if(M.onCentCom() || M.onSyndieBase())
|
||||
escaped_monkeys++
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
maxHealth = INFINITY
|
||||
layer = GHOST_LAYER
|
||||
healable = FALSE
|
||||
spacewalk = TRUE
|
||||
sight = SEE_SELF
|
||||
|
||||
see_in_dark = 8
|
||||
@@ -153,8 +154,6 @@
|
||||
|
||||
|
||||
//Immunities
|
||||
/mob/living/simple_animal/revenant/Process_Spacemove(movement_dir = 0)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/revenant/ex_act(severity, target)
|
||||
return 1 //Immune to the effects of explosions.
|
||||
|
||||
@@ -91,9 +91,11 @@
|
||||
var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge
|
||||
synd_mind.current.put_in_hands(challenge, TRUE)
|
||||
|
||||
var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/card/id)
|
||||
var/static/id_cache = typecacheof(/obj/item/card/id)
|
||||
var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache)
|
||||
if(foundIDs.len)
|
||||
for(var/obj/item/card/id/ID in foundIDs)
|
||||
for(var/i in 1 to foundIDs.len)
|
||||
var/obj/item/card/id/ID = foundIDs[i]
|
||||
ID.name = "lead agent card"
|
||||
ID.access += ACCESS_SYNDICATE_LEADER
|
||||
else
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
icon = 'icons/obj/machines/nuke_terminal.dmi'
|
||||
icon_state = "nuclearbomb_base"
|
||||
anchored = TRUE //stops it being moved
|
||||
use_tag = TRUE
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate
|
||||
//ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb
|
||||
@@ -121,15 +122,7 @@
|
||||
to_chat(user, "<span class='notice'>You remove the screws from [src]'s front panel.</span>")
|
||||
update_icon()
|
||||
return
|
||||
if(NUKESTATE_UNSCREWED)
|
||||
if(istype(I, /obj/item/crowbar))
|
||||
to_chat(user, "<span class='notice'>You start removing [src]'s front panel...</span>")
|
||||
playsound(loc, I.usesound, 100, 1)
|
||||
if(do_after(user,30*I.toolspeed,target=src))
|
||||
to_chat(user, "<span class='notice'>You remove [src]'s front panel.</span>")
|
||||
deconstruction_state = NUKESTATE_PANEL_REMOVED
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(NUKESTATE_PANEL_REMOVED)
|
||||
if(istype(I, /obj/item/weldingtool))
|
||||
var/obj/item/weldingtool/welder = I
|
||||
@@ -141,16 +134,6 @@
|
||||
deconstruction_state = NUKESTATE_WELDED
|
||||
update_icon()
|
||||
return
|
||||
if(NUKESTATE_WELDED)
|
||||
if(istype(I, /obj/item/crowbar))
|
||||
to_chat(user, "<span class='notice'>You start prying off [src]'s inner plate...</span>")
|
||||
playsound(loc, I.usesound, 100, 1)
|
||||
if(do_after(user,50*I.toolspeed,target=src))
|
||||
to_chat(user, "<span class='notice'>You pry off [src]'s inner plate. You can see the core's green glow!</span>")
|
||||
deconstruction_state = NUKESTATE_CORE_EXPOSED
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, core)
|
||||
return
|
||||
if(NUKESTATE_CORE_EXPOSED)
|
||||
if(istype(I, /obj/item/nuke_core_container))
|
||||
var/obj/item/nuke_core_container/core_box = I
|
||||
@@ -181,6 +164,27 @@
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/nuclearbomb/crowbar_act(mob/user, obj/item/tool)
|
||||
. = FALSE
|
||||
switch(deconstruction_state)
|
||||
if(NUKESTATE_UNSCREWED)
|
||||
to_chat(user, "<span class='notice'>You start removing [src]'s front panel...</span>")
|
||||
playsound(loc, tool.usesound, 100, 1)
|
||||
if(do_after(user, 30 * tool.toolspeed, target = src))
|
||||
to_chat(user, "<span class='notice'>You remove [src]'s front panel.</span>")
|
||||
deconstruction_state = NUKESTATE_PANEL_REMOVED
|
||||
update_icon()
|
||||
return TRUE
|
||||
if(NUKESTATE_WELDED)
|
||||
to_chat(user, "<span class='notice'>You start prying off [src]'s inner plate...</span>")
|
||||
playsound(loc, tool.usesound, 100, 1)
|
||||
if(do_after(user, 50 * tool.toolspeed, target = src))
|
||||
to_chat(user, "<span class='notice'>You pry off [src]'s inner plate. You can see the core's green glow!</span>")
|
||||
deconstruction_state = NUKESTATE_CORE_EXPOSED
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, core)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/get_nuke_state()
|
||||
if(exploding)
|
||||
return NUKE_ON_EXPLODING
|
||||
|
||||
@@ -586,7 +586,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
n_p ++
|
||||
else if (SSticker.IsRoundInProgress())
|
||||
for(var/mob/living/carbon/human/P in GLOB.player_list)
|
||||
if(P.client && !(P.mind in SSticker.mode.changelings) && !(P.mind in owners))
|
||||
if(P.client && !(P.mind.has_antag_datum(/datum/antagonist/changeling)) && !(P.mind in owners))
|
||||
n_p ++
|
||||
target_amount = min(target_amount, n_p)
|
||||
|
||||
@@ -597,9 +597,12 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
var/list/datum/mind/owners = get_owners()
|
||||
var/absorbedcount = 0
|
||||
for(var/datum/mind/M in owners)
|
||||
if(!owner || !owner.changeling || !owner.changeling.stored_profiles)
|
||||
if(!M)
|
||||
continue
|
||||
absorbedcount += M.changeling.absorbedcount
|
||||
var/datum/antagonist/changeling/changeling = M.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!changeling || !changeling.stored_profiles)
|
||||
continue
|
||||
absorbedcount += changeling.absorbedcount
|
||||
return absorbedcount >= target_amount
|
||||
|
||||
|
||||
@@ -696,10 +699,11 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
if("Chief Medical Officer")
|
||||
department_string = "medical"
|
||||
|
||||
var/ling_count = SSticker.mode.changelings
|
||||
var/list/lings = get_antagonists(/datum/antagonist/changeling,TRUE)
|
||||
var/ling_count = lings.len
|
||||
|
||||
for(var/datum/mind/M in SSticker.minds)
|
||||
if(M in SSticker.mode.changelings)
|
||||
if(M in lings)
|
||||
continue
|
||||
if(department_head in get_department_heads(M.assigned_role))
|
||||
if(ling_count)
|
||||
@@ -723,13 +727,13 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
//Needed heads is between min_lings and the maximum possible amount of command roles
|
||||
//So at the time of writing, rand(3,6), it's also capped by the amount of lings there are
|
||||
//Because you can't fill 6 head roles with 3 lings
|
||||
|
||||
var/list/lings = get_antagonists(/datum/antagonist/changeling,TRUE)
|
||||
var/needed_heads = rand(min_lings,GLOB.command_positions.len)
|
||||
needed_heads = min(SSticker.mode.changelings.len,needed_heads)
|
||||
needed_heads = min(lings.len,needed_heads)
|
||||
|
||||
var/list/heads = SSjob.get_living_heads()
|
||||
for(var/datum/mind/head in heads)
|
||||
if(head in SSticker.mode.changelings) //Looking at you HoP.
|
||||
if(head in lings) //Looking at you HoP.
|
||||
continue
|
||||
if(needed_heads)
|
||||
department_minds += head
|
||||
@@ -789,7 +793,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
|
||||
//Check each department member's mind to see if any of them made it to centcom alive, if they did it's an automatic fail
|
||||
for(var/datum/mind/M in department_minds)
|
||||
if(M in SSticker.mode.changelings) //Lings aren't picked for this, but let's be safe
|
||||
if(M.has_antag_datum(/datum/antagonist/changeling)) //Lings aren't picked for this, but let's be safe
|
||||
continue
|
||||
|
||||
if(M.current)
|
||||
@@ -800,7 +804,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
//Check each staff member has been replaced, by cross referencing changeling minds, changeling current dna, the staff minds and their original DNA names
|
||||
var/success = 0
|
||||
changelings:
|
||||
for(var/datum/mind/changeling in SSticker.mode.changelings)
|
||||
for(var/datum/mind/changeling in get_antagonists(/datum/antagonist/changeling,TRUE))
|
||||
if(success >= department_minds.len) //We did it, stop here!
|
||||
return 1
|
||||
if(ishuman(changeling.current))
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
if(headrevs.len)
|
||||
var/num_revs = 0
|
||||
var/num_survivors = 0
|
||||
for(var/mob/living/carbon/survivor in GLOB.living_mob_list)
|
||||
for(var/mob/living/carbon/survivor in GLOB.alive_mob_list)
|
||||
if(survivor.ckey)
|
||||
num_survivors++
|
||||
if(survivor.mind)
|
||||
|
||||
@@ -1,139 +1,139 @@
|
||||
/*
|
||||
This is for the sandbox for now,
|
||||
maybe useful later for an actual thing?
|
||||
-Sayu
|
||||
*/
|
||||
|
||||
/obj/structure/door_assembly
|
||||
var/datum/airlock_maker/maker = null
|
||||
|
||||
/obj/structure/door_assembly/attack_hand()
|
||||
..()
|
||||
if(maker)
|
||||
maker.interact()
|
||||
|
||||
/datum/airlock_maker
|
||||
var/obj/structure/door_assembly/linked = null
|
||||
|
||||
var/list/access_used = null
|
||||
var/require_all = 1
|
||||
|
||||
var/paintjob = "none"
|
||||
var/glassdoor = 0
|
||||
|
||||
var/doorname = "airlock"
|
||||
|
||||
/datum/airlock_maker/New(var/atom/target_loc)
|
||||
linked = new(target_loc)
|
||||
linked.maker = src
|
||||
linked.anchored = FALSE
|
||||
access_used = list()
|
||||
|
||||
interact()
|
||||
|
||||
/datum/airlock_maker/proc/linkpretty(href,desc,active)
|
||||
if(!desc)
|
||||
var/static/list/defaults = list("No","Yes")
|
||||
desc = defaults[active+1]
|
||||
if(active)
|
||||
return "<a href='?src=\ref[src];[href]'><b>[desc]</b></a>"
|
||||
return "<a href='?src=\ref[src];[href]'><i>[desc]</i></a>"
|
||||
|
||||
/datum/airlock_maker/proc/interact()
|
||||
var/list/leftcolumn = list()
|
||||
var/list/rightcolumn = list()
|
||||
leftcolumn += "<u><b>Required Access</b></u>"
|
||||
for(var/access in get_all_accesses())
|
||||
leftcolumn += linkpretty("access=[access]",get_access_desc(access),access in access_used)
|
||||
leftcolumn += "Require all listed accesses: [linkpretty("reqall",null,require_all)]"
|
||||
|
||||
rightcolumn += "<u><b>Paintjob</b></u>"
|
||||
for(var/option in list("none","engineering","atmos","security","command","medical","research","mining","maintenance","external","highsecurity"))
|
||||
rightcolumn += linkpretty("paint=[option]",option,option == paintjob)
|
||||
rightcolumn += "Glass door: " + linkpretty("glass",null,glassdoor) + "<br><br>"
|
||||
var/length = max(leftcolumn.len,rightcolumn.len)
|
||||
|
||||
var/dat = "You may move the model airlock around. A new airlock will be built in its space when you click done, below.<hr><br>"
|
||||
dat += "<a href='?src=\ref[src];rename'>Door name</a>: \"[doorname]\""
|
||||
dat += "<table>"
|
||||
for(var/i=1; i<=length; i++)
|
||||
dat += "<tr><td>"
|
||||
if(i<=leftcolumn.len)
|
||||
dat += leftcolumn[i]
|
||||
dat += "</td><td>"
|
||||
if(i<=rightcolumn.len)
|
||||
dat += rightcolumn[i]
|
||||
dat += "</td></tr>"
|
||||
|
||||
dat += "</table><hr><a href='?src=\ref[src];done'>Finalize Airlock Construction</a> | <a href='?src=\ref[src];cancel'>Cancel and Destroy Airlock</a>"
|
||||
usr << browse(dat,"window=airlockmaker")
|
||||
|
||||
/datum/airlock_maker/Topic(var/href,var/list/href_list)
|
||||
if(!usr)
|
||||
return
|
||||
if(!src || !linked || !linked.loc)
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
return
|
||||
|
||||
if("rename" in href_list)
|
||||
var/newname = stripped_input(usr,"New airlock name:","Name the airlock",doorname)
|
||||
if(newname)
|
||||
doorname = newname
|
||||
if("access" in href_list)
|
||||
var/value = text2num(href_list["access"])
|
||||
access_used ^= value
|
||||
if("reqall" in href_list)
|
||||
require_all = !require_all
|
||||
if("paint" in href_list)
|
||||
paintjob = href_list["paint"]
|
||||
if("glass" in href_list)
|
||||
glassdoor = !glassdoor
|
||||
|
||||
if("cancel" in href_list)
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
qdel(linked)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if("done" in href_list)
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
var/turf/t_loc = linked.loc
|
||||
qdel(linked)
|
||||
if(!istype(t_loc))
|
||||
return
|
||||
|
||||
var/target_type = "/obj/machinery/door/airlock"
|
||||
if(glassdoor)
|
||||
if(paintjob != "none")
|
||||
if(paintjob in list("external","highsecurity","maintenance")) // no glass version
|
||||
target_type += "/[paintjob]"
|
||||
else
|
||||
target_type += "/glass_[paintjob]"
|
||||
else
|
||||
target_type += "/glass"
|
||||
else if(paintjob != "none")
|
||||
target_type += "/[paintjob]"
|
||||
var/final = target_type
|
||||
target_type = text2path(final)
|
||||
if(!target_type)
|
||||
to_chat(usr, "Didn't work, contact Sayu with this: [final]")
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
return
|
||||
|
||||
var/obj/machinery/door/D = new target_type(t_loc)
|
||||
|
||||
D.name = doorname
|
||||
|
||||
if(access_used.len == 0)
|
||||
D.req_access = null
|
||||
D.req_one_access = null
|
||||
else if(require_all)
|
||||
D.req_access = access_used.Copy()
|
||||
D.req_one_access = null
|
||||
else
|
||||
D.req_access = null
|
||||
D.req_one_access = access_used.Copy()
|
||||
|
||||
return
|
||||
|
||||
interact()
|
||||
/*
|
||||
This is for the sandbox for now,
|
||||
maybe useful later for an actual thing?
|
||||
-Sayu
|
||||
*/
|
||||
|
||||
/obj/structure/door_assembly
|
||||
var/datum/airlock_maker/maker = null
|
||||
|
||||
/obj/structure/door_assembly/attack_hand()
|
||||
..()
|
||||
if(maker)
|
||||
maker.interact()
|
||||
|
||||
/datum/airlock_maker
|
||||
var/obj/structure/door_assembly/linked = null
|
||||
|
||||
var/list/access_used = null
|
||||
var/require_all = 1
|
||||
|
||||
var/paintjob = "none"
|
||||
var/glassdoor = 0
|
||||
|
||||
var/doorname = "airlock"
|
||||
|
||||
/datum/airlock_maker/New(var/atom/target_loc)
|
||||
linked = new(target_loc)
|
||||
linked.maker = src
|
||||
linked.anchored = FALSE
|
||||
access_used = list()
|
||||
|
||||
interact()
|
||||
|
||||
/datum/airlock_maker/proc/linkpretty(href,desc,active)
|
||||
if(!desc)
|
||||
var/static/list/defaults = list("No","Yes")
|
||||
desc = defaults[active+1]
|
||||
if(active)
|
||||
return "<a href='?src=[REF(src)];[href]'><b>[desc]</b></a>"
|
||||
return "<a href='?src=[REF(src)];[href]'><i>[desc]</i></a>"
|
||||
|
||||
/datum/airlock_maker/proc/interact()
|
||||
var/list/leftcolumn = list()
|
||||
var/list/rightcolumn = list()
|
||||
leftcolumn += "<u><b>Required Access</b></u>"
|
||||
for(var/access in get_all_accesses())
|
||||
leftcolumn += linkpretty("access=[access]",get_access_desc(access),access in access_used)
|
||||
leftcolumn += "Require all listed accesses: [linkpretty("reqall",null,require_all)]"
|
||||
|
||||
rightcolumn += "<u><b>Paintjob</b></u>"
|
||||
for(var/option in list("none","engineering","atmos","security","command","medical","research","mining","maintenance","external","highsecurity"))
|
||||
rightcolumn += linkpretty("paint=[option]",option,option == paintjob)
|
||||
rightcolumn += "Glass door: " + linkpretty("glass",null,glassdoor) + "<br><br>"
|
||||
var/length = max(leftcolumn.len,rightcolumn.len)
|
||||
|
||||
var/dat = "You may move the model airlock around. A new airlock will be built in its space when you click done, below.<hr><br>"
|
||||
dat += "<a href='?src=[REF(src)];rename'>Door name</a>: \"[doorname]\""
|
||||
dat += "<table>"
|
||||
for(var/i=1; i<=length; i++)
|
||||
dat += "<tr><td>"
|
||||
if(i<=leftcolumn.len)
|
||||
dat += leftcolumn[i]
|
||||
dat += "</td><td>"
|
||||
if(i<=rightcolumn.len)
|
||||
dat += rightcolumn[i]
|
||||
dat += "</td></tr>"
|
||||
|
||||
dat += "</table><hr><a href='?src=[REF(src)];done'>Finalize Airlock Construction</a> | <a href='?src=[REF(src)];cancel'>Cancel and Destroy Airlock</a>"
|
||||
usr << browse(dat,"window=airlockmaker")
|
||||
|
||||
/datum/airlock_maker/Topic(var/href,var/list/href_list)
|
||||
if(!usr)
|
||||
return
|
||||
if(!src || !linked || !linked.loc)
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
return
|
||||
|
||||
if("rename" in href_list)
|
||||
var/newname = stripped_input(usr,"New airlock name:","Name the airlock",doorname)
|
||||
if(newname)
|
||||
doorname = newname
|
||||
if("access" in href_list)
|
||||
var/value = text2num(href_list["access"])
|
||||
access_used ^= value
|
||||
if("reqall" in href_list)
|
||||
require_all = !require_all
|
||||
if("paint" in href_list)
|
||||
paintjob = href_list["paint"]
|
||||
if("glass" in href_list)
|
||||
glassdoor = !glassdoor
|
||||
|
||||
if("cancel" in href_list)
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
qdel(linked)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if("done" in href_list)
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
var/turf/t_loc = linked.loc
|
||||
qdel(linked)
|
||||
if(!istype(t_loc))
|
||||
return
|
||||
|
||||
var/target_type = "/obj/machinery/door/airlock"
|
||||
if(glassdoor)
|
||||
if(paintjob != "none")
|
||||
if(paintjob in list("external","highsecurity","maintenance")) // no glass version
|
||||
target_type += "/[paintjob]"
|
||||
else
|
||||
target_type += "/glass_[paintjob]"
|
||||
else
|
||||
target_type += "/glass"
|
||||
else if(paintjob != "none")
|
||||
target_type += "/[paintjob]"
|
||||
var/final = target_type
|
||||
target_type = text2path(final)
|
||||
if(!target_type)
|
||||
to_chat(usr, "Didn't work, contact Sayu with this: [final]")
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
return
|
||||
|
||||
var/obj/machinery/door/D = new target_type(t_loc)
|
||||
|
||||
D.name = doorname
|
||||
|
||||
if(access_used.len == 0)
|
||||
D.req_access = null
|
||||
D.req_one_access = null
|
||||
else if(require_all)
|
||||
D.req_access = access_used.Copy()
|
||||
D.req_one_access = null
|
||||
else
|
||||
D.req_access = null
|
||||
D.req_one_access = access_used.Copy()
|
||||
|
||||
return
|
||||
|
||||
interact()
|
||||
|
||||
@@ -77,26 +77,26 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE)
|
||||
hsbinfo = "<center><b>Sandbox Panel</b></center><hr>"
|
||||
if(admin)
|
||||
hsbinfo += "<b>Administration</b><br>"
|
||||
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtobj'>Toggle Object Spawning</a><br>"
|
||||
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtac'>Toggle Item Spawn Panel Auto-close</a><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbtobj'>Toggle Object Spawning</a><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbtac'>Toggle Item Spawn Panel Auto-close</a><br>"
|
||||
hsbinfo += "<b>Canister Spawning</b><br>"
|
||||
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/toxins]'>Spawn Plasma Canister</a><br>"
|
||||
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/carbon_dioxide]'>Spawn CO2 Canister</a><br>"
|
||||
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrogen]'>Spawn Nitrogen Canister</a><br>"
|
||||
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrous_oxide]'>Spawn N2O Canister</a><hr>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/toxins]'>Spawn Plasma Canister</a><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/carbon_dioxide]'>Spawn CO2 Canister</a><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrogen]'>Spawn Nitrogen Canister</a><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrous_oxide]'>Spawn N2O Canister</a><hr>"
|
||||
else
|
||||
hsbinfo += "<i>Some item spawning may be disabled by the administrators.</i><br>"
|
||||
hsbinfo += "<i>Only administrators may spawn dangerous canisters.</i><br>"
|
||||
for(var/T in hrefs)
|
||||
var/href = hrefs[T]
|
||||
if(href)
|
||||
hsbinfo += "- <a href='?\ref[src];hsb=[hrefs[T]]'>[T]</a><br>"
|
||||
hsbinfo += "- <a href='?[REF(src)];hsb=[hrefs[T]]'>[T]</a><br>"
|
||||
else
|
||||
hsbinfo += "<br><b>[T]</b><br>"
|
||||
hsbinfo += "<hr>"
|
||||
hsbinfo += "- <a href='?\ref[src];hsb=hsbcloth'>Spawn Clothing...</a><br>"
|
||||
hsbinfo += "- <a href='?\ref[src];hsb=hsbreag'>Spawn Reagent Container...</a><br>"
|
||||
hsbinfo += "- <a href='?\ref[src];hsb=hsbobj'>Spawn Other Item...</a><br><br>"
|
||||
hsbinfo += "- <a href='?[REF(src)];hsb=hsbcloth'>Spawn Clothing...</a><br>"
|
||||
hsbinfo += "- <a href='?[REF(src)];hsb=hsbreag'>Spawn Reagent Container...</a><br>"
|
||||
hsbinfo += "- <a href='?[REF(src)];hsb=hsbobj'>Spawn Other Item...</a><br><br>"
|
||||
|
||||
usr << browse(hsbinfo, "window=hsbpanel")
|
||||
|
||||
@@ -235,12 +235,12 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE)
|
||||
if(!GLOB.hsboxspawn) return
|
||||
|
||||
if(!clothinfo)
|
||||
clothinfo = "<b>Clothing</b> <a href='?\ref[src];hsb=hsbreag'>(Reagent Containers)</a> <a href='?\ref[src];hsb=hsbobj'>(Other Items)</a><hr><br>"
|
||||
clothinfo = "<b>Clothing</b> <a href='?[REF(src)];hsb=hsbreag'>(Reagent Containers)</a> <a href='?[REF(src)];hsb=hsbobj'>(Other Items)</a><hr><br>"
|
||||
var/list/all_items = subtypesof(/obj/item/clothing)
|
||||
for(var/typekey in spawn_forbidden)
|
||||
all_items -= typesof(typekey)
|
||||
for(var/O in reverseRange(all_items))
|
||||
clothinfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
|
||||
clothinfo += "<a href='?src=[REF(src)];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
|
||||
|
||||
usr << browse(clothinfo,"window=sandbox")
|
||||
|
||||
@@ -249,12 +249,12 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE)
|
||||
if(!GLOB.hsboxspawn) return
|
||||
|
||||
if(!reaginfo)
|
||||
reaginfo = "<b>Reagent Containers</b> <a href='?\ref[src];hsb=hsbcloth'>(Clothing)</a> <a href='?\ref[src];hsb=hsbobj'>(Other Items)</a><hr><br>"
|
||||
reaginfo = "<b>Reagent Containers</b> <a href='?[REF(src)];hsb=hsbcloth'>(Clothing)</a> <a href='?[REF(src)];hsb=hsbobj'>(Other Items)</a><hr><br>"
|
||||
var/list/all_items = subtypesof(/obj/item/reagent_containers)
|
||||
for(var/typekey in spawn_forbidden)
|
||||
all_items -= typesof(typekey)
|
||||
for(var/O in reverseRange(all_items))
|
||||
reaginfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
|
||||
reaginfo += "<a href='?src=[REF(src)];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
|
||||
|
||||
usr << browse(reaginfo,"window=sandbox")
|
||||
|
||||
@@ -263,13 +263,13 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE)
|
||||
if(!GLOB.hsboxspawn) return
|
||||
|
||||
if(!objinfo)
|
||||
objinfo = "<b>Other Items</b> <a href='?\ref[src];hsb=hsbcloth'>(Clothing)</a> <a href='?\ref[src];hsb=hsbreag'>(Reagent Containers)</a><hr><br>"
|
||||
objinfo = "<b>Other Items</b> <a href='?[REF(src)];hsb=hsbcloth'>(Clothing)</a> <a href='?[REF(src)];hsb=hsbreag'>(Reagent Containers)</a><hr><br>"
|
||||
var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers)
|
||||
for(var/typekey in spawn_forbidden)
|
||||
all_items -= typesof(typekey)
|
||||
|
||||
for(var/O in reverseRange(all_items))
|
||||
objinfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
|
||||
objinfo += "<a href='?src=[REF(src)];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
|
||||
|
||||
usr << browse(objinfo,"window=sandbox")
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
/datum/game_mode/traitor/proc/add_latejoin_traitor(datum/mind/character)
|
||||
var/datum/antagonist/traitor/new_antag = new antag_datum(character)
|
||||
new_antag.should_specialise = TRUE
|
||||
character.add_antag_datum(antag_datum)
|
||||
character.add_antag_datum(new_antag)
|
||||
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
else
|
||||
text += "<br><font color='red'><B>The [special_role_text] has failed!</B></font>"
|
||||
SSblackbox.add_details("traitor_success","FAIL")
|
||||
SEND_SOUND(traitor.current, 'sound/ambience/ambifailure.ogg')
|
||||
|
||||
text += "<br>"
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@
|
||||
possible = list()
|
||||
if(!link)
|
||||
return
|
||||
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
if(md5(H.dna.uni_identity) in link.fingerprints)
|
||||
possible |= H
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
/proc/makeNewConstruct(mob/living/simple_animal/hostile/construct/ctype, mob/target, mob/stoner = null, cultoverride = 0, loc_override = null)
|
||||
var/mob/living/simple_animal/hostile/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target)))
|
||||
if(stoner)
|
||||
newstruct.faction |= "\ref[stoner]"
|
||||
newstruct.faction |= "[REF(stoner)]"
|
||||
newstruct.master = stoner
|
||||
var/datum/action/innate/seek_master/SM = new()
|
||||
SM.Grant(newstruct)
|
||||
@@ -244,7 +244,7 @@
|
||||
S.key = T.key
|
||||
S.language_holder = U.language_holder.copy(S)
|
||||
if(U)
|
||||
S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation
|
||||
S.faction |= "[REF(U)]" //Add the master as a faction, allowing inter-mob cooperation
|
||||
if(U && iscultist(U))
|
||||
SSticker.mode.add_cultist(S.mind, 0)
|
||||
S.cancel_camera()
|
||||
|
||||
@@ -425,7 +425,7 @@
|
||||
|
||||
/datum/spellbook_entry/item/warpwhistle
|
||||
name = "Warp Whistle"
|
||||
desc = "A strange whistle that will transport you to a distant safe place on the station. There is a window of vulnerability at the begining of every use."
|
||||
desc = "A strange whistle that will transport you to a distant safe place on the station. There is a window of vulnerability at the beginning of every use."
|
||||
item_path = /obj/item/warpwhistle
|
||||
category = "Mobility"
|
||||
cost = 1
|
||||
@@ -652,7 +652,7 @@
|
||||
var/list/cat_dat = list()
|
||||
for(var/category in categories)
|
||||
cat_dat[category] = "<hr>"
|
||||
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=\ref[src];page=[category]'>[category]</a></li>"
|
||||
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[REF(src)];page=[category]'>[category]</a></li>"
|
||||
|
||||
dat += "<li><a><b>Points remaining : [uses]</b></a></li>"
|
||||
dat += "</ul>"
|
||||
@@ -663,11 +663,11 @@
|
||||
E = entries[i]
|
||||
spell_info += E.GetInfo()
|
||||
if(E.CanBuy(user,src))
|
||||
spell_info+= "<a href='byond://?src=\ref[src];buy=[i]'>[E.buy_word]</A><br>"
|
||||
spell_info+= "<a href='byond://?src=[REF(src)];buy=[i]'>[E.buy_word]</A><br>"
|
||||
else
|
||||
spell_info+= "<span>Can't [E.buy_word]</span><br>"
|
||||
if(E.CanRefund(user,src))
|
||||
spell_info+= "<a href='byond://?src=\ref[src];refund=[i]'>Refund</A><br>"
|
||||
spell_info+= "<a href='byond://?src=[REF(src)];refund=[i]'>Refund</A><br>"
|
||||
spell_info += "<hr>"
|
||||
if(cat_dat[E.category])
|
||||
cat_dat[E.category] += spell_info
|
||||
|
||||
@@ -28,12 +28,6 @@ Class Variables:
|
||||
component_parts (list)
|
||||
A list of component parts of machine used by frame based machines.
|
||||
|
||||
uid (num)
|
||||
Unique id of machine across all machines.
|
||||
|
||||
gl_uid (global num)
|
||||
Next uid value in sequence
|
||||
|
||||
stat (bitflag)
|
||||
Machine status bit flags.
|
||||
Possible bit flags:
|
||||
@@ -77,9 +71,6 @@ Class Procs:
|
||||
|
||||
Default definition does nothing.
|
||||
|
||||
assign_uid() 'game/machinery/machine.dm'
|
||||
Called by machine to assign a value to the uid variable.
|
||||
|
||||
process() 'game/machinery/machine.dm'
|
||||
Called by the 'machinery subsystem' once per machinery tick for each machine that is listed in its 'machines' list.
|
||||
|
||||
@@ -112,17 +103,14 @@ Class Procs:
|
||||
var/power_channel = EQUIP
|
||||
//EQUIP,ENVIRON or LIGHT
|
||||
var/list/component_parts = null //list of all the parts used to build it, if made from certain kinds of frames.
|
||||
var/uid
|
||||
var/global/gl_uid = 1
|
||||
var/panel_open = FALSE
|
||||
var/state_open = FALSE
|
||||
var/critical_machine = FALSE //If this machine is critical to station operation and should have the area be excempted from power failures.
|
||||
var/list/occupant_typecache //if set, turned into typecache in Initialize, other wise, defaults to mob/living typecache
|
||||
var/atom/movable/occupant = null
|
||||
var/unsecuring_tool = /obj/item/wrench
|
||||
var/interact_open = FALSE // Can the machine be interacted with when in maint/when the panel is open.
|
||||
var/interact_offline = 0 // Can the machine be interacted with while de-powered.
|
||||
var/speed_process = 0 // Process as fast as possible?
|
||||
var/speed_process = FALSE // Process as fast as possible?
|
||||
var/obj/item/circuitboard/circuit // Circuit to be created and inserted when the machinery is created
|
||||
|
||||
/obj/machinery/Initialize()
|
||||
@@ -303,10 +291,6 @@ Class Procs:
|
||||
/obj/machinery/proc/RefreshParts() //Placeholder proc for machines that are built using frames.
|
||||
return
|
||||
|
||||
/obj/machinery/proc/assign_uid()
|
||||
uid = gl_uid
|
||||
gl_uid++
|
||||
|
||||
/obj/machinery/proc/default_pry_open(obj/item/crowbar/C)
|
||||
. = !(state_open || panel_open || is_operational() || (flags_1 & NODECONSTRUCT_1)) && istype(C)
|
||||
if(.)
|
||||
@@ -506,3 +490,19 @@ Class Procs:
|
||||
. = ..()
|
||||
if (AM == occupant)
|
||||
occupant = null
|
||||
|
||||
/obj/machinery/proc/adjust_item_drop_location(atom/movable/AM) // Adjust item drop location to a 3x3 grid inside the tile, returns slot id from 0 to 8
|
||||
var/md5 = md5(AM.name) // Oh, and it's deterministic too. A specific item will always drop from the same slot.
|
||||
for (var/i in 1 to 32)
|
||||
#if DM_VERSION >= 513
|
||||
#warning 512 is definitely stable now, remove the old code
|
||||
#endif
|
||||
|
||||
#if DM_VERSION >= 512
|
||||
. += hex2num(md5[i])
|
||||
#else
|
||||
. += hex2num(copytext(md5,i,i+1))
|
||||
#endif
|
||||
. = . % 9
|
||||
AM.pixel_x = -8 + ((.%3)*8)
|
||||
AM.pixel_y = -8 + (round( . / 3)*8)
|
||||
@@ -107,8 +107,8 @@ GLOBAL_LIST_EMPTY(announcement_systems)
|
||||
return
|
||||
|
||||
|
||||
var/contents = "Arrival Announcement: <A href='?src=\ref[src];ArrivalT-Topic=1'>([(arrivalToggle ? "On" : "Off")])</a><br>\n<A href='?src=\ref[src];ArrivalTopic=1'>[arrival]</a><br><br>\n"
|
||||
contents += "Departmental Head Announcement: <A href='?src=\ref[src];NewheadT-Topic=1'>([(newheadToggle ? "On" : "Off")])</a><br>\n<A href='?src=\ref[src];NewheadTopic=1'>[newhead]</a><br><br>\n"
|
||||
var/contents = "Arrival Announcement: <A href='?src=[REF(src)];ArrivalT-Topic=1'>([(arrivalToggle ? "On" : "Off")])</a><br>\n<A href='?src=[REF(src)];ArrivalTopic=1'>[arrival]</a><br><br>\n"
|
||||
contents += "Departmental Head Announcement: <A href='?src=[REF(src)];NewheadT-Topic=1'>([(newheadToggle ? "On" : "Off")])</a><br>\n<A href='?src=[REF(src)];NewheadTopic=1'>[newhead]</a><br><br>\n"
|
||||
|
||||
var/datum/browser/popup = new(user, "announcement_config", "Automated Announcement Configuration", 370, 220)
|
||||
popup.set_content(contents)
|
||||
|
||||
@@ -240,8 +240,8 @@
|
||||
var/dat = "<div class='statusDisplay'><h3>Autolathe Menu:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
dat += "<form name='search' action='?src=\ref[src]'>\
|
||||
<input type='hidden' name='src' value='\ref[src]'>\
|
||||
dat += "<form name='search' action='?src=[REF(src)]'>\
|
||||
<input type='hidden' name='src' value='[REF(src)]'>\
|
||||
<input type='hidden' name='search' value='to_search'>\
|
||||
<input type='hidden' name='menu' value='[AUTOLATHE_SEARCH_MENU]'>\
|
||||
<input type='text' name='to_search'>\
|
||||
@@ -256,14 +256,14 @@
|
||||
dat += "</tr><tr>"
|
||||
line_length = 1
|
||||
|
||||
dat += "<td><A href='?src=\ref[src];category=[C];menu=[AUTOLATHE_CATEGORY_MENU]'>[C]</A></td>"
|
||||
dat += "<td><A href='?src=[REF(src)];category=[C];menu=[AUTOLATHE_CATEGORY_MENU]'>[C]</A></td>"
|
||||
line_length++
|
||||
|
||||
dat += "</tr></table></div>"
|
||||
return dat
|
||||
|
||||
/obj/machinery/autolathe/proc/category_win(mob/user,selected_category)
|
||||
var/dat = "<A href='?src=\ref[src];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
|
||||
var/dat = "<A href='?src=[REF(src)];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
|
||||
dat += "<div class='statusDisplay'><h3>Browsing [selected_category]:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
@@ -275,22 +275,22 @@
|
||||
if(disabled || !can_build(D))
|
||||
dat += "<span class='linkOff'>[D.name]</span>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];make=[D.id];multiplier=1'>[D.name]</a>"
|
||||
dat += "<a href='?src=[REF(src)];make=[D.id];multiplier=1'>[D.name]</a>"
|
||||
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
GET_COMPONENT(materials, /datum/component/material_container)
|
||||
var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY)
|
||||
if (max_multiplier>10 && !disabled)
|
||||
dat += " <a href='?src=\ref[src];make=[D.id];multiplier=10'>x10</a>"
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
|
||||
if (max_multiplier>25 && !disabled)
|
||||
dat += " <a href='?src=\ref[src];make=[D.id];multiplier=25'>x25</a>"
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=25'>x25</a>"
|
||||
if(max_multiplier > 0 && !disabled)
|
||||
dat += " <a href='?src=\ref[src];make=[D.id];multiplier=[max_multiplier]'>x[max_multiplier]</a>"
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=[max_multiplier]'>x[max_multiplier]</a>"
|
||||
else
|
||||
if(!disabled && can_build(D, 5))
|
||||
dat += " <a href='?src=\ref[src];make=[D.id];multiplier=5'>x5</a>"
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=5'>x5</a>"
|
||||
if(!disabled && can_build(D, 10))
|
||||
dat += " <a href='?src=\ref[src];make=[D.id];multiplier=10'>x10</a>"
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
|
||||
|
||||
dat += "[get_design_cost(D)]<br>"
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
return dat
|
||||
|
||||
/obj/machinery/autolathe/proc/search_win(mob/user)
|
||||
var/dat = "<A href='?src=\ref[src];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
|
||||
var/dat = "<A href='?src=[REF(src)];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
|
||||
dat += "<div class='statusDisplay'><h3>Search results:</h3><br>"
|
||||
dat += materials_printout()
|
||||
|
||||
@@ -307,17 +307,17 @@
|
||||
if(disabled || !can_build(D))
|
||||
dat += "<span class='linkOff'>[D.name]</span>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];make=[D.id];multiplier=1'>[D.name]</a>"
|
||||
dat += "<a href='?src=[REF(src)];make=[D.id];multiplier=1'>[D.name]</a>"
|
||||
|
||||
if(ispath(D.build_path, /obj/item/stack))
|
||||
GET_COMPONENT(materials, /datum/component/material_container)
|
||||
var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY)
|
||||
if (max_multiplier>10 && !disabled)
|
||||
dat += " <a href='?src=\ref[src];make=[D.id];multiplier=10'>x10</a>"
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=10'>x10</a>"
|
||||
if (max_multiplier>25 && !disabled)
|
||||
dat += " <a href='?src=\ref[src];make=[D.id];multiplier=25'>x25</a>"
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=25'>x25</a>"
|
||||
if(max_multiplier > 0 && !disabled)
|
||||
dat += " <a href='?src=\ref[src];make=[D.id];multiplier=[max_multiplier]'>x[max_multiplier]</a>"
|
||||
dat += " <a href='?src=[REF(src)];make=[D.id];multiplier=[max_multiplier]'>x[max_multiplier]</a>"
|
||||
|
||||
dat += "[get_design_cost(D)]<br>"
|
||||
|
||||
|
||||
@@ -62,11 +62,11 @@
|
||||
var/dat = "[world.name] secure vault. Authorized personnel only.<br>"
|
||||
dat += "Current Balance: [SSshuttle.points] credits.<br>"
|
||||
if(!siphoning)
|
||||
dat += "<A href='?src=\ref[src];siphon=1'>Siphon Credits</A><br>"
|
||||
dat += "<A href='?src=[REF(src)];siphon=1'>Siphon Credits</A><br>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];halt=1'>Halt Credit Siphon</A><br>"
|
||||
dat += "<A href='?src=[REF(src)];halt=1'>Halt Credit Siphon</A><br>"
|
||||
|
||||
dat += "<a href='?src=\ref[user];mach_close=computer'>Close</a>"
|
||||
dat += "<a href='?src=[REF(user)];mach_close=computer'>Close</a>"
|
||||
|
||||
var/datum/browser/popup = new(user, "computer", "Bank Vault", 300, 200)
|
||||
popup.set_content("<center>[dat]</center>")
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
var/invuln = null
|
||||
var/obj/item/device/camera_bug/bug = null
|
||||
var/obj/structure/camera_assembly/assembly = null
|
||||
var/area/myarea = null
|
||||
|
||||
//OTHER
|
||||
|
||||
@@ -47,6 +48,9 @@
|
||||
assembly.state = 4
|
||||
GLOB.cameranet.cameras += src
|
||||
GLOB.cameranet.addCamera(src)
|
||||
if (isturf(loc))
|
||||
myarea = get_area(src)
|
||||
LAZYADD(myarea.cameras, src)
|
||||
proximity_monitor = new(src, 1)
|
||||
|
||||
if(mapload && (z in GLOB.station_z_levels) && prob(3) && !start_active)
|
||||
@@ -54,6 +58,8 @@
|
||||
|
||||
/obj/machinery/camera/Destroy()
|
||||
toggle_cam(null, 0) //kick anyone viewing out
|
||||
if(isarea(myarea))
|
||||
LAZYREMOVE(myarea.cameras, src)
|
||||
if(assembly)
|
||||
qdel(assembly)
|
||||
assembly = null
|
||||
@@ -64,7 +70,6 @@
|
||||
bug = null
|
||||
GLOB.cameranet.removeCamera(src) //Will handle removal from the camera network and the chunks, so we don't need to worry about that
|
||||
GLOB.cameranet.cameras -= src
|
||||
GLOB.cameranet.removeCamera(src)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/camera/emp_act(severity)
|
||||
@@ -92,11 +97,12 @@
|
||||
GLOB.cameranet.addCamera(src)
|
||||
emped = 0 //Resets the consecutive EMP count
|
||||
addtimer(CALLBACK(src, .proc/cancelCameraAlarm), 100)
|
||||
for(var/mob/O in GLOB.mob_list)
|
||||
if (O.client && O.client.eye == src)
|
||||
O.unset_machine()
|
||||
O.reset_perspective(null)
|
||||
to_chat(O, "The screen bursts into static.")
|
||||
for(var/i in GLOB.player_list)
|
||||
var/mob/M = i
|
||||
if (M.client.eye == src)
|
||||
M.unset_machine()
|
||||
M.reset_perspective(null)
|
||||
to_chat(M, "The screen bursts into static.")
|
||||
..()
|
||||
|
||||
/obj/machinery/camera/tesla_act(var/power)//EMP proof upgrade also makes it tesla immune
|
||||
@@ -119,6 +125,11 @@
|
||||
return
|
||||
user.electrocute_act(10, src)
|
||||
|
||||
/obj/machinery/camera/singularity_pull(S, current_size)
|
||||
if (status && current_size >= STAGE_FIVE) // If the singulo is strong enough to pull anchored objects and the camera is still active, turn off the camera as it gets ripped off the wall.
|
||||
toggle_cam(null, 0)
|
||||
..()
|
||||
|
||||
/obj/machinery/camera/attackby(obj/item/W, mob/living/user, params)
|
||||
var/msg = "<span class='notice'>You attach [W] into the assembly's inner circuits.</span>"
|
||||
var/msg2 = "<span class='notice'>[src] already has that upgrade!</span>"
|
||||
@@ -203,7 +214,7 @@
|
||||
if(U.name == "Unknown")
|
||||
to_chat(AI, "<b>[U]</b> holds <a href='?_src_=usr;show_paper=1;'>\a [itemname]</a> up to one of your cameras ...")
|
||||
else
|
||||
to_chat(AI, "<b><a href='?src=\ref[AI];track=[html_encode(U.name)]'>[U]</a></b> holds <a href='?_src_=usr;show_paper=1;'>\a [itemname]</a> up to one of your cameras ...")
|
||||
to_chat(AI, "<b><a href='?src=[REF(AI)];track=[html_encode(U.name)]'>[U]</a></b> holds <a href='?_src_=usr;show_paper=1;'>\a [itemname]</a> up to one of your cameras ...")
|
||||
AI.last_paper_seen = "<HTML><HEAD><TITLE>[itemname]</TITLE></HEAD><BODY><TT>[info]</TT></BODY></HTML>"
|
||||
else if (O.client && O.client.eye == src)
|
||||
to_chat(O, "[U] holds \a [itemname] up to one of the cameras ...")
|
||||
@@ -268,9 +279,16 @@
|
||||
status = !status
|
||||
if(can_use())
|
||||
GLOB.cameranet.addCamera(src)
|
||||
if (isturf(loc))
|
||||
myarea = get_area(src)
|
||||
LAZYADD(myarea.cameras, src)
|
||||
else
|
||||
myarea = null
|
||||
else
|
||||
set_light(0)
|
||||
GLOB.cameranet.removeCamera(src)
|
||||
if (isarea(myarea))
|
||||
LAZYREMOVE(myarea.cameras, src)
|
||||
GLOB.cameranet.updateChunk(x, y, z)
|
||||
var/change_msg = "deactivates"
|
||||
if(status)
|
||||
@@ -298,12 +316,12 @@
|
||||
|
||||
/obj/machinery/camera/proc/triggerCameraAlarm()
|
||||
alarm_on = TRUE
|
||||
for(var/mob/living/silicon/S in GLOB.mob_list)
|
||||
for(var/mob/living/silicon/S in GLOB.silicon_mobs)
|
||||
S.triggerAlarm("Camera", get_area(src), list(src), src)
|
||||
|
||||
/obj/machinery/camera/proc/cancelCameraAlarm()
|
||||
alarm_on = FALSE
|
||||
for(var/mob/living/silicon/S in GLOB.mob_list)
|
||||
for(var/mob/living/silicon/S in GLOB.silicon_mobs)
|
||||
S.cancelAlarm("Camera", get_area(src), src)
|
||||
|
||||
/obj/machinery/camera/proc/can_use()
|
||||
|
||||
@@ -45,14 +45,6 @@
|
||||
anchored = TRUE
|
||||
state = 2
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/wrench))
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You unattach the assembly from its place.</span>")
|
||||
new /obj/item/wallframe/camera(get_turf(src))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(2)
|
||||
// State 2
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
@@ -73,40 +65,6 @@
|
||||
anchored = TRUE
|
||||
return
|
||||
|
||||
|
||||
if(3)
|
||||
// State 3
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
|
||||
var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")
|
||||
if(!input)
|
||||
to_chat(user, "<span class='warning'>No input found, please hang up and try your call again!</span>")
|
||||
return
|
||||
|
||||
var/list/tempnetwork = splittext(input, ",")
|
||||
if(tempnetwork.len < 1)
|
||||
to_chat(user, "<span class='warning'>No network found, please hang up and try your call again!</span>")
|
||||
return
|
||||
|
||||
state = 4
|
||||
var/obj/machinery/camera/C = new(src.loc)
|
||||
forceMove(C)
|
||||
C.assembly = src
|
||||
C.setDir(src.dir)
|
||||
|
||||
C.network = tempnetwork
|
||||
var/area/A = get_area(src)
|
||||
C.c_tag = "[A.name] ([rand(1, 999)])"
|
||||
|
||||
|
||||
else if(istype(W, /obj/item/wirecutters))
|
||||
new/obj/item/stack/cable_coil(get_turf(src), 2)
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You cut the wires from the circuits.</span>")
|
||||
state = 2
|
||||
return
|
||||
|
||||
// Upgrades!
|
||||
if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
@@ -115,18 +73,62 @@
|
||||
upgrades += W
|
||||
return
|
||||
|
||||
// Taking out upgrades
|
||||
else if(istype(W, /obj/item/crowbar) && upgrades.len)
|
||||
var/obj/U = locate(/obj) in upgrades
|
||||
if(U)
|
||||
to_chat(user, "<span class='notice'>You unattach an upgrade from the assembly.</span>")
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
U.forceMove(drop_location())
|
||||
upgrades -= U
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/camera_assembly/crowbar_act(mob/user, obj/item/tool)
|
||||
if(!upgrades.len)
|
||||
return FALSE
|
||||
var/obj/U = locate(/obj) in upgrades
|
||||
if(U)
|
||||
to_chat(user, "<span class='notice'>You unattach an upgrade from the assembly.</span>")
|
||||
playsound(src, tool.usesound, 50, 1)
|
||||
U.forceMove(drop_location())
|
||||
upgrades -= U
|
||||
return TRUE
|
||||
|
||||
/obj/structure/camera_assembly/screwdriver_act(mob/user, obj/item/tool)
|
||||
if(state != 3)
|
||||
return FALSE
|
||||
|
||||
playsound(src, tool.usesound, 50, 1)
|
||||
var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")
|
||||
if(!input)
|
||||
to_chat(user, "<span class='warning'>No input found, please hang up and try your call again!</span>")
|
||||
return
|
||||
var/list/tempnetwork = splittext(input, ",")
|
||||
if(tempnetwork.len < 1)
|
||||
to_chat(user, "<span class='warning'>No network found, please hang up and try your call again!</span>")
|
||||
return
|
||||
state = 4
|
||||
var/obj/machinery/camera/C = new(src.loc)
|
||||
forceMove(C)
|
||||
C.assembly = src
|
||||
C.setDir(src.dir)
|
||||
|
||||
C.network = tempnetwork
|
||||
var/area/A = get_area(src)
|
||||
C.c_tag = "[A.name] ([rand(1, 999)])"
|
||||
return TRUE
|
||||
|
||||
/obj/structure/camera_assembly/wirecutter_act(mob/user, obj/item/tool)
|
||||
if(state != 3)
|
||||
return FALSE
|
||||
|
||||
new /obj/item/stack/cable_coil(get_turf(src), 2)
|
||||
playsound(src, tool.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You cut the wires from the circuits.</span>")
|
||||
state = 2
|
||||
return TRUE
|
||||
|
||||
/obj/structure/camera_assembly/wrench_act(mob/user, obj/item/tool)
|
||||
if(state != 1)
|
||||
return FALSE
|
||||
playsound(src, tool.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You unattach the assembly from its place.</span>")
|
||||
new /obj/item/wallframe/camera(get_turf(src))
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user)
|
||||
if(!WT.remove_fuel(0, user))
|
||||
return 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/machinery/camera
|
||||
|
||||
var/list/localMotionTargets = list()
|
||||
var/list/datum/weakref/localMotionTargets = list()
|
||||
var/detectTime = 0
|
||||
var/area/ai_monitored/area_motion = null
|
||||
var/alarm_delay = 30 // Don't forget, there's another 3 seconds in queueAlarm()
|
||||
@@ -15,11 +15,11 @@
|
||||
if (elapsed > alarm_delay)
|
||||
triggerAlarm()
|
||||
else if (detectTime == -1)
|
||||
for (var/targetref in getTargetList())
|
||||
var/mob/target = locate(targetref) in GLOB.mob_list
|
||||
if (QDELETED(target) || target.stat == DEAD || (!area_motion && !in_range(src, target)))
|
||||
for (var/datum/weakref/targetref in getTargetList())
|
||||
var/mob/target = targetref.resolve()
|
||||
if(QDELETED(target) || target.stat == DEAD || (!area_motion && !in_range(src, target)))
|
||||
//If not part of a monitored area and the camera is not in range or the target is dead
|
||||
lostTarget(target)
|
||||
lostTargetRef(targetref)
|
||||
|
||||
/obj/machinery/camera/proc/getTargetList()
|
||||
if(area_motion)
|
||||
@@ -28,41 +28,43 @@
|
||||
|
||||
/obj/machinery/camera/proc/newTarget(mob/target)
|
||||
if(isAI(target))
|
||||
return 0
|
||||
return FALSE
|
||||
if (detectTime == 0)
|
||||
detectTime = world.time // start the clock
|
||||
var/list/targets = getTargetList()
|
||||
targets |= "\ref[target]"
|
||||
return 1
|
||||
targets |= WEAKREF(target)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/camera/Destroy()
|
||||
var/area/ai_monitored/A = get_area(src)
|
||||
localMotionTargets = null
|
||||
if(istype(A))
|
||||
A.motioncameras -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/camera/proc/lostTarget(mob/target)
|
||||
/obj/machinery/camera/proc/lostTargetRef(datum/weakref/R)
|
||||
var/list/targets = getTargetList()
|
||||
targets -= "\ref[target]"
|
||||
targets -= R
|
||||
if (targets.len == 0)
|
||||
cancelAlarm()
|
||||
|
||||
/obj/machinery/camera/proc/cancelAlarm()
|
||||
if (detectTime == -1)
|
||||
for (var/mob/living/silicon/aiPlayer in GLOB.player_list)
|
||||
for (var/i in GLOB.silicon_mobs)
|
||||
var/mob/living/silicon/aiPlayer = i
|
||||
if (status)
|
||||
aiPlayer.cancelAlarm("Motion", get_area(src), src)
|
||||
detectTime = 0
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/camera/proc/triggerAlarm()
|
||||
if (!detectTime)
|
||||
return 0
|
||||
return FALSE
|
||||
for (var/mob/living/silicon/aiPlayer in GLOB.player_list)
|
||||
if (status)
|
||||
aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src)
|
||||
detectTime = -1
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/camera/HasProximity(atom/movable/AM as mob|obj)
|
||||
// Motion cameras outside of an "ai monitored" area will use this to detect stuff.
|
||||
|
||||
@@ -1,172 +1,168 @@
|
||||
/mob/living/silicon/ai/proc/get_camera_list()
|
||||
|
||||
track.cameras.Cut()
|
||||
|
||||
if(src.stat == DEAD)
|
||||
return
|
||||
|
||||
var/list/L = list()
|
||||
for (var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
L.Add(C)
|
||||
|
||||
camera_sort(L)
|
||||
|
||||
var/list/T = list()
|
||||
|
||||
for (var/obj/machinery/camera/C in L)
|
||||
var/list/tempnetwork = C.network&src.network
|
||||
if (tempnetwork.len)
|
||||
T[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C
|
||||
|
||||
track.cameras = T
|
||||
return T
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_camera_list(camera)
|
||||
if (!camera)
|
||||
return 0
|
||||
|
||||
var/obj/machinery/camera/C = track.cameras[camera]
|
||||
src.eyeobj.setLoc(C)
|
||||
|
||||
return
|
||||
|
||||
/datum/trackable
|
||||
var/list/names = list()
|
||||
var/list/namecounts = list()
|
||||
var/list/humans = list()
|
||||
var/list/others = list()
|
||||
var/list/cameras = list()
|
||||
|
||||
/mob/living/silicon/ai/proc/trackable_mobs()
|
||||
|
||||
track.names.Cut()
|
||||
track.namecounts.Cut()
|
||||
track.humans.Cut()
|
||||
track.others.Cut()
|
||||
|
||||
if(usr.stat == DEAD)
|
||||
return list()
|
||||
|
||||
for(var/mob/living/M in GLOB.mob_list)
|
||||
if(!M.can_track(usr))
|
||||
continue
|
||||
|
||||
// Human check
|
||||
var/human = 0
|
||||
if(ishuman(M))
|
||||
human = 1
|
||||
|
||||
var/name = M.name
|
||||
while(name in track.names)
|
||||
track.namecounts[name]++
|
||||
name = text("[] ([])", name, track.namecounts[name])
|
||||
track.names.Add(name)
|
||||
track.namecounts[name] = 1
|
||||
|
||||
if(human)
|
||||
track.humans[name] = M
|
||||
else
|
||||
track.others[name] = M
|
||||
|
||||
var/list/targets = sortList(track.humans) + sortList(track.others)
|
||||
|
||||
return targets
|
||||
|
||||
/mob/living/silicon/ai/verb/ai_camera_track(target_name in trackable_mobs())
|
||||
set name = "track"
|
||||
set hidden = 1 //Don't display it on the verb lists. This verb exists purely so you can type "track Oldman Robustin" and follow his ass
|
||||
|
||||
if(!target_name)
|
||||
return
|
||||
|
||||
var/mob/target = (isnull(track.humans[target_name]) ? track.others[target_name] : track.humans[target_name])
|
||||
|
||||
ai_actual_track(target)
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_actual_track(mob/living/target)
|
||||
if(!istype(target))
|
||||
return
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
|
||||
U.cameraFollow = target
|
||||
U.tracking = 1
|
||||
|
||||
if(!target || !target.can_track(usr))
|
||||
to_chat(U, "<span class='warning'>Target is not near any active cameras.</span>")
|
||||
U.cameraFollow = null
|
||||
return
|
||||
|
||||
to_chat(U, "<span class='notice'>Now tracking [target.get_visible_name()] on camera.</span>")
|
||||
|
||||
var/cameraticks = 0
|
||||
spawn(0)
|
||||
while(U.cameraFollow == target)
|
||||
if(U.cameraFollow == null)
|
||||
return
|
||||
|
||||
if(!target.can_track(usr))
|
||||
U.tracking = 1
|
||||
if(!cameraticks)
|
||||
to_chat(U, "<span class='warning'>Target is not near any active cameras. Attempting to reacquire...</span>")
|
||||
cameraticks++
|
||||
if(cameraticks > 9)
|
||||
U.cameraFollow = null
|
||||
to_chat(U, "<span class='warning'>Unable to reacquire, cancelling track...</span>")
|
||||
tracking = 0
|
||||
return
|
||||
else
|
||||
sleep(10)
|
||||
continue
|
||||
|
||||
else
|
||||
cameraticks = 0
|
||||
U.tracking = 0
|
||||
|
||||
if(U.eyeobj)
|
||||
U.eyeobj.setLoc(get_turf(target))
|
||||
|
||||
else
|
||||
view_core()
|
||||
U.cameraFollow = null
|
||||
return
|
||||
|
||||
sleep(10)
|
||||
|
||||
/proc/near_camera(mob/living/M)
|
||||
if (!isturf(M.loc))
|
||||
return 0
|
||||
if(issilicon(M))
|
||||
var/mob/living/silicon/S = M
|
||||
if((!QDELETED(S.builtInCamera) || !S.builtInCamera.can_use()) && !GLOB.cameranet.checkCameraVis(M))
|
||||
return 0
|
||||
else if(!GLOB.cameranet.checkCameraVis(M))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/camera/attack_ai(mob/living/silicon/ai/user)
|
||||
if (!istype(user))
|
||||
return
|
||||
if (!src.can_use())
|
||||
return
|
||||
user.eyeobj.setLoc(get_turf(src))
|
||||
|
||||
|
||||
/mob/living/silicon/ai/attack_ai(mob/user)
|
||||
ai_camera_list()
|
||||
|
||||
/proc/camera_sort(list/L)
|
||||
var/obj/machinery/camera/a
|
||||
var/obj/machinery/camera/b
|
||||
|
||||
for (var/i = L.len, i > 0, i--)
|
||||
for (var/j = 1 to i - 1)
|
||||
a = L[j]
|
||||
b = L[j + 1]
|
||||
if (a.c_tag_order != b.c_tag_order)
|
||||
if (a.c_tag_order > b.c_tag_order)
|
||||
L.Swap(j, j + 1)
|
||||
else
|
||||
if (sorttext(a.c_tag, b.c_tag) < 0)
|
||||
L.Swap(j, j + 1)
|
||||
return L
|
||||
/mob/living/silicon/ai/proc/get_camera_list()
|
||||
|
||||
track.cameras.Cut()
|
||||
|
||||
if(src.stat == DEAD)
|
||||
return
|
||||
|
||||
var/list/L = list()
|
||||
for (var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
L.Add(C)
|
||||
|
||||
camera_sort(L)
|
||||
|
||||
var/list/T = list()
|
||||
|
||||
for (var/obj/machinery/camera/C in L)
|
||||
var/list/tempnetwork = C.network&src.network
|
||||
if (tempnetwork.len)
|
||||
T[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C
|
||||
|
||||
track.cameras = T
|
||||
return T
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_camera_list(camera)
|
||||
if (!camera)
|
||||
return 0
|
||||
|
||||
var/obj/machinery/camera/C = track.cameras[camera]
|
||||
src.eyeobj.setLoc(C)
|
||||
|
||||
return
|
||||
|
||||
/datum/trackable
|
||||
var/list/names = list()
|
||||
var/list/namecounts = list()
|
||||
var/list/humans = list()
|
||||
var/list/others = list()
|
||||
var/list/cameras = list()
|
||||
|
||||
/mob/living/silicon/ai/proc/trackable_mobs()
|
||||
|
||||
track.names.Cut()
|
||||
track.namecounts.Cut()
|
||||
track.humans.Cut()
|
||||
track.others.Cut()
|
||||
|
||||
if(usr.stat == DEAD)
|
||||
return list()
|
||||
|
||||
for(var/i in GLOB.mob_living_list)
|
||||
var/mob/living/L = i
|
||||
if(!L.can_track(usr))
|
||||
continue
|
||||
|
||||
var/name = L.name
|
||||
while(name in track.names)
|
||||
track.namecounts[name]++
|
||||
name = text("[] ([])", name, track.namecounts[name])
|
||||
track.names.Add(name)
|
||||
track.namecounts[name] = 1
|
||||
|
||||
if(ishuman(L))
|
||||
track.humans[name] = L
|
||||
else
|
||||
track.others[name] = L
|
||||
|
||||
var/list/targets = sortList(track.humans) + sortList(track.others)
|
||||
|
||||
return targets
|
||||
|
||||
/mob/living/silicon/ai/verb/ai_camera_track(target_name in trackable_mobs())
|
||||
set name = "track"
|
||||
set hidden = 1 //Don't display it on the verb lists. This verb exists purely so you can type "track Oldman Robustin" and follow his ass
|
||||
|
||||
if(!target_name)
|
||||
return
|
||||
|
||||
var/mob/target = (isnull(track.humans[target_name]) ? track.others[target_name] : track.humans[target_name])
|
||||
|
||||
ai_actual_track(target)
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_actual_track(mob/living/target)
|
||||
if(!istype(target))
|
||||
return
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
|
||||
U.cameraFollow = target
|
||||
U.tracking = 1
|
||||
|
||||
if(!target || !target.can_track(usr))
|
||||
to_chat(U, "<span class='warning'>Target is not near any active cameras.</span>")
|
||||
U.cameraFollow = null
|
||||
return
|
||||
|
||||
to_chat(U, "<span class='notice'>Now tracking [target.get_visible_name()] on camera.</span>")
|
||||
|
||||
var/cameraticks = 0
|
||||
spawn(0)
|
||||
while(U.cameraFollow == target)
|
||||
if(U.cameraFollow == null)
|
||||
return
|
||||
|
||||
if(!target.can_track(usr))
|
||||
U.tracking = 1
|
||||
if(!cameraticks)
|
||||
to_chat(U, "<span class='warning'>Target is not near any active cameras. Attempting to reacquire...</span>")
|
||||
cameraticks++
|
||||
if(cameraticks > 9)
|
||||
U.cameraFollow = null
|
||||
to_chat(U, "<span class='warning'>Unable to reacquire, cancelling track...</span>")
|
||||
tracking = 0
|
||||
return
|
||||
else
|
||||
sleep(10)
|
||||
continue
|
||||
|
||||
else
|
||||
cameraticks = 0
|
||||
U.tracking = 0
|
||||
|
||||
if(U.eyeobj)
|
||||
U.eyeobj.setLoc(get_turf(target))
|
||||
|
||||
else
|
||||
view_core()
|
||||
U.cameraFollow = null
|
||||
return
|
||||
|
||||
sleep(10)
|
||||
|
||||
/proc/near_camera(mob/living/M)
|
||||
if (!isturf(M.loc))
|
||||
return 0
|
||||
if(issilicon(M))
|
||||
var/mob/living/silicon/S = M
|
||||
if((!QDELETED(S.builtInCamera) || !S.builtInCamera.can_use()) && !GLOB.cameranet.checkCameraVis(M))
|
||||
return 0
|
||||
else if(!GLOB.cameranet.checkCameraVis(M))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/camera/attack_ai(mob/living/silicon/ai/user)
|
||||
if (!istype(user))
|
||||
return
|
||||
if (!src.can_use())
|
||||
return
|
||||
user.eyeobj.setLoc(get_turf(src))
|
||||
|
||||
|
||||
/mob/living/silicon/ai/attack_ai(mob/user)
|
||||
ai_camera_list()
|
||||
|
||||
/proc/camera_sort(list/L)
|
||||
var/obj/machinery/camera/a
|
||||
var/obj/machinery/camera/b
|
||||
|
||||
for (var/i = L.len, i > 0, i--)
|
||||
for (var/j = 1 to i - 1)
|
||||
a = L[j]
|
||||
b = L[j + 1]
|
||||
if (a.c_tag_order != b.c_tag_order)
|
||||
if (a.c_tag_order > b.c_tag_order)
|
||||
L.Swap(j, j + 1)
|
||||
else
|
||||
if (sorttext(a.c_tag, b.c_tag) < 0)
|
||||
L.Swap(j, j + 1)
|
||||
return L
|
||||
|
||||
@@ -13,15 +13,13 @@
|
||||
|
||||
/obj/machinery/cell_charger/proc/updateicon()
|
||||
cut_overlays()
|
||||
|
||||
if(charging)
|
||||
add_overlay(image(charging.icon, charging.icon_state))
|
||||
add_overlay("ccharger-on")
|
||||
if(!(stat & (BROKEN|NOPOWER)))
|
||||
var/newlevel = round(charging.percent() * 4 / 100)
|
||||
if(chargelevel != newlevel)
|
||||
chargelevel = newlevel
|
||||
add_overlay("ccharger-o[newlevel]")
|
||||
chargelevel = newlevel
|
||||
add_overlay("ccharger-o[newlevel]")
|
||||
|
||||
/obj/machinery/cell_charger/examine(mob/user)
|
||||
..()
|
||||
|
||||
@@ -162,11 +162,6 @@
|
||||
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
|
||||
|
||||
if(clonemind.changeling)
|
||||
var/obj/item/organ/brain/B = H.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
B.vital = FALSE
|
||||
B.decoy_override = TRUE
|
||||
|
||||
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
|
||||
|
||||
if(efficiency > 2)
|
||||
@@ -307,7 +302,7 @@
|
||||
comp.AttachCloner(src)
|
||||
else
|
||||
P.buffer = src
|
||||
to_chat(user, "<font color = #666633>-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-</font color>")
|
||||
to_chat(user, "<font color = #666633>-% Successfully stored [REF(P.buffer)] [P.buffer.name] in buffer %-</font color>")
|
||||
return
|
||||
|
||||
var/mob/living/mob_occupant = occupant
|
||||
|
||||
@@ -1,74 +1,72 @@
|
||||
/obj/machinery/computer/operating
|
||||
name = "operating computer"
|
||||
desc = "Used to monitor the vitals of a patient during surgery."
|
||||
icon_screen = "crew"
|
||||
icon_keyboard = "med_key"
|
||||
circuit = /obj/item/circuitboard/computer/operating
|
||||
var/mob/living/carbon/human/patient
|
||||
var/obj/structure/table/optable/table
|
||||
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
|
||||
/obj/machinery/computer/operating/Initialize()
|
||||
. = ..()
|
||||
find_table()
|
||||
|
||||
/obj/machinery/computer/operating/proc/find_table()
|
||||
for(var/dir in GLOB.cardinals)
|
||||
table = locate(/obj/structure/table/optable, get_step(src, dir))
|
||||
if(table)
|
||||
table.computer = src
|
||||
break
|
||||
|
||||
|
||||
/obj/machinery/computer/operating/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/computer/operating/interact(mob/user)
|
||||
var/dat = ""
|
||||
if(table)
|
||||
dat += "<B>Patient information:</B><BR>"
|
||||
if(table.check_patient())
|
||||
patient = table.patient
|
||||
dat += get_patient_info()
|
||||
else
|
||||
patient = null
|
||||
dat += "<B>No patient detected</B>"
|
||||
else
|
||||
dat += "<B>Operating table not found.</B>"
|
||||
|
||||
var/datum/browser/popup = new(user, "op", "Operating Computer", 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/operating/proc/get_patient_info()
|
||||
var/dat = {"
|
||||
<div class='statusLabel'>Patient:</div> [patient.stat ? "<span class='bad'>Non-Responsive</span>" : "<span class='good'>Stable</span>"]<BR>
|
||||
<div class='statusLabel'>Blood Type:</div> [patient.dna.blood_type]
|
||||
|
||||
<BR>
|
||||
<div class='line'><div class='statusLabel'>Health:</div><div class='progressBar'><div style='width: [max(patient.health, 0)]%;' class='progressFill good'></div></div><div class='statusValue'>[patient.health]%</div></div>
|
||||
<div class='line'><div class='statusLabel'>\> Brute Damage:</div><div class='progressBar'><div style='width: [max(patient.getBruteLoss(), 0)]%;' class='progressFill bad'></div></div><div class='statusValue'>[patient.getBruteLoss()]%</div></div>
|
||||
<div class='line'><div class='statusLabel'>\> Resp. Damage:</div><div class='progressBar'><div style='width: [max(patient.getOxyLoss(), 0)]%;' class='progressFill bad'></div></div><div class='statusValue'>[patient.getOxyLoss()]%</div></div>
|
||||
<div class='line'><div class='statusLabel'>\> Toxin Content:</div><div class='progressBar'><div style='width: [max(patient.getToxLoss(), 0)]%;' class='progressFill bad'></div></div><div class='statusValue'>[patient.getToxLoss()]%</div></div>
|
||||
<div class='line'><div class='statusLabel'>\> Burn Severity:</div><div class='progressBar'><div style='width: [max(patient.getFireLoss(), 0)]%;' class='progressFill bad'></div></div><div class='statusValue'>[patient.getFireLoss()]%</div></div>
|
||||
|
||||
"}
|
||||
if(patient.surgeries.len)
|
||||
dat += "<BR><BR><B>Initiated Procedures</B><div class='statusDisplay'>"
|
||||
for(var/datum/surgery/procedure in patient.surgeries)
|
||||
dat += "[capitalize(procedure.name)]<BR>"
|
||||
var/datum/surgery_step/surgery_step = procedure.get_surgery_step()
|
||||
dat += "Next step: [capitalize(surgery_step.name)]"
|
||||
if(surgery_step.repeatable)
|
||||
dat += " or "
|
||||
var/datum/surgery_step/next_step = procedure.get_surgery_next_step()
|
||||
if(next_step)
|
||||
dat += "[capitalize(next_step.name)]"
|
||||
else
|
||||
dat += "finish operation"
|
||||
dat += "<BR>"
|
||||
dat += "</div>"
|
||||
return dat
|
||||
/obj/machinery/computer/operating
|
||||
name = "operating computer"
|
||||
desc = "Used to monitor the vitals of a patient during surgery."
|
||||
icon_screen = "crew"
|
||||
icon_keyboard = "med_key"
|
||||
circuit = /obj/item/circuitboard/computer/operating
|
||||
var/mob/living/carbon/human/patient
|
||||
var/obj/structure/table/optable/table
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
|
||||
/obj/machinery/computer/operating/Initialize()
|
||||
. = ..()
|
||||
find_table()
|
||||
|
||||
/obj/machinery/computer/operating/proc/find_table()
|
||||
for(var/direction in GLOB.cardinals)
|
||||
table = locate(/obj/structure/table/optable, get_step(src, direction))
|
||||
if(table)
|
||||
table.computer = src
|
||||
break
|
||||
|
||||
/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "operating_computer", name, 350, 470, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/operating/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["table"] = table
|
||||
if(table)
|
||||
data["patient"] = list()
|
||||
if(table.check_patient())
|
||||
patient = table.patient
|
||||
switch(patient.stat)
|
||||
if(CONSCIOUS)
|
||||
data["patient"]["stat"] = "Conscious"
|
||||
data["patient"]["statstate"] = "good"
|
||||
if(SOFT_CRIT)
|
||||
data["patient"]["stat"] = "Conscious"
|
||||
data["patient"]["statstate"] = "average"
|
||||
if(UNCONSCIOUS)
|
||||
data["patient"]["stat"] = "Unconscious"
|
||||
data["patient"]["statstate"] = "average"
|
||||
if(DEAD)
|
||||
data["patient"]["stat"] = "Dead"
|
||||
data["patient"]["statstate"] = "bad"
|
||||
data["patient"]["health"] = patient.health
|
||||
data["patient"]["blood_type"] = patient.dna.blood_type
|
||||
data["patient"]["maxHealth"] = patient.maxHealth
|
||||
data["patient"]["minHealth"] = HEALTH_THRESHOLD_DEAD
|
||||
data["patient"]["bruteLoss"] = patient.getBruteLoss()
|
||||
data["patient"]["fireLoss"] = patient.getFireLoss()
|
||||
data["patient"]["toxLoss"] = patient.getToxLoss()
|
||||
data["patient"]["oxyLoss"] = patient.getOxyLoss()
|
||||
if(patient.surgeries.len)
|
||||
data["procedures"] = list()
|
||||
for(var/datum/surgery/procedure in patient.surgeries)
|
||||
var/datum/surgery_step/surgery_step = procedure.get_surgery_step()
|
||||
var/alternative_step
|
||||
if(surgery_step.repeatable)
|
||||
var/datum/surgery_step/next_step = procedure.get_surgery_next_step()
|
||||
if(next_step)
|
||||
alternative_step = capitalize(next_step.name)
|
||||
else
|
||||
alternative_step = "Finish operation"
|
||||
data["procedures"] += list(list(
|
||||
"name" = capitalize(procedure.name),
|
||||
"next_step" = capitalize(surgery_step.name),
|
||||
"alternative_step" = alternative_step
|
||||
))
|
||||
return data
|
||||
|
||||
@@ -61,10 +61,10 @@
|
||||
else
|
||||
dat += "<span class='good'>AI functional</span>"
|
||||
if (!src.active)
|
||||
dat += {"<br><br><A href='byond://?src=\ref[src];fix=1'>Begin Reconstruction</A>"}
|
||||
dat += {"<br><br><A href='byond://?src=[REF(src)];fix=1'>Begin Reconstruction</A>"}
|
||||
else
|
||||
dat += "<br><br>Reconstruction in process, please wait.<br>"
|
||||
dat += {"<br><A href='?src=\ref[user];mach_close=computer'>Close</A>"}
|
||||
dat += {"<br><A href='?src=[REF(user)];mach_close=computer'>Close</A>"}
|
||||
var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
var/list/apcs //APCs the computer has access to
|
||||
var/mob/living/operator //Who's operating the computer right now
|
||||
var/obj/machinery/power/apc/active_apc //The APC we're using right now
|
||||
var/list/filters //For sorting the results
|
||||
var/list/result_filters //For sorting the results
|
||||
var/checking_logs = 0
|
||||
var/list/logs
|
||||
var/authenticated = 0
|
||||
@@ -18,7 +18,7 @@
|
||||
/obj/machinery/computer/apc_control/Initialize()
|
||||
. = ..()
|
||||
apcs = list() //To avoid BYOND making the list run through a ton of procs
|
||||
filters = list("Name" = null, "Charge Above" = null, "Charge Below" = null, "Responsive" = null)
|
||||
result_filters = list("Name" = null, "Charge Above" = null, "Charge Below" = null, "Responsive" = null)
|
||||
|
||||
/obj/machinery/computer/apc_control/process()
|
||||
apcs = list() //Clear the list every tick
|
||||
@@ -52,28 +52,28 @@
|
||||
if(!checking_logs)
|
||||
dat += "Logged in as [auth_id].<br><br>"
|
||||
dat += "<i>Filters</i><br>"
|
||||
dat += "<b>Name:</b> <a href='?src=\ref[src];name_filter=1'>[filters["Name"] ? filters["Name"] : "None set"]</a><br>"
|
||||
dat += "<b>Charge:</b> <a href='?src=\ref[src];above_filter=1'>\>[filters["Charge Above"] ? filters["Charge Above"] : "NaN"]%</a> and <a href='?src=\ref[src];below_filter=1'>\<[filters["Charge Below"] ? filters["Charge Below"] : "NaN"]%</a><br>"
|
||||
dat += "<b>Accessible:</b> <a href='?src=\ref[src];access_filter=1'>[filters["Responsive"] ? "Non-Responsive Only" : "All"]</a><br><br>"
|
||||
dat += "<b>Name:</b> <a href='?src=[REF(src)];name_filter=1'>[result_filters["Name"] ? result_filters["Name"] : "None set"]</a><br>"
|
||||
dat += "<b>Charge:</b> <a href='?src=[REF(src)];above_filter=1'>\>[result_filters["Charge Above"] ? result_filters["Charge Above"] : "NaN"]%</a> and <a href='?src=[REF(src)];below_filter=1'>\<[result_filters["Charge Below"] ? result_filters["Charge Below"] : "NaN"]%</a><br>"
|
||||
dat += "<b>Accessible:</b> <a href='?src=[REF(src)];access_filter=1'>[result_filters["Responsive"] ? "Non-Responsive Only" : "All"]</a><br><br>"
|
||||
for(var/A in apcs)
|
||||
var/obj/machinery/power/apc/APC = apcs[A]
|
||||
if(filters["Name"] && !findtext(APC.name, filters["Name"]) && !findtext(APC.area.name, filters["Name"]))
|
||||
if(result_filters["Name"] && !findtext(APC.name, result_filters["Name"]) && !findtext(APC.area.name, result_filters["Name"]))
|
||||
continue
|
||||
if(filters["Charge Above"] && (APC.cell.charge / APC.cell.maxcharge) < filters["Charge Above"] / 100)
|
||||
if(result_filters["Charge Above"] && (APC.cell.charge / APC.cell.maxcharge) < result_filters["Charge Above"] / 100)
|
||||
continue
|
||||
if(filters["Charge Below"] && (APC.cell.charge / APC.cell.maxcharge) > filters["Charge Below"] / 100)
|
||||
if(result_filters["Charge Below"] && (APC.cell.charge / APC.cell.maxcharge) > result_filters["Charge Below"] / 100)
|
||||
continue
|
||||
if(filters["Responsive"] && !APC.aidisabled)
|
||||
if(result_filters["Responsive"] && !APC.aidisabled)
|
||||
continue
|
||||
dat += "<a href='?src=\ref[src];access_apc=\ref[APC]'>[A]</a><br>\
|
||||
dat += "<a href='?src=[REF(src)];access_apc=[REF(APC)]'>[A]</a><br>\
|
||||
<b>Charge:</b> [DisplayPower(APC.cell.charge)] / [DisplayPower(APC.cell.maxcharge)] ([round((APC.cell.charge / APC.cell.maxcharge) * 100)]%)<br>\
|
||||
<b>Area:</b> [APC.area]<br>\
|
||||
[APC.aidisabled || APC.panel_open ? "<font color='#FF0000'>APC does not respond to interface query.</font>" : "<font color='#00FF00'>APC responds to interface query.</font>"]<br><br>"
|
||||
dat += "<a href='?src=\ref[src];check_logs=1'>Check Logs</a><br>"
|
||||
dat += "<a href='?src=\ref[src];log_out=1'>Log Out</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];check_logs=1'>Check Logs</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];log_out=1'>Log Out</a><br>"
|
||||
if(emagged)
|
||||
dat += "<font color='#FF0000'>WARNING: Logging functionality partially disabled from outside source.</font><br>"
|
||||
dat += "<a href='?src=\ref[src];restore_logging=1'>Restore logging functionality?</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];restore_logging=1'>Restore logging functionality?</a><br>"
|
||||
else
|
||||
if(logs.len)
|
||||
for(var/entry in logs)
|
||||
@@ -81,11 +81,11 @@
|
||||
else
|
||||
dat += "<i>No activity has been recorded at this time.</i><br>"
|
||||
if(emagged)
|
||||
dat += "<a href='?src=\ref[src];clear_logs=1'><font color='#FF0000'>@#%! CLEAR LOGS</a>"
|
||||
dat += "<a href='?src=\ref[src];check_apcs=1'>Return</a>"
|
||||
dat += "<a href='?src=[REF(src)];clear_logs=1'><font color='#FF0000'>@#%! CLEAR LOGS</a>"
|
||||
dat += "<a href='?src=[REF(src)];check_apcs=1'>Return</a>"
|
||||
operator = user
|
||||
else
|
||||
dat = "<a href='?src=\ref[src];authenticate=1'>Please swipe a valid ID to log in...</a>"
|
||||
dat = "<a href='?src=[REF(src)];authenticate=1'>Please swipe a valid ID to log in...</a>"
|
||||
var/datum/browser/popup = new(user, "apc_control", name, 600, 400)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
@@ -153,7 +153,7 @@
|
||||
return
|
||||
log_activity("changed name filter to \"[new_filter]\"")
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
filters["Name"] = new_filter
|
||||
result_filters["Name"] = new_filter
|
||||
if(href_list["above_filter"])
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
var/new_filter = input(usr, "Enter a percentage from 1-100 to sort by (greater than).", name) as null|num
|
||||
@@ -163,7 +163,7 @@
|
||||
if(new_filter)
|
||||
new_filter = Clamp(new_filter, 0, 100)
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
filters["Charge Above"] = new_filter
|
||||
result_filters["Charge Above"] = new_filter
|
||||
if(href_list["below_filter"])
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
var/new_filter = input(usr, "Enter a percentage from 1-100 to sort by (lesser than).", name) as null|num
|
||||
@@ -173,13 +173,13 @@
|
||||
if(new_filter)
|
||||
new_filter = Clamp(new_filter, 0, 100)
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
filters["Charge Below"] = new_filter
|
||||
result_filters["Charge Below"] = new_filter
|
||||
if(href_list["access_filter"])
|
||||
if(isnull(filters["Responsive"]))
|
||||
filters["Responsive"] = 1
|
||||
if(isnull(result_filters["Responsive"]))
|
||||
result_filters["Responsive"] = 1
|
||||
log_activity("sorted by non-responsive APCs only")
|
||||
else
|
||||
filters["Responsive"] = !filters["Responsive"]
|
||||
result_filters["Responsive"] = !result_filters["Responsive"]
|
||||
log_activity("sorted by all APCs")
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
if(href_list["check_logs"])
|
||||
|
||||
@@ -134,18 +134,18 @@
|
||||
if(..())
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<a href='byond://?src=\ref[src];close=1'>Close</a>"
|
||||
var/dat = "<a href='byond://?src=[REF(src)];close=1'>Close</a>"
|
||||
dat += "<center><h4>[enemy_name]</h4></center>"
|
||||
|
||||
dat += "<br><center><h3>[temp]</h3></center>"
|
||||
dat += "<br><center>Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]</center>"
|
||||
|
||||
if (gameover)
|
||||
dat += "<center><b><a href='byond://?src=\ref[src];newgame=1'>New Game</a>"
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];newgame=1'>New Game</a>"
|
||||
else
|
||||
dat += "<center><b><a href='byond://?src=\ref[src];attack=1'>Attack</a> | "
|
||||
dat += "<a href='byond://?src=\ref[src];heal=1'>Heal</a> | "
|
||||
dat += "<a href='byond://?src=\ref[src];charge=1'>Recharge Power</a>"
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];attack=1'>Attack</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];heal=1'>Heal</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];charge=1'>Recharge Power</a>"
|
||||
|
||||
dat += "</b></center>"
|
||||
var/datum/browser/popup = new(user, "arcade", "Space Villian 2000")
|
||||
@@ -439,7 +439,7 @@
|
||||
name = "The Orion Trail"
|
||||
desc = "Learn how our ancestors got to Orion, and have fun in the process!"
|
||||
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=\ref[src];menu=1'>May They Rest In Peace</a></P>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];menu=1'>May They Rest In Peace</a></P>"
|
||||
else if(event)
|
||||
dat = eventdat
|
||||
else if(gameStatus == ORION_STATUS_NORMAL)
|
||||
@@ -452,16 +452,16 @@
|
||||
dat += "<br><b>Food: </b>[food] | <b>Fuel: </b>[fuel]"
|
||||
dat += "<br><b>Engine Parts: </b>[engine] | <b>Hull Panels: </b>[hull] | <b>Electronics: </b>[electronics]"
|
||||
if(turns == 7)
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=\ref[src];pastblack=1'>Go Around</a> <a href='byond://?src=\ref[src];blackhole=1'>Continue</a></P>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];pastblack=1'>Go Around</a> <a href='byond://?src=[REF(src)];blackhole=1'>Continue</a></P>"
|
||||
else
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=\ref[src];continue=1'>Continue</a></P>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=\ref[src];killcrew=1'>Kill a Crewmember</a></P>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];continue=1'>Continue</a></P>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];killcrew=1'>Kill a Crewmember</a></P>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
else
|
||||
dat = "<center><h2>The Orion Trail</h2></center>"
|
||||
dat += "<br><center><h3>Experience the journey of your ancestors!</h3></center><br><br>"
|
||||
dat += "<center><b><a href='byond://?src=\ref[src];newgame=1'>New Game</a></b></center>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];newgame=1'>New Game</a></b></center>"
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
@@ -769,41 +769,41 @@
|
||||
eventdat += "<br>[deadname] tried to fight back, but was killed."
|
||||
else
|
||||
eventdat += "<br>Fortunately, you fended them off without any trouble."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_FLUX)
|
||||
eventdat += "This region of space is highly turbulent. <br>If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies."
|
||||
eventdat += "<br>What will you do?"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];slow=1'>Slow Down</a> <a href='byond://?src=\ref[src];keepspeed=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];slow=1'>Slow Down</a> <a href='byond://?src=[REF(src)];keepspeed=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
|
||||
if(ORION_TRAIL_ILLNESS)
|
||||
eventdat += "A deadly illness has been contracted!"
|
||||
var/deadname = remove_crewmember()
|
||||
eventdat += "<br>[deadname] was killed by the disease."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_BREAKDOWN)
|
||||
eventdat += "Oh no! The engine has broken down!"
|
||||
eventdat += "<br>You can repair it with an engine part, or you can make repairs for 3 days."
|
||||
if(engine >= 1)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];useengine=1'>Use Part</a><a href='byond://?src=\ref[src];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];useengine=1'>Use Part</a><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
|
||||
if(ORION_TRAIL_MALFUNCTION)
|
||||
eventdat += "The ship's systems are malfunctioning!"
|
||||
eventdat += "<br>You can replace the broken electronics with spares, or you can spend 3 days troubleshooting the AI."
|
||||
if(electronics >= 1)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];useelec=1'>Use Part</a><a href='byond://?src=\ref[src];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];useelec=1'>Use Part</a><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
|
||||
if(ORION_TRAIL_COLLISION)
|
||||
eventdat += "Something hit us! Looks like there's some hull damage."
|
||||
@@ -818,23 +818,23 @@
|
||||
eventdat += "<br>[deadname] was killed by rapid depressurization."
|
||||
eventdat += "<br>You can repair the damage with hull plates, or you can spend the next 3 days welding scrap together."
|
||||
if(hull >= 1)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];usehull=1'>Use Part</a><a href='byond://?src=\ref[src];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];usehull=1'>Use Part</a><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];wait=1'>Wait</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
|
||||
if(ORION_TRAIL_BLACKHOLE)
|
||||
eventdat += "You were swept away into the black hole."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];holedeath=1'>Oh...</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];holedeath=1'>Oh...</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
settlers = list()
|
||||
|
||||
if(ORION_TRAIL_LING)
|
||||
eventdat += "Strange reports warn of changelings infiltrating crews on trips to Orion..."
|
||||
if(settlers.len <= 2)
|
||||
eventdat += "<br>Your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
if(prob(10)) // "likely", I didn't say it was guaranteed!
|
||||
lings_aboard = min(++lings_aboard,2)
|
||||
else
|
||||
@@ -844,9 +844,9 @@
|
||||
else if(prob(70))
|
||||
lings_aboard = min(++lings_aboard,2)
|
||||
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];killcrew=1'>Kill a Crewmember</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];eventclose=1'>Risk it</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];killcrew=1'>Kill a Crewmember</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Risk it</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_LING_ATTACK)
|
||||
@@ -892,8 +892,8 @@
|
||||
else
|
||||
lings_aboard = max(0,--lings_aboard)
|
||||
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
|
||||
@@ -903,8 +903,8 @@
|
||||
eventdat += "The spaceport is on high alert! You've been barred from docking by the local authorities after your failed raid."
|
||||
if(last_spaceport_action)
|
||||
eventdat += "<br><b>Last Spaceport Action:</b> [last_spaceport_action]"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];leave_spaceport=1'>Depart Spaceport</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];leave_spaceport=1'>Depart Spaceport</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
else
|
||||
eventdat += "Your jump into the sector yields a spaceport - a lucky find!"
|
||||
eventdat += "<br>This spaceport is home to travellers who failed to reach Orion, but managed to find a different home..."
|
||||
@@ -943,13 +943,13 @@
|
||||
|
||||
//Buy crew
|
||||
if(food >= 10 && fuel >= 10)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];buycrew=1'>Hire a New Crewmember (-10FU, -10FO)</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];buycrew=1'>Hire a New Crewmember (-10FU, -10FO)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You cannot afford a new crewmember.</P>"
|
||||
|
||||
//Sell crew
|
||||
if(settlers.len > 1)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];sellcrew=1'>Sell Crew for Fuel and Food (+7FU, +7FO)</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];sellcrew=1'>Sell Crew for Fuel and Food (+7FU, +7FO)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You have no other crew to sell.</P>"
|
||||
|
||||
@@ -958,37 +958,37 @@
|
||||
|
||||
//Engine parts
|
||||
if(fuel > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];buyparts=1'>Buy Engine Parts (-5FU)</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];buyparts=1'>Buy Engine Parts (-5FU)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You cannot afford engine parts.</a>"
|
||||
|
||||
//Hull plates
|
||||
if(fuel > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];buyparts=2'>Buy Hull Plates (-5FU)</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];buyparts=2'>Buy Hull Plates (-5FU)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You cannot afford hull plates.</a>"
|
||||
|
||||
//Electronics
|
||||
if(fuel > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];buyparts=3'>Buy Spare Electronics (-5FU)</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];buyparts=3'>Buy Spare Electronics (-5FU)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You cannot afford spare electronics.</a>"
|
||||
|
||||
//Trade
|
||||
if(fuel > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];trade=1'>Trade Fuel for Food (-5FU,+5FO)</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];trade=1'>Trade Fuel for Food (-5FU,+5FO)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You don't have 5FU to trade.</P"
|
||||
|
||||
if(food > 5)
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];trade=2'>Trade Food for Fuel (+5FU,-5FO)</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];trade=2'>Trade Food for Fuel (+5FU,-5FO)</a></P>"
|
||||
else
|
||||
eventdat += "<P ALIGN=Right>You don't have 5FO to trade.</P"
|
||||
|
||||
//Raid the spaceport
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];raid_spaceport=1'>!! Raid Spaceport !!</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];raid_spaceport=1'>!! Raid Spaceport !!</a></P>"
|
||||
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];leave_spaceport=1'>Depart Spaceport</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];leave_spaceport=1'>Depart Spaceport</a></P>"
|
||||
|
||||
|
||||
//Add Random/Specific crewmember
|
||||
|
||||
@@ -145,18 +145,18 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
var/crew = ""
|
||||
for(var/datum/data/record/t in sortRecord(GLOB.data_core.general))
|
||||
crew += t.fields["name"] + " - " + t.fields["rank"] + "<br>"
|
||||
dat = "<tt><b>Crew Manifest:</b><br>Please use security record computer to modify entries.<br><br>[crew]<a href='?src=\ref[src];choice=print'>Print</a><br><br><a href='?src=\ref[src];choice=mode;mode_target=0'>Access ID modification console.</a><br></tt>"
|
||||
dat = "<tt><b>Crew Manifest:</b><br>Please use security record computer to modify entries.<br><br>[crew]<a href='?src=[REF(src)];choice=print'>Print</a><br><br><a href='?src=[REF(src)];choice=mode;mode_target=0'>Access ID modification console.</a><br></tt>"
|
||||
|
||||
else if(mode == 2)
|
||||
// JOB MANAGEMENT
|
||||
dat = "<a href='?src=\ref[src];choice=return'>Return</a>"
|
||||
dat = "<a href='?src=[REF(src)];choice=return'>Return</a>"
|
||||
dat += " || Confirm Identity: "
|
||||
var/S
|
||||
if(scan)
|
||||
S = html_encode(scan.name)
|
||||
else
|
||||
S = "--------"
|
||||
dat += "<a href='?src=\ref[src];choice=scan'>[S]</a>"
|
||||
dat += "<a href='?src=[REF(src)];choice=scan'>[S]</a>"
|
||||
dat += "<table>"
|
||||
dat += "<tr><td style='width:25%'><b>Job</b></td><td style='width:25%'><b>Slots</b></td><td style='width:25%'><b>Open job</b></td><td style='width:25%'><b>Close job</b><td style='width:25%'><b>Prioritize</b></td></td></tr>"
|
||||
var/ID
|
||||
@@ -174,7 +174,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
switch(can_open_job(job))
|
||||
if(1)
|
||||
if(ID)
|
||||
dat += "<a href='?src=\ref[src];choice=make_job_available;job=[job.title]'>Open Position</a><br>"
|
||||
dat += "<a href='?src=[REF(src)];choice=make_job_available;job=[job.title]'>Open Position</a><br>"
|
||||
else
|
||||
dat += "Open Position"
|
||||
if(-1)
|
||||
@@ -190,7 +190,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
switch(can_close_job(job))
|
||||
if(1)
|
||||
if(ID)
|
||||
dat += "<a href='?src=\ref[src];choice=make_job_unavailable;job=[job.title]'>Close Position</a>"
|
||||
dat += "<a href='?src=[REF(src)];choice=make_job_unavailable;job=[job.title]'>Close Position</a>"
|
||||
else
|
||||
dat += "Close Position"
|
||||
if(-1)
|
||||
@@ -209,10 +209,10 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
else
|
||||
if(ID)
|
||||
if(job in SSjob.prioritized_jobs)
|
||||
dat += "<a href='?src=\ref[src];choice=prioritize_job;job=[job.title]'>Deprioritize</a>"
|
||||
dat += "<a href='?src=[REF(src)];choice=prioritize_job;job=[job.title]'>Deprioritize</a>"
|
||||
else
|
||||
if(SSjob.prioritized_jobs.len < 5)
|
||||
dat += "<a href='?src=\ref[src];choice=prioritize_job;job=[job.title]'>Prioritize</a>"
|
||||
dat += "<a href='?src=[REF(src)];choice=prioritize_job;job=[job.title]'>Prioritize</a>"
|
||||
else
|
||||
dat += "Denied"
|
||||
else
|
||||
@@ -247,14 +247,14 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
|
||||
if(!authenticated)
|
||||
header += "<br><i>Please insert the cards into the slots</i><br>"
|
||||
header += "Target: <a href='?src=\ref[src];choice=modify'>[target_name]</a><br>"
|
||||
header += "Confirm Identity: <a href='?src=\ref[src];choice=scan'>[scan_name]</a><br>"
|
||||
header += "Target: <a href='?src=[REF(src)];choice=modify'>[target_name]</a><br>"
|
||||
header += "Confirm Identity: <a href='?src=[REF(src)];choice=scan'>[scan_name]</a><br>"
|
||||
else
|
||||
header += "<div align='center'><br>"
|
||||
header += "<a href='?src=\ref[src];choice=modify'>Remove [target_name]</a> || "
|
||||
header += "<a href='?src=\ref[src];choice=scan'>Remove [scan_name]</a> <br> "
|
||||
header += "<a href='?src=\ref[src];choice=mode;mode_target=1'>Access Crew Manifest</a> <br> "
|
||||
header += "<a href='?src=\ref[src];choice=logout'>Log Out</a></div>"
|
||||
header += "<a href='?src=[REF(src)];choice=modify'>Remove [target_name]</a> || "
|
||||
header += "<a href='?src=[REF(src)];choice=scan'>Remove [scan_name]</a> <br> "
|
||||
header += "<a href='?src=[REF(src)];choice=mode;mode_target=1'>Access Crew Manifest</a> <br> "
|
||||
header += "<a href='?src=[REF(src)];choice=logout'>Log Out</a></div>"
|
||||
|
||||
header += "<hr>"
|
||||
|
||||
@@ -262,7 +262,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
var/list/alljobs = list("Unassigned")
|
||||
alljobs += (istype(src, /obj/machinery/computer/card/centcom)? get_all_centcom_jobs() : get_all_jobs()) + "Custom"
|
||||
for(var/job in alljobs)
|
||||
jobs_all += "<a href='?src=\ref[src];choice=assign;assign_target=[job]'>[replacetext(job, " ", " ")]</a> " //make sure there isn't a line break in the middle of a job
|
||||
jobs_all += "<a href='?src=[REF(src)];choice=assign;assign_target=[job]'>[replacetext(job, " ", " ")]</a> " //make sure there isn't a line break in the middle of a job
|
||||
|
||||
|
||||
var/body
|
||||
@@ -290,8 +290,8 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
allJobsSlot.innerHTML = "<a href='#' onclick='showAll()'>show</a>";
|
||||
}
|
||||
</script>"}
|
||||
carddesc += "<form name='cardcomp' action='?src=\ref[src]' method='get'>"
|
||||
carddesc += "<input type='hidden' name='src' value='\ref[src]'>"
|
||||
carddesc += "<form name='cardcomp' action='?src=[REF(src)]' method='get'>"
|
||||
carddesc += "<input type='hidden' name='src' value='[REF(src)]'>"
|
||||
carddesc += "<input type='hidden' name='choice' value='reg'>"
|
||||
carddesc += "<b>registered name:</b> <input type='text' id='namefield' name='reg' value='[target_owner]' style='width:250px; background-color:white;' onchange='markRed()'>"
|
||||
carddesc += "<input type='submit' value='Rename' onclick='markGreen()'>"
|
||||
@@ -302,16 +302,16 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
|
||||
else
|
||||
carddesc += "<b>registered_name:</b> [target_owner]</span>"
|
||||
jobs += "<b>Assignment:</b> [target_rank] (<a href='?src=\ref[src];choice=demote'>Demote</a>)</span>"
|
||||
jobs += "<b>Assignment:</b> [target_rank] (<a href='?src=[REF(src)];choice=demote'>Demote</a>)</span>"
|
||||
|
||||
var/accesses = ""
|
||||
if(istype(src, /obj/machinery/computer/card/centcom))
|
||||
accesses += "<h5>Central Command:</h5>"
|
||||
for(var/A in get_all_centcom_access())
|
||||
if(A in modify.access)
|
||||
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=0'><font color=\"red\">[replacetext(get_centcom_access_desc(A), " ", " ")]</font></a> "
|
||||
accesses += "<a href='?src=[REF(src)];choice=access;access_target=[A];allowed=0'><font color=\"red\">[replacetext(get_centcom_access_desc(A), " ", " ")]</font></a> "
|
||||
else
|
||||
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=1'>[replacetext(get_centcom_access_desc(A), " ", " ")]</a> "
|
||||
accesses += "<a href='?src=[REF(src)];choice=access;access_target=[A];allowed=1'>[replacetext(get_centcom_access_desc(A), " ", " ")]</a> "
|
||||
else
|
||||
accesses += "<div align='center'><b>Access</b></div>"
|
||||
accesses += "<table style='width:100%'>"
|
||||
@@ -327,19 +327,19 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
accesses += "<td style='width:14%' valign='top'>"
|
||||
for(var/A in get_region_accesses(i))
|
||||
if(A in modify.access)
|
||||
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=0'><font color=\"red\">[replacetext(get_access_desc(A), " ", " ")]</font></a> "
|
||||
accesses += "<a href='?src=[REF(src)];choice=access;access_target=[A];allowed=0'><font color=\"red\">[replacetext(get_access_desc(A), " ", " ")]</font></a> "
|
||||
else
|
||||
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=1'>[replacetext(get_access_desc(A), " ", " ")]</a> "
|
||||
accesses += "<a href='?src=[REF(src)];choice=access;access_target=[A];allowed=1'>[replacetext(get_access_desc(A), " ", " ")]</a> "
|
||||
accesses += "<br>"
|
||||
accesses += "</td>"
|
||||
accesses += "</tr></table>"
|
||||
body = "[carddesc]<br>[jobs]<br><br>[accesses]" //CHECK THIS
|
||||
|
||||
else
|
||||
body = "<a href='?src=\ref[src];choice=auth'>{Log in}</a> <br><hr>"
|
||||
body += "<a href='?src=\ref[src];choice=mode;mode_target=1'>Access Crew Manifest</a>"
|
||||
body = "<a href='?src=[REF(src)];choice=auth'>{Log in}</a> <br><hr>"
|
||||
body += "<a href='?src=[REF(src)];choice=mode;mode_target=1'>Access Crew Manifest</a>"
|
||||
if(!target_dept)
|
||||
body += "<br><hr><a href = '?src=\ref[src];choice=mode;mode_target=2'>Job Management</a>"
|
||||
body += "<br><hr><a href = '?src=[REF(src)];choice=mode;mode_target=2'>Job Management</a>"
|
||||
|
||||
dat = "<tt>[header][body]<hr><br></tt>"
|
||||
var/datum/browser/popup = new(user, "id_com", src.name, 900, 620)
|
||||
|
||||
@@ -83,10 +83,10 @@
|
||||
var/obj/machinery/dna_scannernew/scannerf = null
|
||||
|
||||
// Loop through every direction
|
||||
for(dir in list(NORTH,EAST,SOUTH,WEST))
|
||||
for(var/direction in GLOB.cardinals)
|
||||
|
||||
// Try to find a scanner in that direction
|
||||
scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
|
||||
scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, direction))
|
||||
|
||||
// If found and operational, return the scanner
|
||||
if (!isnull(scannerf) && scannerf.is_operational())
|
||||
@@ -98,10 +98,9 @@
|
||||
/obj/machinery/computer/cloning/proc/findcloner()
|
||||
var/obj/machinery/clonepod/podf = null
|
||||
|
||||
for(dir in list(NORTH,EAST,SOUTH,WEST))
|
||||
|
||||
podf = locate(/obj/machinery/clonepod, get_step(src, dir))
|
||||
for(var/direction in GLOB.cardinals)
|
||||
|
||||
podf = locate(/obj/machinery/clonepod, get_step(src, direction))
|
||||
if (!isnull(podf) && podf.is_operational())
|
||||
AttachCloner(podf)
|
||||
|
||||
@@ -138,7 +137,7 @@
|
||||
AttachCloner(pod)
|
||||
else
|
||||
P.buffer = src
|
||||
to_chat(user, "<font color = #666633>-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-</font color>")
|
||||
to_chat(user, "<font color = #666633>-% Successfully stored [REF(P.buffer)] [P.buffer.name] in buffer %-</font color>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
@@ -158,13 +157,13 @@
|
||||
updatemodules(TRUE)
|
||||
|
||||
var/dat = ""
|
||||
dat += "<a href='byond://?src=\ref[src];refresh=1'>Refresh</a>"
|
||||
dat += "<a href='byond://?src=[REF(src)];refresh=1'>Refresh</a>"
|
||||
|
||||
if(scanner && HasEfficientPod() && scanner.scan_level > 2)
|
||||
if(!autoprocess)
|
||||
dat += "<a href='byond://?src=\ref[src];task=autoprocess'>Autoprocess</a>"
|
||||
dat += "<a href='byond://?src=[REF(src)];task=autoprocess'>Autoprocess</a>"
|
||||
else
|
||||
dat += "<a href='byond://?src=\ref[src];task=stopautoprocess'>Stop autoprocess</a>"
|
||||
dat += "<a href='byond://?src=[REF(src)];task=stopautoprocess'>Stop autoprocess</a>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Autoprocess</span>"
|
||||
dat += "<h3>Cloning Pod Status</h3>"
|
||||
@@ -175,7 +174,7 @@
|
||||
// Modules
|
||||
if (isnull(src.scanner) || !LAZYLEN(pods))
|
||||
dat += "<h3>Modules</h3>"
|
||||
//dat += "<a href='byond://?src=\ref[src];relmodules=1'>Reload Modules</a>"
|
||||
//dat += "<a href='byond://?src=[REF(src)];relmodules=1'>Reload Modules</a>"
|
||||
if (isnull(src.scanner))
|
||||
dat += "<font class='bad'>ERROR: No Scanner detected!</font><br>"
|
||||
if (!LAZYLEN(pods))
|
||||
@@ -200,36 +199,36 @@
|
||||
dat += "</div>"
|
||||
|
||||
if(scanner_occupant)
|
||||
dat += "<a href='byond://?src=\ref[src];scan=1'>Start Scan</a>"
|
||||
dat += "<br><a href='byond://?src=\ref[src];lock=1'>[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]</a>"
|
||||
dat += "<a href='byond://?src=[REF(src)];scan=1'>Start Scan</a>"
|
||||
dat += "<br><a href='byond://?src=[REF(src)];lock=1'>[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]</a>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Start Scan</span>"
|
||||
|
||||
// Database
|
||||
dat += "<h3>Database Functions</h3>"
|
||||
if (src.records.len && src.records.len > 0)
|
||||
dat += "<a href='byond://?src=\ref[src];menu=2'>View Records ([src.records.len])</a><br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];menu=2'>View Records ([src.records.len])</a><br>"
|
||||
else
|
||||
dat += "<span class='linkOff'>View Records (0)</span><br>"
|
||||
if (src.diskette)
|
||||
dat += "<a href='byond://?src=\ref[src];disk=eject'>Eject Disk</a><br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];disk=eject'>Eject Disk</a><br>"
|
||||
|
||||
|
||||
|
||||
if(2)
|
||||
dat += "<h3>Current records</h3>"
|
||||
dat += "<a href='byond://?src=\ref[src];menu=1'><< Back</a><br><br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];menu=1'><< Back</a><br><br>"
|
||||
for(var/datum/data/record/R in records)
|
||||
dat += "<h4>[R.fields["name"]]</h4>Scan ID [R.fields["id"]] <a href='byond://?src=\ref[src];view_rec=[R.fields["id"]]'>View Record</a>"
|
||||
dat += "<h4>[R.fields["name"]]</h4>Scan ID [R.fields["id"]] <a href='byond://?src=[REF(src)];view_rec=[R.fields["id"]]'>View Record</a>"
|
||||
if(3)
|
||||
dat += "<h3>Selected Record</h3>"
|
||||
dat += "<a href='byond://?src=\ref[src];menu=2'><< Back</a><br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];menu=2'><< Back</a><br>"
|
||||
|
||||
if (!src.active_record)
|
||||
dat += "<font class='bad'>Record not found.</font>"
|
||||
else
|
||||
dat += "<h4>[src.active_record.fields["name"]]</h4>"
|
||||
dat += "Scan ID [src.active_record.fields["id"]] <a href='byond://?src=\ref[src];clone=[active_record.fields["id"]]'>Clone</a><br>"
|
||||
dat += "Scan ID [src.active_record.fields["id"]] <a href='byond://?src=[REF(src)];clone=[active_record.fields["id"]]'>Clone</a><br>"
|
||||
|
||||
var/obj/item/implant/health/H = locate(src.active_record.fields["imp"])
|
||||
|
||||
@@ -253,12 +252,12 @@
|
||||
if(diskette.fields["SE"])
|
||||
L += "Structural Enzymes"
|
||||
dat += english_list(L, "Empty", " + ", " + ")
|
||||
dat += "<br /><a href='byond://?src=\ref[src];disk=load'>Load from Disk</a>"
|
||||
dat += "<br /><a href='byond://?src=[REF(src)];disk=load'>Load from Disk</a>"
|
||||
|
||||
dat += "<br /><a href='byond://?src=\ref[src];disk=save'>Save to Disk</a>"
|
||||
dat += "<br /><a href='byond://?src=[REF(src)];disk=save'>Save to Disk</a>"
|
||||
dat += "</div>"
|
||||
|
||||
dat += "<font size=1><a href='byond://?src=\ref[src];del_rec=1'>Delete Record</a></font>"
|
||||
dat += "<font size=1><a href='byond://?src=[REF(src)];del_rec=1'>Delete Record</a></font>"
|
||||
|
||||
if(4)
|
||||
if (!src.active_record)
|
||||
@@ -266,8 +265,8 @@
|
||||
dat = "[src.temp]<br>"
|
||||
dat += "<h3>Confirm Record Deletion</h3>"
|
||||
|
||||
dat += "<b><a href='byond://?src=\ref[src];del_rec=1'>Scan card to confirm.</a></b><br>"
|
||||
dat += "<b><a href='byond://?src=\ref[src];menu=3'>Cancel</a></b>"
|
||||
dat += "<b><a href='byond://?src=[REF(src)];del_rec=1'>Scan card to confirm.</a></b><br>"
|
||||
dat += "<b><a href='byond://?src=[REF(src)];menu=3'>Cancel</a></b>"
|
||||
|
||||
|
||||
var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
|
||||
@@ -484,7 +483,7 @@
|
||||
R.fields["factions"] = mob_occupant.faction
|
||||
|
||||
if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning.
|
||||
R.fields["mind"] = "\ref[mob_occupant.mind]"
|
||||
R.fields["mind"] = "[REF(mob_occupant.mind)]"
|
||||
|
||||
//Add an implant if needed
|
||||
var/obj/item/implant/health/imp
|
||||
@@ -494,7 +493,7 @@
|
||||
if(!imp)
|
||||
imp = new /obj/item/implant/health(mob_occupant)
|
||||
imp.implant(mob_occupant)
|
||||
R.fields["imp"] = "\ref[imp]"
|
||||
R.fields["imp"] = "[REF(imp)]"
|
||||
|
||||
src.records += R
|
||||
scantemp = "Subject successfully scanned."
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
circuit = /obj/item/circuitboard/computer/communications
|
||||
var/authenticated = 0
|
||||
var/auth_id = "Unknown" //Who is currently logged in?
|
||||
var/list/messagetitle = list()
|
||||
var/list/messagetext = list()
|
||||
var/currmsg = 0
|
||||
var/aicurrmsg = 0
|
||||
var/list/datum/comm_message/messages = list()
|
||||
var/datum/comm_message/currmsg
|
||||
var/datum/comm_message/aicurrmsg
|
||||
var/state = STATE_DEFAULT
|
||||
var/aistate = STATE_DEFAULT
|
||||
var/message_cooldown = 0
|
||||
@@ -48,7 +47,7 @@
|
||||
/obj/machinery/computer/communications/process()
|
||||
if(..())
|
||||
if(state != STATE_STATUSDISPLAY)
|
||||
src.updateDialog()
|
||||
updateDialog()
|
||||
|
||||
|
||||
/obj/machinery/computer/communications/Topic(href, href_list)
|
||||
@@ -65,7 +64,7 @@
|
||||
switch(href_list["operation"])
|
||||
// main interface
|
||||
if("main")
|
||||
src.state = STATE_DEFAULT
|
||||
state = STATE_DEFAULT
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
if("login")
|
||||
var/mob/M = usr
|
||||
@@ -75,13 +74,13 @@
|
||||
I = M.get_idcard()
|
||||
|
||||
if(I && istype(I))
|
||||
if(src.check_access(I))
|
||||
if(check_access(I))
|
||||
authenticated = 1
|
||||
auth_id = "[I.registered_name] ([I.assignment])"
|
||||
if((20 in I.access))
|
||||
authenticated = 2
|
||||
playsound(src, 'sound/machines/terminal_on.ogg', 50, 0)
|
||||
if(src.emagged)
|
||||
if(emagged)
|
||||
authenticated = 2
|
||||
auth_id = "Unknown"
|
||||
to_chat(M, "<span class='warning'>[src] lets out a quiet alarm as its login is overriden.</span>")
|
||||
@@ -132,7 +131,7 @@
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
|
||||
if("announce")
|
||||
if(src.authenticated==2)
|
||||
if(authenticated==2)
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
make_announcement(usr)
|
||||
|
||||
@@ -186,53 +185,60 @@
|
||||
to_chat(usr, "Not enough credits.")
|
||||
|
||||
if("callshuttle")
|
||||
src.state = STATE_DEFAULT
|
||||
if(src.authenticated)
|
||||
src.state = STATE_CALLSHUTTLE
|
||||
state = STATE_DEFAULT
|
||||
if(authenticated)
|
||||
state = STATE_CALLSHUTTLE
|
||||
if("callshuttle2")
|
||||
if(src.authenticated)
|
||||
if(authenticated)
|
||||
SSshuttle.requestEvac(usr, href_list["call"])
|
||||
if(SSshuttle.emergency.timer)
|
||||
post_status("shuttle")
|
||||
src.state = STATE_DEFAULT
|
||||
state = STATE_DEFAULT
|
||||
if("cancelshuttle")
|
||||
src.state = STATE_DEFAULT
|
||||
if(src.authenticated)
|
||||
src.state = STATE_CANCELSHUTTLE
|
||||
state = STATE_DEFAULT
|
||||
if(authenticated)
|
||||
state = STATE_CANCELSHUTTLE
|
||||
if("cancelshuttle2")
|
||||
if(src.authenticated)
|
||||
if(authenticated)
|
||||
SSshuttle.cancelEvac(usr)
|
||||
src.state = STATE_DEFAULT
|
||||
state = STATE_DEFAULT
|
||||
if("messagelist")
|
||||
src.currmsg = 0
|
||||
src.state = STATE_MESSAGELIST
|
||||
currmsg = 0
|
||||
state = STATE_MESSAGELIST
|
||||
if("viewmessage")
|
||||
src.state = STATE_VIEWMESSAGE
|
||||
if (!src.currmsg)
|
||||
state = STATE_VIEWMESSAGE
|
||||
if (!currmsg)
|
||||
if(href_list["message-num"])
|
||||
src.currmsg = text2num(href_list["message-num"])
|
||||
var/msgnum = text2num(href_list["message-num"])
|
||||
currmsg = messages[msgnum]
|
||||
else
|
||||
src.state = STATE_MESSAGELIST
|
||||
state = STATE_MESSAGELIST
|
||||
if("delmessage")
|
||||
src.state = (src.currmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
|
||||
state = currmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST
|
||||
if("delmessage2")
|
||||
if(src.authenticated)
|
||||
if(src.currmsg)
|
||||
var/title = src.messagetitle[src.currmsg]
|
||||
var/text = src.messagetext[src.currmsg]
|
||||
src.messagetitle.Remove(title)
|
||||
src.messagetext.Remove(text)
|
||||
if(src.currmsg == src.aicurrmsg)
|
||||
src.aicurrmsg = 0
|
||||
src.currmsg = 0
|
||||
src.state = STATE_MESSAGELIST
|
||||
if(authenticated)
|
||||
if(currmsg)
|
||||
if(aicurrmsg == currmsg)
|
||||
aicurrmsg = null
|
||||
messages -= currmsg
|
||||
currmsg = null
|
||||
state = STATE_MESSAGELIST
|
||||
else
|
||||
src.state = STATE_VIEWMESSAGE
|
||||
state = STATE_VIEWMESSAGE
|
||||
if("respond")
|
||||
var/answer = text2num(href_list["answer"])
|
||||
if(!currmsg || !answer || currmsg.possible_answers.len < answer)
|
||||
state = STATE_MESSAGELIST
|
||||
currmsg.answered = answer
|
||||
log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]")
|
||||
if(currmsg)
|
||||
currmsg.answer_callback.Invoke()
|
||||
|
||||
state = STATE_VIEWMESSAGE
|
||||
if("status")
|
||||
src.state = STATE_STATUSDISPLAY
|
||||
|
||||
state = STATE_STATUSDISPLAY
|
||||
if("securitylevel")
|
||||
src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
|
||||
tmp_alertlevel = text2num( href_list["newalertlevel"] )
|
||||
if(!tmp_alertlevel)
|
||||
tmp_alertlevel = 0
|
||||
state = STATE_CONFIRM_LEVEL
|
||||
@@ -245,12 +251,12 @@
|
||||
make_maint_all_access()
|
||||
log_game("[key_name(usr)] enabled emergency maintenance access.")
|
||||
message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
|
||||
src.state = STATE_DEFAULT
|
||||
state = STATE_DEFAULT
|
||||
if("disableemergency")
|
||||
revoke_maint_all_access()
|
||||
log_game("[key_name(usr)] disabled emergency maintenance access.")
|
||||
message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
|
||||
src.state = STATE_DEFAULT
|
||||
state = STATE_DEFAULT
|
||||
|
||||
// Status display stuff
|
||||
if("setstat")
|
||||
@@ -265,14 +271,14 @@
|
||||
|
||||
if("setmsg1")
|
||||
stat_msg1 = reject_bad_text(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40)
|
||||
src.updateDialog()
|
||||
updateDialog()
|
||||
if("setmsg2")
|
||||
stat_msg2 = reject_bad_text(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40)
|
||||
src.updateDialog()
|
||||
updateDialog()
|
||||
|
||||
// OMG CENTCOM LETTERHEAD
|
||||
if("MessageCentCom")
|
||||
if(src.authenticated==2)
|
||||
if(authenticated==2)
|
||||
if(!checkCCcooldown())
|
||||
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
|
||||
return
|
||||
@@ -288,7 +294,7 @@
|
||||
|
||||
// OMG SYNDICATE ...LETTERHEAD
|
||||
if("MessageSyndicate")
|
||||
if((src.authenticated==2) && (src.emagged))
|
||||
if((authenticated==2) && (emagged))
|
||||
if(!checkCCcooldown())
|
||||
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
|
||||
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
|
||||
@@ -306,10 +312,10 @@
|
||||
to_chat(usr, "<span class='notice'>Backup routing data restored!</span>")
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
emagged = FALSE
|
||||
src.updateDialog()
|
||||
updateDialog()
|
||||
|
||||
if("nukerequest") //When there's no other way
|
||||
if(src.authenticated==2)
|
||||
if(authenticated==2)
|
||||
if(!checkCCcooldown())
|
||||
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
|
||||
return
|
||||
@@ -325,41 +331,48 @@
|
||||
|
||||
// AI interface
|
||||
if("ai-main")
|
||||
src.aicurrmsg = 0
|
||||
src.aistate = STATE_DEFAULT
|
||||
aicurrmsg = null
|
||||
aistate = STATE_DEFAULT
|
||||
if("ai-callshuttle")
|
||||
src.aistate = STATE_CALLSHUTTLE
|
||||
aistate = STATE_CALLSHUTTLE
|
||||
if("ai-callshuttle2")
|
||||
SSshuttle.requestEvac(usr, href_list["call"])
|
||||
src.aistate = STATE_DEFAULT
|
||||
aistate = STATE_DEFAULT
|
||||
if("ai-messagelist")
|
||||
src.aicurrmsg = 0
|
||||
src.aistate = STATE_MESSAGELIST
|
||||
aicurrmsg = null
|
||||
aistate = STATE_MESSAGELIST
|
||||
if("ai-viewmessage")
|
||||
src.aistate = STATE_VIEWMESSAGE
|
||||
if (!src.aicurrmsg)
|
||||
aistate = STATE_VIEWMESSAGE
|
||||
if (!aicurrmsg)
|
||||
if(href_list["message-num"])
|
||||
src.aicurrmsg = text2num(href_list["message-num"])
|
||||
var/msgnum = text2num(href_list["message-num"])
|
||||
aicurrmsg = messages[msgnum]
|
||||
else
|
||||
src.aistate = STATE_MESSAGELIST
|
||||
aistate = STATE_MESSAGELIST
|
||||
if("ai-delmessage")
|
||||
src.aistate = (src.aicurrmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST
|
||||
aistate = aicurrmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST
|
||||
if("ai-delmessage2")
|
||||
if(src.aicurrmsg)
|
||||
var/title = src.messagetitle[src.aicurrmsg]
|
||||
var/text = src.messagetext[src.aicurrmsg]
|
||||
src.messagetitle.Remove(title)
|
||||
src.messagetext.Remove(text)
|
||||
if(src.currmsg == src.aicurrmsg)
|
||||
src.currmsg = 0
|
||||
src.aicurrmsg = 0
|
||||
src.aistate = STATE_MESSAGELIST
|
||||
if(aicurrmsg)
|
||||
if(currmsg == aicurrmsg)
|
||||
currmsg = null
|
||||
messages -= aicurrmsg
|
||||
aicurrmsg = null
|
||||
aistate = STATE_MESSAGELIST
|
||||
if("ai-respond")
|
||||
var/answer = text2num(href_list["answer"])
|
||||
if(!aicurrmsg || !answer || aicurrmsg.possible_answers.len < answer)
|
||||
aistate = STATE_MESSAGELIST
|
||||
aicurrmsg.answered = answer
|
||||
log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]")
|
||||
if(aicurrmsg.answer_callback)
|
||||
aicurrmsg.answer_callback.Invoke()
|
||||
aistate = STATE_VIEWMESSAGE
|
||||
if("ai-status")
|
||||
src.aistate = STATE_STATUSDISPLAY
|
||||
aistate = STATE_STATUSDISPLAY
|
||||
if("ai-announce")
|
||||
make_announcement(usr, 1)
|
||||
if("ai-securitylevel")
|
||||
src.tmp_alertlevel = text2num( href_list["newalertlevel"] )
|
||||
tmp_alertlevel = text2num( href_list["newalertlevel"] )
|
||||
if(!tmp_alertlevel)
|
||||
tmp_alertlevel = 0
|
||||
var/old_level = GLOB.security_level
|
||||
@@ -380,24 +393,23 @@
|
||||
if(SEC_LEVEL_BLUE)
|
||||
SSblackbox.inc("alert_comms_blue",1)
|
||||
tmp_alertlevel = 0
|
||||
src.aistate = STATE_DEFAULT
|
||||
aistate = STATE_DEFAULT
|
||||
if("ai-changeseclevel")
|
||||
src.aistate = STATE_ALERT_LEVEL
|
||||
|
||||
aistate = STATE_ALERT_LEVEL
|
||||
if("ai-emergencyaccess")
|
||||
src.aistate = STATE_TOGGLE_EMERGENCY
|
||||
aistate = STATE_TOGGLE_EMERGENCY
|
||||
if("ai-enableemergency")
|
||||
make_maint_all_access()
|
||||
log_game("[key_name(usr)] enabled emergency maintenance access.")
|
||||
message_admins("[key_name_admin(usr)] enabled emergency maintenance access.")
|
||||
src.aistate = STATE_DEFAULT
|
||||
aistate = STATE_DEFAULT
|
||||
if("ai-disableemergency")
|
||||
revoke_maint_all_access()
|
||||
log_game("[key_name(usr)] disabled emergency maintenance access.")
|
||||
message_admins("[key_name_admin(usr)] disabled emergency maintenance access.")
|
||||
src.aistate = STATE_DEFAULT
|
||||
aistate = STATE_DEFAULT
|
||||
|
||||
src.updateUsrDialog()
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/computer/communications/attackby(obj/I, mob/user, params)
|
||||
if(istype(I, /obj/item/card/id))
|
||||
@@ -417,7 +429,7 @@
|
||||
/obj/machinery/computer/communications/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
if (src.z > 6)
|
||||
if (z > 6)
|
||||
to_chat(user, "<span class='boldannounce'>Unable to establish a connection</span>: \black You're too far away from the station!")
|
||||
return
|
||||
|
||||
@@ -429,19 +441,19 @@
|
||||
|
||||
|
||||
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
|
||||
if(issilicon(user))
|
||||
var/dat2 = src.interact_ai(user) // give the AI a different interact proc to limit its access
|
||||
var/dat2 = interact_ai(user) // give the AI a different interact proc to limit its access
|
||||
if(dat2)
|
||||
dat += dat2
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
return
|
||||
|
||||
switch(src.state)
|
||||
switch(state)
|
||||
if(STATE_DEFAULT)
|
||||
if (src.authenticated)
|
||||
if (authenticated)
|
||||
if(SSshuttle.emergencyCallAmount)
|
||||
if(SSshuttle.emergencyLastCallLoc)
|
||||
dat += "Most recent shuttle call/recall traced to: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b><BR>"
|
||||
@@ -449,33 +461,33 @@
|
||||
dat += "Unable to trace most recent shuttle call/recall signal.<BR>"
|
||||
dat += "Logged in as: [auth_id]"
|
||||
dat += "<BR>"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=logout'>Log Out</A> \]<BR>"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=logout'>Log Out</A> \]<BR>"
|
||||
dat += "<BR><B>General Functions</B>"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=messagelist'>Message List</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=messagelist'>Message List</A> \]"
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_IDLE, SHUTTLE_RECALL)
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=callshuttle'>Call Emergency Shuttle</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=callshuttle'>Call Emergency Shuttle</A> \]"
|
||||
else
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=cancelshuttle'>Cancel Shuttle Call</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=cancelshuttle'>Cancel Shuttle Call</A> \]"
|
||||
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=status'>Set Status Display</A> \]"
|
||||
if (src.authenticated==2)
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=status'>Set Status Display</A> \]"
|
||||
if (authenticated==2)
|
||||
dat += "<BR><BR><B>Captain Functions</B>"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=announce'>Make a Captain's Announcement</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=announce'>Make a Captain's Announcement</A> \]"
|
||||
if(CONFIG_GET(string/cross_server_address))
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=crossserver'>Send a message to an allied station</A> \]"
|
||||
if(SSmapping.config.allow_custom_shuttles == "yes")
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=purchase_menu'>Purchase Shuttle</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=changeseclevel'>Change Alert Level</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=emergencyaccess'>Emergency Maintenance Access</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=nukerequest'>Request Nuclear Authentication Codes</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=crossserver'>Send a message to an allied station</A> \]"
|
||||
if(SSmapping.config.allow_custom_shuttles)
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=purchase_menu'>Purchase Shuttle</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=changeseclevel'>Change Alert Level</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=emergencyaccess'>Emergency Maintenance Access</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=nukerequest'>Request Nuclear Authentication Codes</A> \]"
|
||||
if(!emagged)
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=MessageCentCom'>Send Message to CentCom</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=MessageCentCom'>Send Message to CentCom</A> \]"
|
||||
else
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=MessageSyndicate'>Send Message to \[UNKNOWN\]</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=RestoreBackup'>Restore Backup Routing Data</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=MessageSyndicate'>Send Message to \[UNKNOWN\]</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=RestoreBackup'>Restore Backup Routing Data</A> \]"
|
||||
else
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=login'>Log In</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=login'>Log In</A> \]"
|
||||
if(STATE_CALLSHUTTLE)
|
||||
dat += get_call_shuttle_form()
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
@@ -484,56 +496,63 @@
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
if(STATE_MESSAGELIST)
|
||||
dat += "Messages:"
|
||||
for(var/i = 1; i<=src.messagetitle.len; i++)
|
||||
dat += "<BR><A HREF='?src=\ref[src];operation=viewmessage;message-num=[i]'>[src.messagetitle[i]]</A>"
|
||||
for(var/i in 1 to messages.len)
|
||||
var/datum/comm_message/M = messages[i]
|
||||
dat += "<BR><A HREF='?src=[REF(src)];operation=viewmessage;message-num=[i]'>[M.title]</A>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
if(STATE_VIEWMESSAGE)
|
||||
if (src.currmsg)
|
||||
dat += "<B>[src.messagetitle[src.currmsg]]</B><BR><BR>[src.messagetext[src.currmsg]]"
|
||||
if (src.authenticated)
|
||||
dat += "<BR><BR>\[ <A HREF='?src=\ref[src];operation=delmessage'>Delete</a> \]"
|
||||
if (currmsg)
|
||||
dat += "<B>[currmsg.title]</B><BR><BR>[currmsg.content]"
|
||||
if(!currmsg.answered && currmsg.possible_answers.len)
|
||||
for(var/i in 1 to currmsg.possible_answers.len)
|
||||
var/answer = currmsg.possible_answers[i]
|
||||
dat += "<br>\[ <A HREF='?src=[REF(src)];operation=respond;answer=[i]'>Answer : [answer]</A> \]"
|
||||
else if(currmsg.answered)
|
||||
var/answered = currmsg.possible_answers[currmsg.answered]
|
||||
dat += "<br> Archived Answer : [answered]"
|
||||
dat += "<BR><BR>\[ <A HREF='?src=[REF(src)];operation=delmessage'>Delete</A> \]"
|
||||
else
|
||||
src.state = STATE_MESSAGELIST
|
||||
src.attack_hand(user)
|
||||
return
|
||||
aistate = STATE_MESSAGELIST
|
||||
attack_hand(user)
|
||||
return null
|
||||
if(STATE_DELMESSAGE)
|
||||
if (src.currmsg)
|
||||
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=\ref[src];operation=delmessage2'>OK</A> | <A HREF='?src=\ref[src];operation=viewmessage'>Cancel</A> \]"
|
||||
if (currmsg)
|
||||
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=[REF(src)];operation=delmessage2'>OK</A> | <A HREF='?src=[REF(src)];operation=viewmessage'>Cancel</A> \]"
|
||||
else
|
||||
src.state = STATE_MESSAGELIST
|
||||
src.attack_hand(user)
|
||||
state = STATE_MESSAGELIST
|
||||
attack_hand(user)
|
||||
return
|
||||
if(STATE_STATUSDISPLAY)
|
||||
dat += "Set Status Displays<BR>"
|
||||
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=blank'>Clear</A> \]<BR>"
|
||||
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
|
||||
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=message'>Message</A> \]"
|
||||
dat += "<ul><li> Line 1: <A HREF='?src=\ref[src];operation=setmsg1'>[ stat_msg1 ? stat_msg1 : "(none)"]</A>"
|
||||
dat += "<li> Line 2: <A HREF='?src=\ref[src];operation=setmsg2'>[ stat_msg2 ? stat_msg2 : "(none)"]</A></ul><br>"
|
||||
dat += "\[ Alert: <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=default'>None</A> |"
|
||||
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
|
||||
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
|
||||
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
|
||||
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=blank'>Clear</A> \]<BR>"
|
||||
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
|
||||
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=message'>Message</A> \]"
|
||||
dat += "<ul><li> Line 1: <A HREF='?src=[REF(src)];operation=setmsg1'>[ stat_msg1 ? stat_msg1 : "(none)"]</A>"
|
||||
dat += "<li> Line 2: <A HREF='?src=[REF(src)];operation=setmsg2'>[ stat_msg2 ? stat_msg2 : "(none)"]</A></ul><br>"
|
||||
dat += "\[ Alert: <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=default'>None</A> |"
|
||||
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
|
||||
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
|
||||
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
if(STATE_ALERT_LEVEL)
|
||||
dat += "Current alert level: [get_security_level()]<BR>"
|
||||
if(GLOB.security_level == SEC_LEVEL_DELTA)
|
||||
dat += "<font color='red'><b>The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate.</b></font>"
|
||||
else
|
||||
dat += "<A HREF='?src=\ref[src];operation=securitylevel;newalertlevel=[SEC_LEVEL_BLUE]'>Blue</A><BR>"
|
||||
dat += "<A HREF='?src=\ref[src];operation=securitylevel;newalertlevel=[SEC_LEVEL_GREEN]'>Green</A>"
|
||||
dat += "<A HREF='?src=[REF(src)];operation=securitylevel;newalertlevel=[SEC_LEVEL_BLUE]'>Blue</A><BR>"
|
||||
dat += "<A HREF='?src=[REF(src)];operation=securitylevel;newalertlevel=[SEC_LEVEL_GREEN]'>Green</A>"
|
||||
if(STATE_CONFIRM_LEVEL)
|
||||
dat += "Current alert level: [get_security_level()]<BR>"
|
||||
dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]<BR>"
|
||||
dat += "<A HREF='?src=\ref[src];operation=swipeidseclevel'>Swipe ID</A> to confirm change.<BR>"
|
||||
dat += "<A HREF='?src=[REF(src)];operation=swipeidseclevel'>Swipe ID</A> to confirm change.<BR>"
|
||||
if(STATE_TOGGLE_EMERGENCY)
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
if(GLOB.emergency_access == 1)
|
||||
dat += "<b>Emergency Maintenance Access is currently <font color='red'>ENABLED</font></b>"
|
||||
dat += "<BR>Restore maintenance access restrictions? <BR>\[ <A HREF='?src=\ref[src];operation=disableemergency'>OK</A> | <A HREF='?src=\ref[src];operation=viewmessage'>Cancel</A> \]"
|
||||
dat += "<BR>Restore maintenance access restrictions? <BR>\[ <A HREF='?src=[REF(src)];operation=disableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=viewmessage'>Cancel</A> \]"
|
||||
else
|
||||
dat += "<b>Emergency Maintenance Access is currently <font color='green'>DISABLED</font></b>"
|
||||
dat += "<BR>Lift access restrictions on maintenance and external airlocks? <BR>\[ <A HREF='?src=\ref[src];operation=enableemergency'>OK</A> | <A HREF='?src=\ref[src];operation=viewmessage'>Cancel</A> \]"
|
||||
dat += "<BR>Lift access restrictions on maintenance and external airlocks? <BR>\[ <A HREF='?src=[REF(src)];operation=enableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=viewmessage'>Cancel</A> \]"
|
||||
|
||||
if(STATE_PURCHASE)
|
||||
dat += "Budget: [SSshuttle.points] Credits.<BR>"
|
||||
@@ -544,9 +563,9 @@
|
||||
dat += "[S.description]<BR>"
|
||||
if(S.prerequisites)
|
||||
dat += "Prerequisites: [S.prerequisites]<BR>"
|
||||
dat += "<A href='?src=\ref[src];operation=buyshuttle;chosen_shuttle=\ref[S]'>(<font color=red><i>Purchase</i></font>)</A><BR><BR>"
|
||||
dat += "<A href='?src=[REF(src)];operation=buyshuttle;chosen_shuttle=[REF(S)]'>(<font color=red><i>Purchase</i></font>)</A><BR><BR>"
|
||||
|
||||
dat += "<BR><BR>\[ [(src.state != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
|
||||
dat += "<BR><BR>\[ [(state != STATE_DEFAULT) ? "<A HREF='?src=[REF(src)];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=[REF(user)];mach_close=communications'>Close</A> \]"
|
||||
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
@@ -573,8 +592,8 @@
|
||||
/obj/machinery/computer/communications/proc/get_call_shuttle_form(ai_interface = 0)
|
||||
var/form_id = "callshuttle"
|
||||
var/dat = get_javascript_header(form_id)
|
||||
dat += "<form name='callshuttle' id='[form_id]' action='?src=\ref[src]' method='get' style='display: inline'>"
|
||||
dat += "<input type='hidden' name='src' value='\ref[src]'>"
|
||||
dat += "<form name='callshuttle' id='[form_id]' action='?src=[REF(src)]' method='get' style='display: inline'>"
|
||||
dat += "<input type='hidden' name='src' value='[REF(src)]'>"
|
||||
dat += "<input type='hidden' name='operation' value='[ai_interface ? "ai-callshuttle2" : "callshuttle2"]'>"
|
||||
dat += "<b>Nature of emergency:</b><BR> <input type='text' id='reasonfield' name='call' style='width:250px; background-color:#FFDDDD; onkeydown='getLength() onkeyup='getLength()' onkeypress='getLength()'>"
|
||||
dat += "<BR>Are you sure you want to call the shuttle? \[ <a href='#' onclick='submit()'>Call</a> \]"
|
||||
@@ -583,8 +602,8 @@
|
||||
/obj/machinery/computer/communications/proc/get_cancel_shuttle_form()
|
||||
var/form_id = "cancelshuttle"
|
||||
var/dat = get_javascript_header(form_id)
|
||||
dat += "<form name='cancelshuttle' id='[form_id]' action='?src=\ref[src]' method='get' style='display: inline'>"
|
||||
dat += "<input type='hidden' name='src' value='\ref[src]'>"
|
||||
dat += "<form name='cancelshuttle' id='[form_id]' action='?src=[REF(src)]' method='get' style='display: inline'>"
|
||||
dat += "<input type='hidden' name='src' value='[REF(src)]'>"
|
||||
dat += "<input type='hidden' name='operation' value='cancelshuttle2'>"
|
||||
|
||||
dat += "<BR>Are you sure you want to cancel the shuttle? \[ <a href='#' onclick='submit()'>Cancel</a> \]"
|
||||
@@ -592,7 +611,7 @@
|
||||
|
||||
/obj/machinery/computer/communications/proc/interact_ai(mob/living/silicon/ai/user)
|
||||
var/dat = ""
|
||||
switch(src.aistate)
|
||||
switch(aistate)
|
||||
if(STATE_DEFAULT)
|
||||
if(SSshuttle.emergencyCallAmount)
|
||||
if(SSshuttle.emergencyLastCallLoc)
|
||||
@@ -604,65 +623,73 @@
|
||||
else
|
||||
dat += "Current login: None"
|
||||
dat += "<BR><BR><B>General Functions</B>"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=ai-messagelist'>Message List</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-messagelist'>Message List</A> \]"
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_IDLE)
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=ai-callshuttle'>Call Emergency Shuttle</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=ai-status'>Set Status Display</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-callshuttle'>Call Emergency Shuttle</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-status'>Set Status Display</A> \]"
|
||||
dat += "<BR><BR><B>Special Functions</B>"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=ai-announce'>Make an Announcement</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=ai-changeseclevel'>Change Alert Level</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=ai-emergencyaccess'>Emergency Maintenance Access</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-announce'>Make an Announcement</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-changeseclevel'>Change Alert Level</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=ai-emergencyaccess'>Emergency Maintenance Access</A> \]"
|
||||
if(STATE_CALLSHUTTLE)
|
||||
dat += get_call_shuttle_form(1)
|
||||
if(STATE_MESSAGELIST)
|
||||
dat += "Messages:"
|
||||
for(var/i = 1; i<=src.messagetitle.len; i++)
|
||||
dat += "<BR><A HREF='?src=\ref[src];operation=ai-viewmessage;message-num=[i]'>[src.messagetitle[i]]</A>"
|
||||
for(var/i in 1 to messages.len)
|
||||
var/datum/comm_message/M = messages[i]
|
||||
dat += "<BR><A HREF='?src=[REF(src)];operation=ai-viewmessage;message-num=[i]'>[M.title]</A>"
|
||||
if(STATE_VIEWMESSAGE)
|
||||
if (src.aicurrmsg)
|
||||
dat += "<B>[src.messagetitle[src.aicurrmsg]]</B><BR><BR>[src.messagetext[src.aicurrmsg]]"
|
||||
dat += "<BR><BR>\[ <A HREF='?src=\ref[src];operation=ai-delmessage'>Delete</A> \]"
|
||||
if (aicurrmsg)
|
||||
dat += "<B>[aicurrmsg.title]</B><BR><BR>[aicurrmsg.content]"
|
||||
if(!aicurrmsg.answered && aicurrmsg.possible_answers.len)
|
||||
for(var/i in 1 to aicurrmsg.possible_answers.len)
|
||||
var/answer = aicurrmsg.possible_answers[i]
|
||||
dat += "<br>\[ <A HREF='?src=[REF(src)];operation=ai-respond;answer=[i]'>Answer : [answer]</A> \]"
|
||||
else if(aicurrmsg.answered)
|
||||
var/answered = aicurrmsg.possible_answers[aicurrmsg.answered]
|
||||
dat += "<br> Archived Answer : [answered]"
|
||||
dat += "<BR><BR>\[ <A HREF='?src=[REF(src)];operation=ai-delmessage'>Delete</A> \]"
|
||||
else
|
||||
src.aistate = STATE_MESSAGELIST
|
||||
src.attack_hand(user)
|
||||
aistate = STATE_MESSAGELIST
|
||||
attack_hand(user)
|
||||
return null
|
||||
if(STATE_DELMESSAGE)
|
||||
if(src.aicurrmsg)
|
||||
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=\ref[src];operation=ai-delmessage2'>OK</A> | <A HREF='?src=\ref[src];operation=ai-viewmessage'>Cancel</A> \]"
|
||||
if(aicurrmsg)
|
||||
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=[REF(src)];operation=ai-delmessage2'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
|
||||
else
|
||||
src.aistate = STATE_MESSAGELIST
|
||||
src.attack_hand(user)
|
||||
aistate = STATE_MESSAGELIST
|
||||
attack_hand(user)
|
||||
return
|
||||
|
||||
if(STATE_STATUSDISPLAY)
|
||||
dat += "Set Status Displays<BR>"
|
||||
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=blank'>Clear</A> \]<BR>"
|
||||
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
|
||||
dat += "\[ <A HREF='?src=\ref[src];operation=setstat;statdisp=message'>Message</A> \]"
|
||||
dat += "<ul><li> Line 1: <A HREF='?src=\ref[src];operation=setmsg1'>[ stat_msg1 ? stat_msg1 : "(none)"]</A>"
|
||||
dat += "<li> Line 2: <A HREF='?src=\ref[src];operation=setmsg2'>[ stat_msg2 ? stat_msg2 : "(none)"]</A></ul><br>"
|
||||
dat += "\[ Alert: <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=default'>None</A> |"
|
||||
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
|
||||
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
|
||||
dat += " <A HREF='?src=\ref[src];operation=setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
|
||||
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=blank'>Clear</A> \]<BR>"
|
||||
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
|
||||
dat += "\[ <A HREF='?src=[REF(src)];operation=setstat;statdisp=message'>Message</A> \]"
|
||||
dat += "<ul><li> Line 1: <A HREF='?src=[REF(src)];operation=setmsg1'>[ stat_msg1 ? stat_msg1 : "(none)"]</A>"
|
||||
dat += "<li> Line 2: <A HREF='?src=[REF(src)];operation=setmsg2'>[ stat_msg2 ? stat_msg2 : "(none)"]</A></ul><br>"
|
||||
dat += "\[ Alert: <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=default'>None</A> |"
|
||||
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
|
||||
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
|
||||
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
|
||||
|
||||
if(STATE_ALERT_LEVEL)
|
||||
dat += "Current alert level: [get_security_level()]<BR>"
|
||||
if(GLOB.security_level == SEC_LEVEL_DELTA)
|
||||
dat += "<font color='red'><b>The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate.</b></font>"
|
||||
else
|
||||
dat += "<A HREF='?src=\ref[src];operation=ai-securitylevel;newalertlevel=[SEC_LEVEL_BLUE]'>Blue</A><BR>"
|
||||
dat += "<A HREF='?src=\ref[src];operation=ai-securitylevel;newalertlevel=[SEC_LEVEL_GREEN]'>Green</A>"
|
||||
dat += "<A HREF='?src=[REF(src)];operation=ai-securitylevel;newalertlevel=[SEC_LEVEL_BLUE]'>Blue</A><BR>"
|
||||
dat += "<A HREF='?src=[REF(src)];operation=ai-securitylevel;newalertlevel=[SEC_LEVEL_GREEN]'>Green</A>"
|
||||
|
||||
if(STATE_TOGGLE_EMERGENCY)
|
||||
if(GLOB.emergency_access == 1)
|
||||
dat += "<b>Emergency Maintenance Access is currently <font color='red'>ENABLED</font></b>"
|
||||
dat += "<BR>Restore maintenance access restrictions? <BR>\[ <A HREF='?src=\ref[src];operation=ai-disableemergency'>OK</A> | <A HREF='?src=\ref[src];operation=ai-viewmessage'>Cancel</A> \]"
|
||||
dat += "<BR>Restore maintenance access restrictions? <BR>\[ <A HREF='?src=[REF(src)];operation=ai-disableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
|
||||
else
|
||||
dat += "<b>Emergency Maintenance Access is currently <font color='green'>DISABLED</font></b>"
|
||||
dat += "<BR>Lift access restrictions on maintenance and external airlocks? <BR>\[ <A HREF='?src=\ref[src];operation=ai-enableemergency'>OK</A> | <A HREF='?src=\ref[src];operation=ai-viewmessage'>Cancel</A> \]"
|
||||
dat += "<BR>Lift access restrictions on maintenance and external airlocks? <BR>\[ <A HREF='?src=[REF(src)];operation=ai-enableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=ai-viewmessage'>Cancel</A> \]"
|
||||
|
||||
dat += "<BR><BR>\[ [(src.aistate != STATE_DEFAULT) ? "<A HREF='?src=\ref[src];operation=ai-main'>Main Menu</A> | " : ""]<A HREF='?src=\ref[user];mach_close=communications'>Close</A> \]"
|
||||
dat += "<BR><BR>\[ [(aistate != STATE_DEFAULT) ? "<A HREF='?src=[REF(src)];operation=ai-main'>Main Menu</A> | " : ""]<A HREF='?src=[REF(user)];mach_close=communications'>Close</A> \]"
|
||||
return dat
|
||||
|
||||
/obj/machinery/computer/communications/proc/make_announcement(mob/living/user, is_silicon)
|
||||
@@ -704,3 +731,22 @@
|
||||
/obj/machinery/computer/communications/proc/overrideCooldown()
|
||||
var/obj/item/circuitboard/computer/communications/CM = circuit
|
||||
CM.lastTimeUsed = 0
|
||||
|
||||
/obj/machinery/computer/communications/proc/add_message(datum/comm_message/new_message)
|
||||
messages += new_message
|
||||
|
||||
/datum/comm_message
|
||||
var/title
|
||||
var/content
|
||||
var/list/possible_answers = list()
|
||||
var/answered
|
||||
var/datum/callback/answer_callback
|
||||
|
||||
/datum/comm_message/New(new_title,new_content,new_possible_answers)
|
||||
..()
|
||||
if(title)
|
||||
title = new_title
|
||||
if(content)
|
||||
content = new_content
|
||||
if(new_possible_answers)
|
||||
possible_answers = new_possible_answers
|
||||
@@ -150,7 +150,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
|
||||
var/pos_y
|
||||
var/life_status
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
|
||||
// Check if their z-level is correct and if they are wearing a uniform.
|
||||
// Accept H.z==0 as well in case the mob is inside an object.
|
||||
if ((H.z == 0 || H.z == z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
@@ -258,16 +258,12 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
|
||||
AI.switchCamera(C)
|
||||
|
||||
/mob/living/carbon/human/Move()
|
||||
var/old_z = src.z
|
||||
. = ..()
|
||||
if (src.w_uniform)
|
||||
var/old_z = src.z
|
||||
|
||||
. = ..()
|
||||
|
||||
if (old_z != src.z)
|
||||
GLOB.crewmonitor.queueUpdate(old_z)
|
||||
GLOB.crewmonitor.queueUpdate(src.z)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/datum/crewmonitor/proc/queueUpdate(z)
|
||||
addtimer(CALLBACK(src, .proc/update, z), 5, TIMER_UNIQUE)
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/Initialize()
|
||||
. = ..()
|
||||
for(dir in list(NORTH,EAST,SOUTH,WEST))
|
||||
connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
|
||||
for(var/direction in GLOB.cardinals)
|
||||
connected = locate(/obj/machinery/dna_scannernew, get_step(src, direction))
|
||||
if(!isnull(connected))
|
||||
break
|
||||
injectorready = world.time + INJECTOR_TIMEOUT
|
||||
@@ -143,27 +143,27 @@
|
||||
status += "<div class='line'><div class='statusLabel'>Pulse Duration:</div><div class='statusValue'>[radduration]</div></div>"
|
||||
status += "<div class='line'><div class='statusLabel'> \> Accuracy:</div><div class='statusValue'>[chance_to_hit]</div></div>"
|
||||
status += "<br></div>" // Close statusDisplay div
|
||||
var/buttons = "<a href='?src=\ref[src];'>Scan</a> "
|
||||
var/buttons = "<a href='?src=[REF(src)];'>Scan</a> "
|
||||
if(connected)
|
||||
buttons += " <a href='?src=\ref[src];task=toggleopen;'>[connected.state_open ? "Close" : "Open"] Scanner</a> "
|
||||
buttons += " <a href='?src=[REF(src)];task=toggleopen;'>[connected.state_open ? "Close" : "Open"] Scanner</a> "
|
||||
if (connected.state_open)
|
||||
buttons += "<span class='linkOff'>[connected.locked ? "Unlock" : "Lock"] Scanner</span> "
|
||||
else
|
||||
buttons += "<a href='?src=\ref[src];task=togglelock;'>[connected.locked ? "Unlock" : "Lock"] Scanner</a> "
|
||||
buttons += "<a href='?src=[REF(src)];task=togglelock;'>[connected.locked ? "Unlock" : "Lock"] Scanner</a> "
|
||||
else
|
||||
buttons += "<span class='linkOff'>Open Scanner</span> <span class='linkOff'>Lock Scanner</span> "
|
||||
if(viable_occupant)
|
||||
buttons += "<a href='?src=\ref[src];task=rejuv'>Inject Rejuvenators</a> "
|
||||
buttons += "<a href='?src=[REF(src)];task=rejuv'>Inject Rejuvenators</a> "
|
||||
else
|
||||
buttons += "<span class='linkOff'>Inject Rejuvenators</span> "
|
||||
if(diskette)
|
||||
buttons += "<a href='?src=\ref[src];task=ejectdisk'>Eject Disk</a> "
|
||||
buttons += "<a href='?src=[REF(src)];task=ejectdisk'>Eject Disk</a> "
|
||||
else
|
||||
buttons += "<span class='linkOff'>Eject Disk</span> "
|
||||
if(current_screen == "buffer")
|
||||
buttons += "<a href='?src=\ref[src];task=screen;text=mainmenu;'>Radiation Emitter Menu</a> "
|
||||
buttons += "<a href='?src=[REF(src)];task=screen;text=mainmenu;'>Radiation Emitter Menu</a> "
|
||||
else
|
||||
buttons += "<a href='?src=\ref[src];task=screen;text=buffer;'>Buffer Menu</a> "
|
||||
buttons += "<a href='?src=[REF(src)];task=screen;text=buffer;'>Buffer Menu</a> "
|
||||
|
||||
switch(current_screen)
|
||||
if("working")
|
||||
@@ -182,12 +182,12 @@
|
||||
if( !buffer_slot || !buffer_slot.len || !buffer_slot["name"] || !((buffer_slot["UI"] && buffer_slot["UE"]) || buffer_slot["SE"]) )
|
||||
temp_html += "<br>\tNo Data"
|
||||
if(viable_occupant)
|
||||
temp_html += "<br><a href='?src=\ref[src];task=setbuffer;num=[i];'>Save to Buffer</a> "
|
||||
temp_html += "<br><a href='?src=[REF(src)];task=setbuffer;num=[i];'>Save to Buffer</a> "
|
||||
else
|
||||
temp_html += "<br><span class='linkOff'>Save to Buffer</span> "
|
||||
temp_html += "<span class='linkOff'>Clear Buffer</span> "
|
||||
if(diskette)
|
||||
temp_html += "<a href='?src=\ref[src];task=loaddisk;num=[i];'>Load from Disk</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=loaddisk;num=[i];'>Load from Disk</a> "
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Load from Disk</span> "
|
||||
temp_html += "<span class='linkOff'>Save to Disk</span> "
|
||||
@@ -198,18 +198,18 @@
|
||||
var/name = buffer_slot["name"]
|
||||
var/label = buffer_slot["label"]
|
||||
var/blood_type = buffer_slot["blood_type"]
|
||||
temp_html += "<br>\t<a href='?src=\ref[src];task=setbufferlabel;num=[i];'>Label</a>: [label ? label : name]"
|
||||
temp_html += "<br>\t<a href='?src=[REF(src)];task=setbufferlabel;num=[i];'>Label</a>: [label ? label : name]"
|
||||
temp_html += "<br>\tSubject: [name]"
|
||||
if(ue && name && blood_type)
|
||||
temp_html += "<br>\tBlood Type: [blood_type]"
|
||||
temp_html += "<br>\tUE: [ue] "
|
||||
if(viable_occupant)
|
||||
temp_html += "<a href='?src=\ref[src];task=transferbuffer;num=[i];text=ue'>Occupant</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=transferbuffer;num=[i];text=ue'>Occupant</a> "
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Occupant</span>"
|
||||
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_UE]'>Occupant:Delayed</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_UE]'>Occupant:Delayed</a> "
|
||||
if(injectorready < world.time)
|
||||
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=ue'>Injector</a>"
|
||||
temp_html += "<a href='?src=[REF(src)];task=injector;num=[i];text=ue'>Injector</a>"
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Injector</span>"
|
||||
else
|
||||
@@ -218,12 +218,12 @@
|
||||
if(ui)
|
||||
temp_html += "<br>\tUI: [ui] "
|
||||
if(viable_occupant)
|
||||
temp_html += "<a href='?src=\ref[src];task=transferbuffer;num=[i];text=ui'>Occupant</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=transferbuffer;num=[i];text=ui'>Occupant</a> "
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Occupant</span>"
|
||||
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_UI]'>Occupant:Delayed</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_UI]'>Occupant:Delayed</a> "
|
||||
if(injectorready < world.time)
|
||||
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=ui'>Injector</a>"
|
||||
temp_html += "<a href='?src=[REF(src)];task=injector;num=[i];text=ui'>Injector</a>"
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Injector</span>"
|
||||
else
|
||||
@@ -231,38 +231,38 @@
|
||||
if(ue && name && blood_type && ui)
|
||||
temp_html += "<br>\tUI+UE: [ui]/[ue] "
|
||||
if(viable_occupant)
|
||||
temp_html += "<a href='?src=\ref[src];task=transferbuffer;num=[i];text=mixed'>Occupant</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=transferbuffer;num=[i];text=mixed'>Occupant</a> "
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Occupant</span>"
|
||||
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_MIXED]'>Occupant:Delayed</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_MIXED]'>Occupant:Delayed</a> "
|
||||
if(injectorready < world.time)
|
||||
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=mixed'>UI+UE Injector</a>"
|
||||
temp_html += "<a href='?src=[REF(src)];task=injector;num=[i];text=mixed'>UI+UE Injector</a>"
|
||||
else
|
||||
temp_html += "<span class='linkOff'>UI+UE Injector</span>"
|
||||
if(se)
|
||||
temp_html += "<br>\tSE: [se] "
|
||||
if(viable_occupant)
|
||||
temp_html += "<a href='?src=\ref[src];task=transferbuffer;num=[i];text=se'>Occupant</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=transferbuffer;num=[i];text=se'>Occupant</a> "
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Occupant</span> "
|
||||
temp_html += "<a href='?src=\ref[src];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_SE]'>Occupant:Delayed</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_SE]'>Occupant:Delayed</a> "
|
||||
if(injectorready < world.time )
|
||||
temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=se'>Injector</a>"
|
||||
temp_html += "<a href='?src=[REF(src)];task=injector;num=[i];text=se'>Injector</a>"
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Injector</span>"
|
||||
else
|
||||
temp_html += "<br>\tSE: No Data"
|
||||
if(viable_occupant)
|
||||
temp_html += "<br><a href='?src=\ref[src];task=setbuffer;num=[i];'>Save to Buffer</a> "
|
||||
temp_html += "<br><a href='?src=[REF(src)];task=setbuffer;num=[i];'>Save to Buffer</a> "
|
||||
else
|
||||
temp_html += "<br><span class='linkOff'>Save to Buffer</span> "
|
||||
temp_html += "<a href='?src=\ref[src];task=clearbuffer;num=[i];'>Clear Buffer</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=clearbuffer;num=[i];'>Clear Buffer</a> "
|
||||
if(diskette)
|
||||
temp_html += "<a href='?src=\ref[src];task=loaddisk;num=[i];'>Load from Disk</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=loaddisk;num=[i];'>Load from Disk</a> "
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Load from Disk</span> "
|
||||
if(diskette && !diskette.read_only)
|
||||
temp_html += "<a href='?src=\ref[src];task=savedisk;num=[i];'>Save to Disk</a> "
|
||||
temp_html += "<a href='?src=[REF(src)];task=savedisk;num=[i];'>Save to Disk</a> "
|
||||
else
|
||||
temp_html += "<span class='linkOff'>Save to Disk</span> "
|
||||
else
|
||||
@@ -270,8 +270,8 @@
|
||||
temp_html += buttons
|
||||
temp_html += "<h1>Radiation Emitter Menu</h1>"
|
||||
|
||||
temp_html += "<a href='?src=\ref[src];task=setstrength;num=[radstrength-1];'>--</a> <a href='?src=\ref[src];task=setstrength;'>Output Level</a> <a href='?src=\ref[src];task=setstrength;num=[radstrength+1];'>++</a>"
|
||||
temp_html += "<br><a href='?src=\ref[src];task=setduration;num=[radduration-1];'>--</a> <a href='?src=\ref[src];task=setduration;'>Pulse Duration</a> <a href='?src=\ref[src];task=setduration;num=[radduration+1];'>++</a>"
|
||||
temp_html += "<a href='?src=[REF(src)];task=setstrength;num=[radstrength-1];'>--</a> <a href='?src=[REF(src)];task=setstrength;'>Output Level</a> <a href='?src=[REF(src)];task=setstrength;num=[radstrength+1];'>++</a>"
|
||||
temp_html += "<br><a href='?src=[REF(src)];task=setduration;num=[radduration-1];'>--</a> <a href='?src=[REF(src)];task=setduration;'>Pulse Duration</a> <a href='?src=[REF(src)];task=setduration;num=[radduration+1];'>++</a>"
|
||||
|
||||
temp_html += "<h3>Irradiate Subject</h3>"
|
||||
temp_html += "<div class='line'><div class='statusLabel'>Unique Identifier:</div><div class='statusValue'><div class='clearBoth'>"
|
||||
@@ -281,7 +281,7 @@
|
||||
temp_html += "<div class='dnaBlockNumber'>1</div>"
|
||||
var/len = length(viable_occupant.dna.uni_identity)
|
||||
for(var/i=1, i<=len, i++)
|
||||
temp_html += "<a class='dnaBlock' href='?src=\ref[src];task=pulseui;num=[i];'>[copytext(viable_occupant.dna.uni_identity,i,i+1)]</a>"
|
||||
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulseui;num=[i];'>[copytext(viable_occupant.dna.uni_identity,i,i+1)]</a>"
|
||||
if ((i % max_line_len) == 0)
|
||||
temp_html += "</div><div class='clearBoth'>"
|
||||
if((i % DNA_BLOCK_SIZE) == 0 && i < len)
|
||||
@@ -295,7 +295,7 @@
|
||||
temp_html += "<div class='dnaBlockNumber'>1</div>"
|
||||
var/len = length(viable_occupant.dna.struc_enzymes)
|
||||
for(var/i=1, i<=len, i++)
|
||||
temp_html += "<a class='dnaBlock' href='?src=\ref[src];task=pulsese;num=[i];'>[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]</a>"
|
||||
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulsese;num=[i];'>[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]</a>"
|
||||
if ((i % max_line_len) == 0)
|
||||
temp_html += "</div><div class='clearBoth'>"
|
||||
if((i % DNA_BLOCK_SIZE) == 0 && i < len)
|
||||
|
||||
@@ -129,8 +129,8 @@
|
||||
/obj/machinery/computer/gulag_teleporter_computer/proc/findteleporter()
|
||||
var/obj/machinery/gulag_teleporter/teleporterf = null
|
||||
|
||||
for(dir in GLOB.cardinals)
|
||||
teleporterf = locate(/obj/machinery/gulag_teleporter, get_step(src, dir))
|
||||
for(var/direction in GLOB.cardinals)
|
||||
teleporterf = locate(/obj/machinery/gulag_teleporter, get_step(src, direction))
|
||||
if(teleporterf && teleporterf.is_operational())
|
||||
return teleporterf
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
if(pad.stat & NOPOWER)
|
||||
t+= "<span class='linkOff'>[pad.display_name]</span>"
|
||||
else
|
||||
t+= "<A href='?src=\ref[src];choose_pad=1;pad=[i]'>[pad.display_name]</A>"
|
||||
t+= "<A href='?src=[REF(src)];choose_pad=1;pad=[i]'>[pad.display_name]</A>"
|
||||
else
|
||||
launchpads -= get_pad(i)
|
||||
t += "<BR>"
|
||||
@@ -68,24 +68,24 @@
|
||||
if(current_pad)
|
||||
var/obj/machinery/launchpad/pad = get_pad(current_pad)
|
||||
t += "<div class='statusDisplay'><b>[pad.display_name]</b></div>"
|
||||
t += "<A href='?src=\ref[src];change_name=1;pad=[current_pad]'>Rename</A>"
|
||||
t += "<A href='?src=\ref[src];remove=1;pad=[current_pad]'>Remove</A><BR><BR>"
|
||||
t += "<A href='?src=\ref[src];raisey=1;lowerx=1;pad=[current_pad]'>O</A>" //up-left
|
||||
t += "<A href='?src=\ref[src];raisey=1;pad=[current_pad]'>^</A>" //up
|
||||
t += "<A href='?src=\ref[src];raisey=1;raisex=1;pad=[current_pad]'>O</A><BR>" //up-right
|
||||
t += "<A href='?src=\ref[src];lowerx=1;pad=[current_pad]'><</A>"//left
|
||||
t += "<A href='?src=\ref[src];reset=1;pad=[current_pad]'>R</A>"//reset to 0
|
||||
t += "<A href='?src=\ref[src];raisex=1;pad=[current_pad]'>></A><BR>"//right
|
||||
t += "<A href='?src=\ref[src];lowery=1;lowerx=1;pad=[current_pad]'>O</A>"//down-left
|
||||
t += "<A href='?src=\ref[src];lowery=1;pad=[current_pad]'>v</A>"//down
|
||||
t += "<A href='?src=\ref[src];lowery=1;raisex=1;pad=[current_pad]'>O</A><BR>"//down-right
|
||||
t += "<A href='?src=[REF(src)];change_name=1;pad=[current_pad]'>Rename</A>"
|
||||
t += "<A href='?src=[REF(src)];remove=1;pad=[current_pad]'>Remove</A><BR><BR>"
|
||||
t += "<A href='?src=[REF(src)];raisey=1;lowerx=1;pad=[current_pad]'>O</A>" //up-left
|
||||
t += "<A href='?src=[REF(src)];raisey=1;pad=[current_pad]'>^</A>" //up
|
||||
t += "<A href='?src=[REF(src)];raisey=1;raisex=1;pad=[current_pad]'>O</A><BR>" //up-right
|
||||
t += "<A href='?src=[REF(src)];lowerx=1;pad=[current_pad]'><</A>"//left
|
||||
t += "<A href='?src=[REF(src)];reset=1;pad=[current_pad]'>R</A>"//reset to 0
|
||||
t += "<A href='?src=[REF(src)];raisex=1;pad=[current_pad]'>></A><BR>"//right
|
||||
t += "<A href='?src=[REF(src)];lowery=1;lowerx=1;pad=[current_pad]'>O</A>"//down-left
|
||||
t += "<A href='?src=[REF(src)];lowery=1;pad=[current_pad]'>v</A>"//down
|
||||
t += "<A href='?src=[REF(src)];lowery=1;raisex=1;pad=[current_pad]'>O</A><BR>"//down-right
|
||||
t += "<BR>"
|
||||
t += "<div class='statusDisplay'>Current offset:</div><BR>"
|
||||
t += "<div class='statusDisplay'>[abs(pad.y_offset)] [pad.y_offset > 0 ? "N":"S"]</div><BR>"
|
||||
t += "<div class='statusDisplay'>[abs(pad.x_offset)] [pad.x_offset > 0 ? "E":"W"]</div><BR>"
|
||||
|
||||
t += "<BR><A href='?src=\ref[src];launch=1;pad=[current_pad]'>Launch</A>"
|
||||
t += " <A href='?src=\ref[src];pull=1;pad=[current_pad]'>Pull</A>"
|
||||
t += "<BR><A href='?src=[REF(src)];launch=1;pad=[current_pad]'>Launch</A>"
|
||||
t += " <A href='?src=[REF(src)];pull=1;pad=[current_pad]'>Pull</A>"
|
||||
|
||||
var/datum/browser/popup = new(user, "launchpad", name, 300, 500)
|
||||
popup.set_content(t.Join())
|
||||
|
||||
@@ -39,21 +39,21 @@
|
||||
return
|
||||
var/dat
|
||||
if(src.temp)
|
||||
dat = text("<TT>[src.temp]</TT><BR><BR><A href='?src=\ref[src];temp=1'>Clear Screen</A>")
|
||||
dat = text("<TT>[src.temp]</TT><BR><BR><A href='?src=[REF(src)];temp=1'>Clear Screen</A>")
|
||||
else
|
||||
dat = text("Confirm Identity: <A href='?src=\ref[];scan=1'>[]</A><HR>", src, (src.scan ? text("[]", src.scan.name) : "----------"))
|
||||
dat = text("Confirm Identity: <A href='?src=[REF(src)];scan=1'>[]</A><HR>", (src.scan ? text("[]", src.scan.name) : "----------"))
|
||||
if(src.authenticated)
|
||||
switch(src.screen)
|
||||
if(1)
|
||||
dat += {"
|
||||
<A href='?src=\ref[src];search=1'>Search Records</A>
|
||||
<BR><A href='?src=\ref[src];screen=2'>List Records</A>
|
||||
<A href='?src=[REF(src)];search=1'>Search Records</A>
|
||||
<BR><A href='?src=[REF(src)];screen=2'>List Records</A>
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[src];screen=5'>Virus Database</A>
|
||||
<BR><A href='?src=\ref[src];screen=6'>Medbot Tracking</A>
|
||||
<BR><A href='?src=[REF(src)];screen=5'>Virus Database</A>
|
||||
<BR><A href='?src=[REF(src)];screen=6'>Medbot Tracking</A>
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[src];screen=3'>Record Maintenance</A>
|
||||
<BR><A href='?src=\ref[src];logout=1'>{Log Out}</A><BR>
|
||||
<BR><A href='?src=[REF(src)];screen=3'>Record Maintenance</A>
|
||||
<BR><A href='?src=[REF(src)];logout=1'>{Log Out}</A><BR>
|
||||
"}
|
||||
if(2)
|
||||
dat += {"
|
||||
@@ -65,10 +65,10 @@
|
||||
</table>
|
||||
<table style="text-align:center;" border="1" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<th><A href='?src=\ref[src];choice=Sorting;sort=name'>Name</A></th>
|
||||
<th><A href='?src=\ref[src];choice=Sorting;sort=id'>ID</A></th>
|
||||
<th><A href='?src=[REF(src)];choice=Sorting;sort=name'>Name</A></th>
|
||||
<th><A href='?src=[REF(src)];choice=Sorting;sort=id'>ID</A></th>
|
||||
<th>Fingerprints (F) | DNA (D)</th>
|
||||
<th><A href='?src=\ref[src];choice=Sorting;sort=bloodtype'>Blood Type</A></th>
|
||||
<th><A href='?src=[REF(src)];choice=Sorting;sort=bloodtype'>Blood Type</A></th>
|
||||
<th>Physical Status</th>
|
||||
<th>Mental Status</th>
|
||||
</tr>"}
|
||||
@@ -93,7 +93,7 @@
|
||||
else
|
||||
background = "'background-color:#4F7529;'"
|
||||
|
||||
dat += text("<tr style=[]><td><A href='?src=\ref[];d_rec=[]'>[]</a></td>", background, src, R.fields["id"], R.fields["name"])
|
||||
dat += text("<tr style=[]><td><A href='?src=[REF(src)];d_rec=[]'>[]</a></td>", background, R.fields["id"], R.fields["name"])
|
||||
dat += text("<td>[]</td>", R.fields["id"])
|
||||
dat += text("<td><b>F:</b> []<BR><b>D:</b> []</td>", R.fields["fingerprint"], b_dna)
|
||||
dat += text("<td>[]</td>", blood_type)
|
||||
@@ -102,11 +102,11 @@
|
||||
dat += "</table><hr width='75%' />"
|
||||
// if(GLOB.data_core.general)
|
||||
// for(var/datum/data/record/R in sortRecord(GLOB.data_core.general))
|
||||
// dat += "<A href='?src=\ref[src];d_rec=[R.fields["id"]]'>[R.fields["id"]]: [R.fields["name"]]<BR>"
|
||||
// dat += "<A href='?src=[REF(src)];d_rec=[R.fields["id"]]'>[R.fields["id"]]: [R.fields["name"]]<BR>"
|
||||
// //Foreach goto(132)
|
||||
dat += text("<HR><A href='?src=\ref[];screen=1'>Back</A>", src)
|
||||
dat += "<HR><A href='?src=[REF(src)];screen=1'>Back</A>"
|
||||
if(3)
|
||||
dat += text("<B>Records Maintenance</B><HR>\n<A href='?src=\ref[];back=1'>Backup To Disk</A><BR>\n<A href='?src=\ref[];u_load=1'>Upload From Disk</A><BR>\n<A href='?src=\ref[];del_all=1'>Delete All Records</A><BR>\n<BR>\n<A href='?src=\ref[];screen=1'>Back</A>", src, src, src, src)
|
||||
dat += "<B>Records Maintenance</B><HR>\n<A href='?src=[REF(src)];back=1'>Backup To Disk</A><BR>\n<A href='?src=[REF(src)];u_load=1'>Upload From Disk</A><BR>\n<A href='?src=[REF(src)];del_all=1'>Delete All Records</A><BR>\n<BR>\n<A href='?src=[REF(src)];screen=1'>Back</A>"
|
||||
if(4)
|
||||
|
||||
dat += "<table><tr><td><b><font size='4'>Medical Record</font></b></td></tr>"
|
||||
@@ -118,45 +118,45 @@
|
||||
var/obj/item/photo/P2 = active1.fields["photo_side"]
|
||||
user << browse_rsc(P2.img, "photo_side")
|
||||
dat += "<tr><td>Name:</td><td>[active1.fields["name"]]</td>"
|
||||
dat += "<td><a href='?src=\ref[src];field=show_photo_front'><img src=photo_front height=80 width=80 border=4></a></td>"
|
||||
dat += "<td><a href='?src=\ref[src];field=show_photo_side'><img src=photo_side height=80 width=80 border=4></a></td></tr>"
|
||||
dat += "<td><a href='?src=[REF(src)];field=show_photo_front'><img src=photo_front height=80 width=80 border=4></a></td>"
|
||||
dat += "<td><a href='?src=[REF(src)];field=show_photo_side'><img src=photo_side height=80 width=80 border=4></a></td></tr>"
|
||||
dat += "<tr><td>ID:</td><td>[active1.fields["id"]]</td></tr>"
|
||||
dat += "<tr><td>Sex:</td><td><A href='?src=\ref[src];field=sex'> [active1.fields["sex"]] </A></td></tr>"
|
||||
dat += "<tr><td>Age:</td><td><A href='?src=\ref[src];field=age'> [active1.fields["age"]] </A></td></tr>"
|
||||
dat += "<tr><td>Species:</td><td><A href='?src=\ref[src];field=species'> [active1.fields["species"]] </A></td></tr>"
|
||||
dat += "<tr><td>Fingerprint:</td><td><A href='?src=\ref[src];field=fingerprint'> [active1.fields["fingerprint"]] </A></td></tr>"
|
||||
dat += "<tr><td>Physical Status:</td><td><A href='?src=\ref[src];field=p_stat'> [active1.fields["p_stat"]] </A></td></tr>"
|
||||
dat += "<tr><td>Mental Status:</td><td><A href='?src=\ref[src];field=m_stat'> [active1.fields["m_stat"]] </A></td></tr>"
|
||||
dat += "<tr><td>Sex:</td><td><A href='?src=[REF(src)];field=sex'> [active1.fields["sex"]] </A></td></tr>"
|
||||
dat += "<tr><td>Age:</td><td><A href='?src=[REF(src)];field=age'> [active1.fields["age"]] </A></td></tr>"
|
||||
dat += "<tr><td>Species:</td><td><A href='?src=[REF(src)];field=species'> [active1.fields["species"]] </A></td></tr>"
|
||||
dat += "<tr><td>Fingerprint:</td><td><A href='?src=[REF(src)];field=fingerprint'> [active1.fields["fingerprint"]] </A></td></tr>"
|
||||
dat += "<tr><td>Physical Status:</td><td><A href='?src=[REF(src)];field=p_stat'> [active1.fields["p_stat"]] </A></td></tr>"
|
||||
dat += "<tr><td>Mental Status:</td><td><A href='?src=[REF(src)];field=m_stat'> [active1.fields["m_stat"]] </A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td>General Record Lost!</td></tr>"
|
||||
|
||||
dat += "<tr><td><br><b><font size='4'>Medical Data</font></b></td></tr>"
|
||||
if(active2 in GLOB.data_core.medical)
|
||||
dat += "<tr><td>Blood Type:</td><td><A href='?src=\ref[src];field=blood_type'> [active2.fields["blood_type"]] </A></td></tr>"
|
||||
dat += "<tr><td>DNA:</td><td><A href='?src=\ref[src];field=b_dna'> [active2.fields["b_dna"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Minor Disabilities:</td><td><br><A href='?src=\ref[src];field=mi_dis'> [active2.fields["mi_dis"]] </A></td></tr>"
|
||||
dat += "<tr><td>Details:</td><td><A href='?src=\ref[src];field=mi_dis_d'> [active2.fields["mi_dis_d"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Major Disabilities:</td><td><br><A href='?src=\ref[src];field=ma_dis'> [active2.fields["ma_dis"]] </A></td></tr>"
|
||||
dat += "<tr><td>Details:</td><td><A href='?src=\ref[src];field=ma_dis_d'> [active2.fields["ma_dis_d"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Allergies:</td><td><br><A href='?src=\ref[src];field=alg'> [active2.fields["alg"]] </A></td></tr>"
|
||||
dat += "<tr><td>Details:</td><td><A href='?src=\ref[src];field=alg_d'> [active2.fields["alg_d"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Current Diseases:</td><td><br><A href='?src=\ref[src];field=cdi'> [active2.fields["cdi"]] </A></td></tr>" //(per disease info placed in log/comment section)
|
||||
dat += "<tr><td>Details:</td><td><A href='?src=\ref[src];field=cdi_d'> [active2.fields["cdi_d"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Important Notes:</td><td><br><A href='?src=\ref[src];field=notes'> [active2.fields["notes"]] </A></td></tr>"
|
||||
dat += "<tr><td>Blood Type:</td><td><A href='?src=[REF(src)];field=blood_type'> [active2.fields["blood_type"]] </A></td></tr>"
|
||||
dat += "<tr><td>DNA:</td><td><A href='?src=[REF(src)];field=b_dna'> [active2.fields["b_dna"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Minor Disabilities:</td><td><br><A href='?src=[REF(src)];field=mi_dis'> [active2.fields["mi_dis"]] </A></td></tr>"
|
||||
dat += "<tr><td>Details:</td><td><A href='?src=[REF(src)];field=mi_dis_d'> [active2.fields["mi_dis_d"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Major Disabilities:</td><td><br><A href='?src=[REF(src)];field=ma_dis'> [active2.fields["ma_dis"]] </A></td></tr>"
|
||||
dat += "<tr><td>Details:</td><td><A href='?src=[REF(src)];field=ma_dis_d'> [active2.fields["ma_dis_d"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Allergies:</td><td><br><A href='?src=[REF(src)];field=alg'> [active2.fields["alg"]] </A></td></tr>"
|
||||
dat += "<tr><td>Details:</td><td><A href='?src=[REF(src)];field=alg_d'> [active2.fields["alg_d"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Current Diseases:</td><td><br><A href='?src=[REF(src)];field=cdi'> [active2.fields["cdi"]] </A></td></tr>" //(per disease info placed in log/comment section)
|
||||
dat += "<tr><td>Details:</td><td><A href='?src=[REF(src)];field=cdi_d'> [active2.fields["cdi_d"]] </A></td></tr>"
|
||||
dat += "<tr><td><br>Important Notes:</td><td><br><A href='?src=[REF(src)];field=notes'> [active2.fields["notes"]] </A></td></tr>"
|
||||
|
||||
dat += "<tr><td><br><b><font size='4'>Comments/Log</font></b></td></tr>"
|
||||
var/counter = 1
|
||||
while(src.active2.fields[text("com_[]", counter)])
|
||||
dat += "<tr><td>[active2.fields[text("com_[]", counter)]]</td></tr><tr><td><A href='?src=\ref[src];del_c=[counter]'>Delete Entry</A></td></tr>"
|
||||
dat += "<tr><td>[active2.fields[text("com_[]", counter)]]</td></tr><tr><td><A href='?src=[REF(src)];del_c=[counter]'>Delete Entry</A></td></tr>"
|
||||
counter++
|
||||
dat += "<tr><td><A href='?src=\ref[src];add_c=1'>Add Entry</A></td></tr>"
|
||||
dat += "<tr><td><A href='?src=[REF(src)];add_c=1'>Add Entry</A></td></tr>"
|
||||
|
||||
dat += "<tr><td><br><A href='?src=\ref[src];del_r=1'>Delete Record (Medical Only)</A></td></tr>"
|
||||
dat += "<tr><td><br><A href='?src=[REF(src)];del_r=1'>Delete Record (Medical Only)</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td>Medical Record Lost!</tr>"
|
||||
dat += "<tr><td><br><A href='?src=\ref[src];new=1'>New Record</A></td></tr>"
|
||||
dat += "<tr><td><A href='?src=\ref[src];print_p=1'>Print Record</A></td></tr>"
|
||||
dat += "<tr><td><A href='?src=\ref[src];screen=2'>Back</A></td></tr>"
|
||||
dat += "<tr><td><br><A href='?src=[REF(src)];new=1'>New Record</A></td></tr>"
|
||||
dat += "<tr><td><A href='?src=[REF(src)];print_p=1'>Print Record</A></td></tr>"
|
||||
dat += "<tr><td><A href='?src=[REF(src)];screen=2'>Back</A></td></tr>"
|
||||
dat += "</table>"
|
||||
if(5)
|
||||
dat += "<CENTER><B>Virus Database</B></CENTER>"
|
||||
@@ -166,14 +166,14 @@
|
||||
continue // TODO (tm): Add advance diseases to the virus database which no one uses.
|
||||
if(!Dis.desc)
|
||||
continue
|
||||
dat += "<br><a href='?src=\ref[src];vir=[Dt]'>[Dis.name]</a>"
|
||||
dat += "<br><a href='?src=\ref[src];screen=1'>Back</a>"
|
||||
dat += "<br><a href='?src=[REF(src)];vir=[Dt]'>[Dis.name]</a>"
|
||||
dat += "<br><a href='?src=[REF(src)];screen=1'>Back</a>"
|
||||
if(6)
|
||||
dat += "<center><b>Medical Robot Monitor</b></center>"
|
||||
dat += "<a href='?src=\ref[src];screen=1'>Back</a>"
|
||||
dat += "<a href='?src=[REF(src)];screen=1'>Back</a>"
|
||||
dat += "<br><b>Medical Robots:</b>"
|
||||
var/bdat = null
|
||||
for(var/mob/living/simple_animal/bot/medbot/M in GLOB.living_mob_list)
|
||||
for(var/mob/living/simple_animal/bot/medbot/M in GLOB.alive_mob_list)
|
||||
if(M.z != src.z)
|
||||
continue //only find medibots on the same z-level as the computer
|
||||
var/turf/bl = get_turf(M)
|
||||
@@ -191,7 +191,7 @@
|
||||
|
||||
else
|
||||
else
|
||||
dat += text("<A href='?src=\ref[];login=1'>{Log In}</A>", src)
|
||||
dat += "<A href='?src=[REF(src)];login=1'>{Log In}</A>"
|
||||
var/datum/browser/popup = new(user, "med_rec", "Medical Records Console", 600, 400)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
@@ -286,7 +286,7 @@
|
||||
<BR><b>Severity:</b> [Dis.severity]"}
|
||||
|
||||
else if(href_list["del_all"])
|
||||
src.temp = text("Are you sure you wish to delete all records?<br>\n\t<A href='?src=\ref[];temp=1;del_all2=1'>Yes</A><br>\n\t<A href='?src=\ref[];temp=1'>No</A><br>", src, src)
|
||||
src.temp = "Are you sure you wish to delete all records?<br>\n\t<A href='?src=[REF(src)];temp=1;del_all2=1'>Yes</A><br>\n\t<A href='?src=[REF(src)];temp=1'>No</A><br>"
|
||||
|
||||
else if(href_list["del_all2"])
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted all medical records.", INVESTIGATE_RECORDS)
|
||||
@@ -377,13 +377,13 @@
|
||||
src.active2.fields["notes"] = t1
|
||||
if("p_stat")
|
||||
if(active1)
|
||||
src.temp = text("<B>Physical Condition:</B><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=deceased'>*Deceased*</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=unconscious'>*Unconscious*</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=active'>Active</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=unfit'>Physically Unfit</A><BR>", src, src, src, src)
|
||||
src.temp = "<B>Physical Condition:</B><BR>\n\t<A href='?src=[REF(src)];temp=1;p_stat=deceased'>*Deceased*</A><BR>\n\t<A href='?src=[REF(src)];temp=1;p_stat=unconscious'>*Unconscious*</A><BR>\n\t<A href='?src=[REF(src)];temp=1;p_stat=active'>Active</A><BR>\n\t<A href='?src=[REF(src)];temp=1;p_stat=unfit'>Physically Unfit</A><BR>"
|
||||
if("m_stat")
|
||||
if(active1)
|
||||
src.temp = text("<B>Mental Condition:</B><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=insane'>*Insane*</A><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=unstable'>*Unstable*</A><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=watch'>*Watch*</A><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=stable'>Stable</A><BR>", src, src, src, src)
|
||||
src.temp = "<B>Mental Condition:</B><BR>\n\t<A href='?src=[REF(src)];temp=1;m_stat=insane'>*Insane*</A><BR>\n\t<A href='?src=[REF(src)];temp=1;m_stat=unstable'>*Unstable*</A><BR>\n\t<A href='?src=[REF(src)];temp=1;m_stat=watch'>*Watch*</A><BR>\n\t<A href='?src=[REF(src)];temp=1;m_stat=stable'>Stable</A><BR>"
|
||||
if("blood_type")
|
||||
if(active2)
|
||||
src.temp = text("<B>Blood Type:</B><BR>\n\t<A href='?src=\ref[];temp=1;blood_type=an'>A-</A> <A href='?src=\ref[];temp=1;blood_type=ap'>A+</A><BR>\n\t<A href='?src=\ref[];temp=1;blood_type=bn'>B-</A> <A href='?src=\ref[];temp=1;blood_type=bp'>B+</A><BR>\n\t<A href='?src=\ref[];temp=1;blood_type=abn'>AB-</A> <A href='?src=\ref[];temp=1;blood_type=abp'>AB+</A><BR>\n\t<A href='?src=\ref[];temp=1;blood_type=on'>O-</A> <A href='?src=\ref[];temp=1;blood_type=op'>O+</A><BR>", src, src, src, src, src, src, src, src)
|
||||
src.temp = "<B>Blood Type:</B><BR>\n\t<A href='?src=[REF(src)];temp=1;blood_type=an'>A-</A> <A href='?src=[REF(src)];temp=1;blood_type=ap'>A+</A><BR>\n\t<A href='?src=[REF(src)];temp=1;blood_type=bn'>B-</A> <A href='?src=[REF(src)];temp=1;blood_type=bp'>B+</A><BR>\n\t<A href='?src=[REF(src)];temp=1;blood_type=abn'>AB-</A> <A href='?src=[REF(src)];temp=1;blood_type=abp'>AB+</A><BR>\n\t<A href='?src=[REF(src)];temp=1;blood_type=on'>O-</A> <A href='?src=[REF(src)];temp=1;blood_type=op'>O+</A><BR>"
|
||||
if("b_dna")
|
||||
if(active2)
|
||||
var/t1 = stripped_input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null)
|
||||
@@ -452,7 +452,7 @@
|
||||
|
||||
else if(href_list["del_r"])
|
||||
if(active2)
|
||||
src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)?<br>\n\t<A href='?src=\ref[];temp=1;del_r2=1'>Yes</A><br>\n\t<A href='?src=\ref[];temp=1'>No</A><br>", src, src)
|
||||
src.temp = "Are you sure you wish to delete the record (Medical Portion Only)?<br>\n\t<A href='?src=[REF(src)];temp=1;del_r2=1'>Yes</A><br>\n\t<A href='?src=[REF(src)];temp=1'>No</A><br>"
|
||||
|
||||
else if(href_list["del_r2"])
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted the medical records for [active1.fields["name"]].", INVESTIGATE_RECORDS)
|
||||
@@ -575,7 +575,7 @@
|
||||
if(4)
|
||||
R.fields["blood_type"] = random_blood_type()
|
||||
if(5)
|
||||
R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit")
|
||||
R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit")
|
||||
if(6)
|
||||
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
|
||||
continue
|
||||
|
||||
@@ -1,473 +1,472 @@
|
||||
|
||||
// Allows you to monitor messages that passes the server.
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/machinery/computer/message_monitor
|
||||
name = "message monitor console"
|
||||
desc = "Used to Monitor the crew's messages, that are sent via PDA. Can also be used to view Request Console messages."
|
||||
icon_screen = "comm_logs"
|
||||
circuit = /obj/item/circuitboard/computer/message_monitor
|
||||
//Server linked to.
|
||||
var/obj/machinery/message_server/linkedServer = null
|
||||
//Sparks effect - For emag
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
|
||||
//Messages - Saves me time if I want to change something.
|
||||
var/noserver = "<span class='alert'>ALERT: No server detected.</span>"
|
||||
var/incorrectkey = "<span class='warning'>ALERT: Incorrect decryption key!</span>"
|
||||
var/defaultmsg = "<span class='notice'>Welcome. Please select an option.</span>"
|
||||
var/rebootmsg = "<span class='warning'>%$&(�: Critical %$$@ Error // !RestArting! <lOadiNg backUp iNput ouTput> - ?pLeaSe wAit!</span>"
|
||||
//Computer properties
|
||||
var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message
|
||||
var/hacking = 0 // Is it being hacked into by the AI/Cyborg
|
||||
var/message = "<span class='notice'>System bootup complete. Please select an option.</span>" // The message that shows on the main menu.
|
||||
var/auth = 0 // Are they authenticated?
|
||||
var/optioncount = 7
|
||||
// Custom Message Properties
|
||||
var/customsender = "System Administrator"
|
||||
var/obj/item/device/pda/customrecepient = null
|
||||
var/customjob = "Admin"
|
||||
var/custommessage = "This is a test, please ignore."
|
||||
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/machinery/computer/message_monitor/attackby(obj/item/O, mob/living/user, params)
|
||||
if(istype(O, /obj/item/screwdriver) && emagged)
|
||||
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
|
||||
to_chat(user, "<span class='warning'>It is too hot to mess with!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/message_monitor/emag_act(mob/user)
|
||||
if(emagged)
|
||||
return
|
||||
if(!isnull(src.linkedServer))
|
||||
emagged = TRUE
|
||||
screen = 2
|
||||
spark_system.set_up(5, 0, src)
|
||||
src.spark_system.start()
|
||||
var/obj/item/paper/monitorkey/MK = new/obj/item/paper/monitorkey
|
||||
MK.loc = src.loc
|
||||
// Will help make emagging the console not so easy to get away with.
|
||||
MK.info += "<br><br><font color='red'>�%@%(*$%&(�&?*(%&�/{}</font>"
|
||||
var/time = 100 * length(src.linkedServer.decryptkey)
|
||||
addtimer(CALLBACK(src, .proc/UnmagConsole), time)
|
||||
message = rebootmsg
|
||||
else
|
||||
to_chat(user, "<span class='notice'>A no server error appears on the screen.</span>")
|
||||
|
||||
/obj/machinery/computer/message_monitor/Initialize()
|
||||
. = ..()
|
||||
//Is the server isn't linked to a server, and there's a server available, default it to the first one in the list.
|
||||
if(!linkedServer)
|
||||
if(GLOB.message_servers && GLOB.message_servers.len > 0)
|
||||
linkedServer = GLOB.message_servers[1]
|
||||
|
||||
/obj/machinery/computer/message_monitor/attack_hand(mob/living/user)
|
||||
if(..())
|
||||
return
|
||||
//If the computer is being hacked or is emagged, display the reboot message.
|
||||
if(hacking || emagged)
|
||||
message = rebootmsg
|
||||
var/dat = "<center><font color='blue'[message]</font>/</center>"
|
||||
|
||||
if(auth)
|
||||
dat += "<h4><dd><A href='?src=\ref[src];auth=1'>	<font color='green'>\[Authenticated\]</font></a>	/"
|
||||
dat += " Server Power: <A href='?src=\ref[src];active=1'>[src.linkedServer && src.linkedServer.active ? "<font color='green'>\[On\]</font>":"<font color='red'>\[Off\]</font>"]</a></h4>"
|
||||
else
|
||||
dat += "<h4><dd><A href='?src=\ref[src];auth=1'>	<font color='red'>\[Unauthenticated\]</font></a>	/"
|
||||
dat += " Server Power: <u>[src.linkedServer && src.linkedServer.active ? "<font color='green'>\[On\]</font>":"<font color='red'>\[Off\]</font>"]</u></h4>"
|
||||
|
||||
if(hacking || emagged)
|
||||
screen = 2
|
||||
else if(!auth || !linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
screen = 0
|
||||
|
||||
switch(screen)
|
||||
//Main menu
|
||||
if(0)
|
||||
//	 = TAB
|
||||
var/i = 0
|
||||
dat += "<dd><A href='?src=\ref[src];find=1'>	[++i]. Link To A Server</a></dd>"
|
||||
if(auth)
|
||||
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
dat += "<dd><A>	ERROR: Server not found!</A><br></dd>"
|
||||
else
|
||||
dat += "<dd><A href='?src=\ref[src];view=1'>	[++i]. View Message Logs </a><br></dd>"
|
||||
dat += "<dd><A href='?src=\ref[src];viewr=1'>	[++i]. View Request Console Logs </a></br></dd>"
|
||||
dat += "<dd><A href='?src=\ref[src];clear=1'>	[++i]. Clear Message Logs</a><br></dd>"
|
||||
dat += "<dd><A href='?src=\ref[src];clearr=1'>	[++i]. Clear Request Console Logs</a><br></dd>"
|
||||
dat += "<dd><A href='?src=\ref[src];pass=1'>	[++i]. Set Custom Key</a><br></dd>"
|
||||
dat += "<dd><A href='?src=\ref[src];msg=1'>	[++i]. Send Admin Message</a><br></dd>"
|
||||
else
|
||||
for(var/n = ++i; n <= optioncount; n++)
|
||||
dat += "<dd><font color='blue'>	[n]. ---------------</font><br></dd>"
|
||||
if(issilicon(usr) && is_special_character(usr))
|
||||
//Malf/Traitor AIs can bruteforce into the system to gain the Key.
|
||||
dat += "<dd><A href='?src=\ref[src];hack=1'><i><font color='Red'>*&@#. Bruteforce Key</font></i></font></a><br></dd>"
|
||||
else
|
||||
dat += "<br>"
|
||||
|
||||
//Bottom message
|
||||
if(!auth)
|
||||
dat += "<br><hr><dd><span class='notice'>Please authenticate with the server in order to show additional options.</span>"
|
||||
else
|
||||
dat += "<br><hr><dd><span class='warning'>Reg, #514 forbids sending messages to a Head of Staff containing Erotic Rendering Properties.</span>"
|
||||
|
||||
//Message Logs
|
||||
if(1)
|
||||
var/index = 0
|
||||
//var/recipient = "Unspecified" //name of the person
|
||||
//var/sender = "Unspecified" //name of the sender
|
||||
//var/message = "Blank" //transferred message
|
||||
dat += "<center><A href='?src=\ref[src];back=1'>Back</a> - <A href='?src=\ref[src];refresh=1'>Refresh</center><hr>"
|
||||
dat += "<table border='1' width='100%'><tr><th width = '5%'>X</th><th width='15%'>Sender</th><th width='15%'>Recipient</th><th width='300px' word-wrap: break-word>Message</th></tr>"
|
||||
for(var/datum/data_pda_msg/pda in src.linkedServer.pda_msgs)
|
||||
index++
|
||||
if(index > 3000)
|
||||
break
|
||||
// Del - Sender - Recepient - Message
|
||||
// X - Al Green - Your Mom - WHAT UP!?
|
||||
dat += "<tr><td width = '5%'><center><A href='?src=\ref[src];delete=\ref[pda]' style='color: rgb(255,0,0)'>X</a></center></td><td width='15%'>[pda.sender]</td><td width='15%'>[pda.recipient]</td><td width='300px'>[pda.message][pda.photo ? "<a href='byond://?src=\ref[pda];photo=1'>(Photo)</a>":""]</td></tr>"
|
||||
dat += "</table>"
|
||||
//Hacking screen.
|
||||
if(2)
|
||||
if(isAI(user) || iscyborg(user))
|
||||
dat += "Brute-forcing for server key.<br> It will take 20 seconds for every character that the password has."
|
||||
dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time."
|
||||
else
|
||||
//It's the same message as the one above but in binary. Because robots understand binary and humans don't... well I thought it was clever.
|
||||
dat += {"01000010011100100111010101110100011001010010110<br>
|
||||
10110011001101111011100100110001101101001011011100110011<br>
|
||||
10010000001100110011011110111001000100000011100110110010<br>
|
||||
10111001001110110011001010111001000100000011010110110010<br>
|
||||
10111100100101110001000000100100101110100001000000111011<br>
|
||||
10110100101101100011011000010000001110100011000010110101<br>
|
||||
10110010100100000001100100011000000100000011100110110010<br>
|
||||
10110001101101111011011100110010001110011001000000110011<br>
|
||||
00110111101110010001000000110010101110110011001010111001<br>
|
||||
00111100100100000011000110110100001100001011100100110000<br>
|
||||
10110001101110100011001010111001000100000011101000110100<br>
|
||||
00110000101110100001000000111010001101000011001010010000<br>
|
||||
00111000001100001011100110111001101110111011011110111001<br>
|
||||
00110010000100000011010000110000101110011001011100010000<br>
|
||||
00100100101101110001000000111010001101000011001010010000<br>
|
||||
00110110101100101011000010110111001110100011010010110110<br>
|
||||
10110010100101100001000000111010001101000011010010111001<br>
|
||||
10010000001100011011011110110111001110011011011110110110<br>
|
||||
00110010100100000011000110110000101101110001000000111001<br>
|
||||
00110010101110110011001010110000101101100001000000111100<br>
|
||||
10110111101110101011100100010000001110100011100100111010<br>
|
||||
10110010100100000011010010110111001110100011001010110111<br>
|
||||
00111010001101001011011110110111001110011001000000110100<br>
|
||||
10110011000100000011110010110111101110101001000000110110<br>
|
||||
00110010101110100001000000111001101101111011011010110010<br>
|
||||
10110111101101110011001010010000001100001011000110110001<br>
|
||||
10110010101110011011100110010000001101001011101000010111<br>
|
||||
00010000001001101011000010110101101100101001000000111001<br>
|
||||
10111010101110010011001010010000001101110011011110010000<br>
|
||||
00110100001110101011011010110000101101110011100110010000<br>
|
||||
00110010101101110011101000110010101110010001000000111010<br>
|
||||
00110100001100101001000000111001001101111011011110110110<br>
|
||||
10010000001100100011101010111001001101001011011100110011<br>
|
||||
10010000001110100011010000110000101110100001000000111010<br>
|
||||
001101001011011010110010100101110"}
|
||||
|
||||
//Fake messages
|
||||
if(3)
|
||||
dat += "<center><A href='?src=\ref[src];back=1'>Back</a> - <A href='?src=\ref[src];Reset=1'>Reset</a></center><hr>"
|
||||
|
||||
dat += {"<table border='1' width='100%'>
|
||||
<tr><td width='20%'><A href='?src=\ref[src];select=Sender'>Sender</a></td>
|
||||
<td width='20%'><A href='?src=\ref[src];select=RecJob'>Sender's Job</a></td>
|
||||
<td width='20%'><A href='?src=\ref[src];select=Recepient'>Recipient</a></td>
|
||||
<td width='300px' word-wrap: break-word><A href='?src=\ref[src];select=Message'>Message</a></td></tr>"}
|
||||
//Sender - Sender's Job - Recepient - Message
|
||||
//Al Green- Your Dad - Your Mom - WHAT UP!?
|
||||
|
||||
dat += {"<tr><td width='20%'>[customsender]</td>
|
||||
<td width='20%'>[customjob]</td>
|
||||
<td width='20%'>[customrecepient ? customrecepient.owner : "NONE"]</td>
|
||||
<td width='300px'>[custommessage]</td></tr>"}
|
||||
dat += "</table><br><center><A href='?src=\ref[src];select=Send'>Send</a>"
|
||||
|
||||
//Request Console Logs
|
||||
if(4)
|
||||
|
||||
var/index = 0
|
||||
/* data_rc_msg
|
||||
X - 5%
|
||||
var/rec_dpt = "Unspecified" //name of the person - 15%
|
||||
var/send_dpt = "Unspecified" //name of the sender- 15%
|
||||
var/message = "Blank" //transferred message - 300px
|
||||
var/stamp = "Unstamped" - 15%
|
||||
var/id_auth = "Unauthenticated" - 15%
|
||||
var/priority = "Normal" - 10%
|
||||
*/
|
||||
dat += "<center><A href='?src=\ref[src];back=1'>Back</a> - <A href='?src=\ref[src];refresh=1'>Refresh</center><hr>"
|
||||
dat += {"<table border='1' width='100%'><tr><th width = '5%'>X</th><th width='15%'>Sending Dep.</th><th width='15%'>Receiving Dep.</th>
|
||||
<th width='300px' word-wrap: break-word>Message</th><th width='15%'>Stamp</th><th width='15%'>ID Auth.</th><th width='15%'>Priority.</th></tr>"}
|
||||
for(var/datum/data_rc_msg/rc in src.linkedServer.rc_msgs)
|
||||
index++
|
||||
if(index > 3000)
|
||||
break
|
||||
// Del - Sender - Recepient - Message
|
||||
// X - Al Green - Your Mom - WHAT UP!?
|
||||
dat += {"<tr><td width = '5%'><center><A href='?src=\ref[src];deleter=\ref[rc]' style='color: rgb(255,0,0)'>X</a></center></td><td width='15%'>[rc.send_dpt]</td>
|
||||
<td width='15%'>[rc.rec_dpt]</td><td width='300px'>[rc.message]</td><td width='15%'>[rc.stamp]</td><td width='15%'>[rc.id_auth]</td><td width='15%'>[rc.priority]</td></tr>"}
|
||||
dat += "</table>"
|
||||
|
||||
message = defaultmsg
|
||||
var/datum/browser/popup = new(user, "hologram_console", name, 700, 700)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/message_monitor/proc/BruteForce(mob/user)
|
||||
if(isnull(linkedServer))
|
||||
to_chat(user, "<span class='warning'>Could not complete brute-force: Linked Server Disconnected!</span>")
|
||||
else
|
||||
var/currentKey = src.linkedServer.decryptkey
|
||||
to_chat(user, "<span class='warning'>Brute-force completed! The key is '[currentKey]'.</span>")
|
||||
src.hacking = 0
|
||||
src.screen = 0 // Return the screen back to normal
|
||||
|
||||
/obj/machinery/computer/message_monitor/proc/UnmagConsole()
|
||||
emagged = FALSE
|
||||
|
||||
/obj/machinery/computer/message_monitor/proc/ResetMessage()
|
||||
customsender = "System Administrator"
|
||||
customrecepient = null
|
||||
custommessage = "This is a test, please ignore."
|
||||
customjob = "Admin"
|
||||
|
||||
/obj/machinery/computer/message_monitor/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr))
|
||||
//Authenticate
|
||||
if (href_list["auth"])
|
||||
if(!linkedServer || linkedServer.stat & (NOPOWER|BROKEN))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
auth = 0
|
||||
screen = 0
|
||||
else
|
||||
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
|
||||
if(dkey && dkey != "")
|
||||
if(src.linkedServer.decryptkey == dkey)
|
||||
auth = 1
|
||||
else
|
||||
message = incorrectkey
|
||||
|
||||
//Turn the server on/off.
|
||||
if (href_list["active"])
|
||||
if(auth)
|
||||
linkedServer.active = !linkedServer.active
|
||||
//Find a server
|
||||
if (href_list["find"])
|
||||
if(GLOB.message_servers && GLOB.message_servers.len > 1)
|
||||
src.linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in GLOB.message_servers
|
||||
message = "<span class='alert'>NOTICE: Server selected.</span>"
|
||||
else if(GLOB.message_servers && GLOB.message_servers.len > 0)
|
||||
linkedServer = GLOB.message_servers[1]
|
||||
message = "<span class='notice'>NOTICE: Only Single Server Detected - Server selected.</span>"
|
||||
else
|
||||
message = noserver
|
||||
|
||||
//View the logs - KEY REQUIRED
|
||||
if (href_list["view"])
|
||||
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.screen = 1
|
||||
|
||||
//Clears the logs - KEY REQUIRED
|
||||
if (href_list["clear"])
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.linkedServer.pda_msgs = list()
|
||||
message = "<span class='notice'>NOTICE: Logs cleared.</span>"
|
||||
//Clears the request console logs - KEY REQUIRED
|
||||
if (href_list["clearr"])
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.linkedServer.rc_msgs = list()
|
||||
message = "<span class='notice'>NOTICE: Logs cleared.</span>"
|
||||
//Change the password - KEY REQUIRED
|
||||
if (href_list["pass"])
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
var/dkey = trim(stripped_input(usr, "Please enter the decryption key."))
|
||||
if(dkey && dkey != "")
|
||||
if(src.linkedServer.decryptkey == dkey)
|
||||
var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):"))
|
||||
if(length(newkey) <= 3)
|
||||
message = "<span class='notice'>NOTICE: Decryption key too short!</span>"
|
||||
else if(length(newkey) > 16)
|
||||
message = "<span class='notice'>NOTICE: Decryption key too long!</span>"
|
||||
else if(newkey && newkey != "")
|
||||
src.linkedServer.decryptkey = newkey
|
||||
message = "<span class='notice'>NOTICE: Decryption key set.</span>"
|
||||
else
|
||||
message = incorrectkey
|
||||
|
||||
//Hack the Console to get the password
|
||||
if (href_list["hack"])
|
||||
if(issilicon(usr) && is_special_character(usr))
|
||||
src.hacking = 1
|
||||
src.screen = 2
|
||||
//Time it takes to bruteforce is dependant on the password length.
|
||||
spawn(100*length(src.linkedServer.decryptkey))
|
||||
if(src && src.linkedServer && usr)
|
||||
BruteForce(usr)
|
||||
//Delete the log.
|
||||
if (href_list["delete"])
|
||||
//Are they on the view logs screen?
|
||||
if(screen == 1)
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else //if(istype(href_list["delete"], /datum/data_pda_msg))
|
||||
src.linkedServer.pda_msgs -= locate(href_list["delete"])
|
||||
message = "<span class='notice'>NOTICE: Log Deleted!</span>"
|
||||
//Delete the request console log.
|
||||
if (href_list["deleter"])
|
||||
//Are they on the view logs screen?
|
||||
if(screen == 4)
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else //if(istype(href_list["delete"], /datum/data_pda_msg))
|
||||
src.linkedServer.rc_msgs -= locate(href_list["deleter"])
|
||||
message = "<span class='notice'>NOTICE: Log Deleted!</span>"
|
||||
//Create a custom message
|
||||
if (href_list["msg"])
|
||||
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.screen = 3
|
||||
//Fake messaging selection - KEY REQUIRED
|
||||
if (href_list["select"])
|
||||
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
screen = 0
|
||||
else
|
||||
switch(href_list["select"])
|
||||
|
||||
//Reset
|
||||
if("Reset")
|
||||
ResetMessage()
|
||||
|
||||
//Select Your Name
|
||||
if("Sender")
|
||||
customsender = stripped_input(usr, "Please enter the sender's name.")
|
||||
|
||||
//Select Receiver
|
||||
if("Recepient")
|
||||
//Get out list of viable PDAs
|
||||
var/list/obj/item/device/pda/sendPDAs = get_viewable_pdas()
|
||||
if(GLOB.PDAs && GLOB.PDAs.len > 0)
|
||||
customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortNames(sendPDAs)
|
||||
else
|
||||
customrecepient = null
|
||||
|
||||
//Enter custom job
|
||||
if("RecJob")
|
||||
customjob = stripped_input(usr, "Please enter the sender's job.")
|
||||
|
||||
//Enter message
|
||||
if("Message")
|
||||
custommessage = stripped_input(usr, "Please enter your message.")
|
||||
|
||||
//Send message
|
||||
if("Send")
|
||||
|
||||
if(isnull(customsender) || customsender == "")
|
||||
customsender = "UNKNOWN"
|
||||
|
||||
if(isnull(customrecepient))
|
||||
message = "<span class='notice'>NOTICE: No recepient selected!</span>"
|
||||
return src.attack_hand(usr)
|
||||
|
||||
if(isnull(custommessage) || custommessage == "")
|
||||
message = "<span class='notice'>NOTICE: No message entered!</span>"
|
||||
return src.attack_hand(usr)
|
||||
|
||||
var/obj/item/device/pda/PDARec = null
|
||||
for (var/obj/item/device/pda/P in get_viewable_pdas())
|
||||
if(P.owner == customsender)
|
||||
PDARec = P
|
||||
//Sender isn't faking as someone who exists
|
||||
if(isnull(PDARec))
|
||||
src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]")
|
||||
customrecepient.tnote += "<i><b>← From <a href='byond://?src=\ref[customrecepient];choice=Message;target=\ref[src]'>[customsender]</a> ([customjob]):</b></i><br>[custommessage]<br>"
|
||||
if (!customrecepient.silent)
|
||||
playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
customrecepient.audible_message("[icon2html(customrecepient, viewers(customrecepient))] *[customrecepient.ttone]*", null, 3)
|
||||
if( customrecepient.loc && ishuman(customrecepient.loc) )
|
||||
var/mob/living/carbon/human/H = customrecepient.loc
|
||||
to_chat(H, "[icon2html(customrecepient, viewers(H))] <b>Message from [customsender] ([customjob]), </b>\"[custommessage]\" (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[src]'>Reply</a>)")
|
||||
log_talk(usr,"[key_name(usr)] (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]",LOGPDA)
|
||||
customrecepient.cut_overlays()
|
||||
customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r"))
|
||||
//Sender is faking as someone who exists
|
||||
else
|
||||
src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]")
|
||||
customrecepient.tnote += "<i><b>← From <a href='byond://?src=\ref[customrecepient];choice=Message;target=\ref[PDARec]'>[PDARec.owner]</a> ([customjob]):</b></i><br>[custommessage]<br>"
|
||||
if (!customrecepient.silent)
|
||||
playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
customrecepient.audible_message("[icon2html(customrecepient, viewers(customrecepient))] *[customrecepient.ttone]*", null, 3)
|
||||
if( customrecepient.loc && ishuman(customrecepient.loc) )
|
||||
var/mob/living/carbon/human/H = customrecepient.loc
|
||||
to_chat(H, "[icon2html(customrecepient, H)] <b>Message from [PDARec.owner] ([customjob]), </b>\"[custommessage]\" (<a href='byond://?src=\ref[customrecepient];choice=Message;skiprefresh=1;target=\ref[PDARec]'>Reply</a>)")
|
||||
log_talk(usr,"[key_name(usr)] (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]",LOGPDA)
|
||||
customrecepient.cut_overlays()
|
||||
customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r"))
|
||||
//Finally..
|
||||
ResetMessage()
|
||||
|
||||
//Request Console Logs - KEY REQUIRED
|
||||
if(href_list["viewr"])
|
||||
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.screen = 4
|
||||
|
||||
if (href_list["back"])
|
||||
src.screen = 0
|
||||
|
||||
return src.attack_hand(usr)
|
||||
|
||||
|
||||
/obj/item/paper/monitorkey
|
||||
//..()
|
||||
name = "monitor decryption key"
|
||||
var/obj/machinery/message_server/server = null
|
||||
|
||||
/obj/item/paper/monitorkey/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/item/paper/monitorkey/LateInitialize()
|
||||
if(GLOB.message_servers)
|
||||
for(var/obj/machinery/message_server/server in GLOB.message_servers)
|
||||
if(!isnull(server))
|
||||
if(!isnull(server.decryptkey))
|
||||
info = "<center><h2>Daily Key Reset</h2></center><br>The new message monitor key is '[server.decryptkey]'.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one."
|
||||
info_links = info
|
||||
add_overlay("paper_words")
|
||||
break
|
||||
// Allows you to monitor messages that passes the server.
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/machinery/computer/message_monitor
|
||||
name = "message monitor console"
|
||||
desc = "Used to Monitor the crew's messages, that are sent via PDA. Can also be used to view Request Console messages."
|
||||
icon_screen = "comm_logs"
|
||||
circuit = /obj/item/circuitboard/computer/message_monitor
|
||||
//Server linked to.
|
||||
var/obj/machinery/message_server/linkedServer = null
|
||||
//Sparks effect - For emag
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
|
||||
//Messages - Saves me time if I want to change something.
|
||||
var/noserver = "<span class='alert'>ALERT: No server detected.</span>"
|
||||
var/incorrectkey = "<span class='warning'>ALERT: Incorrect decryption key!</span>"
|
||||
var/defaultmsg = "<span class='notice'>Welcome. Please select an option.</span>"
|
||||
var/rebootmsg = "<span class='warning'>%$&(�: Critical %$$@ Error // !RestArting! <lOadiNg backUp iNput ouTput> - ?pLeaSe wAit!</span>"
|
||||
//Computer properties
|
||||
var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message
|
||||
var/hacking = 0 // Is it being hacked into by the AI/Cyborg
|
||||
var/message = "<span class='notice'>System bootup complete. Please select an option.</span>" // The message that shows on the main menu.
|
||||
var/auth = 0 // Are they authenticated?
|
||||
var/optioncount = 7
|
||||
// Custom Message Properties
|
||||
var/customsender = "System Administrator"
|
||||
var/obj/item/device/pda/customrecepient = null
|
||||
var/customjob = "Admin"
|
||||
var/custommessage = "This is a test, please ignore."
|
||||
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/machinery/computer/message_monitor/attackby(obj/item/O, mob/living/user, params)
|
||||
if(istype(O, /obj/item/screwdriver) && emagged)
|
||||
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
|
||||
to_chat(user, "<span class='warning'>It is too hot to mess with!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/message_monitor/emag_act(mob/user)
|
||||
if(emagged)
|
||||
return
|
||||
if(!isnull(src.linkedServer))
|
||||
emagged = TRUE
|
||||
screen = 2
|
||||
spark_system.set_up(5, 0, src)
|
||||
src.spark_system.start()
|
||||
var/obj/item/paper/monitorkey/MK = new/obj/item/paper/monitorkey
|
||||
MK.loc = src.loc
|
||||
// Will help make emagging the console not so easy to get away with.
|
||||
MK.info += "<br><br><font color='red'>�%@%(*$%&(�&?*(%&�/{}</font>"
|
||||
var/time = 100 * length(src.linkedServer.decryptkey)
|
||||
addtimer(CALLBACK(src, .proc/UnmagConsole), time)
|
||||
message = rebootmsg
|
||||
else
|
||||
to_chat(user, "<span class='notice'>A no server error appears on the screen.</span>")
|
||||
|
||||
/obj/machinery/computer/message_monitor/Initialize()
|
||||
. = ..()
|
||||
//Is the server isn't linked to a server, and there's a server available, default it to the first one in the list.
|
||||
if(!linkedServer)
|
||||
if(GLOB.message_servers && GLOB.message_servers.len > 0)
|
||||
linkedServer = GLOB.message_servers[1]
|
||||
|
||||
/obj/machinery/computer/message_monitor/attack_hand(mob/living/user)
|
||||
if(..())
|
||||
return
|
||||
//If the computer is being hacked or is emagged, display the reboot message.
|
||||
if(hacking || emagged)
|
||||
message = rebootmsg
|
||||
var/dat = "<center><font color='blue'[message]</font>/</center>"
|
||||
|
||||
if(auth)
|
||||
dat += "<h4><dd><A href='?src=[REF(src)];auth=1'>	<font color='green'>\[Authenticated\]</font></a>	/"
|
||||
dat += " Server Power: <A href='?src=[REF(src)];active=1'>[src.linkedServer && src.linkedServer.active ? "<font color='green'>\[On\]</font>":"<font color='red'>\[Off\]</font>"]</a></h4>"
|
||||
else
|
||||
dat += "<h4><dd><A href='?src=[REF(src)];auth=1'>	<font color='red'>\[Unauthenticated\]</font></a>	/"
|
||||
dat += " Server Power: <u>[src.linkedServer && src.linkedServer.active ? "<font color='green'>\[On\]</font>":"<font color='red'>\[Off\]</font>"]</u></h4>"
|
||||
|
||||
if(hacking || emagged)
|
||||
screen = 2
|
||||
else if(!auth || !linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
screen = 0
|
||||
|
||||
switch(screen)
|
||||
//Main menu
|
||||
if(0)
|
||||
//	 = TAB
|
||||
var/i = 0
|
||||
dat += "<dd><A href='?src=[REF(src)];find=1'>	[++i]. Link To A Server</a></dd>"
|
||||
if(auth)
|
||||
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
dat += "<dd><A>	ERROR: Server not found!</A><br></dd>"
|
||||
else
|
||||
dat += "<dd><A href='?src=[REF(src)];view=1'>	[++i]. View Message Logs </a><br></dd>"
|
||||
dat += "<dd><A href='?src=[REF(src)];viewr=1'>	[++i]. View Request Console Logs </a></br></dd>"
|
||||
dat += "<dd><A href='?src=[REF(src)];clear=1'>	[++i]. Clear Message Logs</a><br></dd>"
|
||||
dat += "<dd><A href='?src=[REF(src)];clearr=1'>	[++i]. Clear Request Console Logs</a><br></dd>"
|
||||
dat += "<dd><A href='?src=[REF(src)];pass=1'>	[++i]. Set Custom Key</a><br></dd>"
|
||||
dat += "<dd><A href='?src=[REF(src)];msg=1'>	[++i]. Send Admin Message</a><br></dd>"
|
||||
else
|
||||
for(var/n = ++i; n <= optioncount; n++)
|
||||
dat += "<dd><font color='blue'>	[n]. ---------------</font><br></dd>"
|
||||
if(issilicon(usr) && is_special_character(usr))
|
||||
//Malf/Traitor AIs can bruteforce into the system to gain the Key.
|
||||
dat += "<dd><A href='?src=[REF(src)];hack=1'><i><font color='Red'>*&@#. Bruteforce Key</font></i></font></a><br></dd>"
|
||||
else
|
||||
dat += "<br>"
|
||||
|
||||
//Bottom message
|
||||
if(!auth)
|
||||
dat += "<br><hr><dd><span class='notice'>Please authenticate with the server in order to show additional options.</span>"
|
||||
else
|
||||
dat += "<br><hr><dd><span class='warning'>Reg, #514 forbids sending messages to a Head of Staff containing Erotic Rendering Properties.</span>"
|
||||
|
||||
//Message Logs
|
||||
if(1)
|
||||
var/index = 0
|
||||
//var/recipient = "Unspecified" //name of the person
|
||||
//var/sender = "Unspecified" //name of the sender
|
||||
//var/message = "Blank" //transferred message
|
||||
dat += "<center><A href='?src=[REF(src)];back=1'>Back</a> - <A href='?src=[REF(src)];refresh=1'>Refresh</center><hr>"
|
||||
dat += "<table border='1' width='100%'><tr><th width = '5%'>X</th><th width='15%'>Sender</th><th width='15%'>Recipient</th><th width='300px' word-wrap: break-word>Message</th></tr>"
|
||||
for(var/datum/data_pda_msg/pda in src.linkedServer.pda_msgs)
|
||||
index++
|
||||
if(index > 3000)
|
||||
break
|
||||
// Del - Sender - Recepient - Message
|
||||
// X - Al Green - Your Mom - WHAT UP!?
|
||||
dat += "<tr><td width = '5%'><center><A href='?src=[REF(src)];delete=[REF(pda)]' style='color: rgb(255,0,0)'>X</a></center></td><td width='15%'>[pda.sender]</td><td width='15%'>[pda.recipient]</td><td width='300px'>[pda.message][pda.photo ? "<a href='byond://?src=[REF(pda)];photo=1'>(Photo)</a>":""]</td></tr>"
|
||||
dat += "</table>"
|
||||
//Hacking screen.
|
||||
if(2)
|
||||
if(isAI(user) || iscyborg(user))
|
||||
dat += "Brute-forcing for server key.<br> It will take 20 seconds for every character that the password has."
|
||||
dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time."
|
||||
else
|
||||
//It's the same message as the one above but in binary. Because robots understand binary and humans don't... well I thought it was clever.
|
||||
dat += {"01000010011100100111010101110100011001010010110<br>
|
||||
10110011001101111011100100110001101101001011011100110011<br>
|
||||
10010000001100110011011110111001000100000011100110110010<br>
|
||||
10111001001110110011001010111001000100000011010110110010<br>
|
||||
10111100100101110001000000100100101110100001000000111011<br>
|
||||
10110100101101100011011000010000001110100011000010110101<br>
|
||||
10110010100100000001100100011000000100000011100110110010<br>
|
||||
10110001101101111011011100110010001110011001000000110011<br>
|
||||
00110111101110010001000000110010101110110011001010111001<br>
|
||||
00111100100100000011000110110100001100001011100100110000<br>
|
||||
10110001101110100011001010111001000100000011101000110100<br>
|
||||
00110000101110100001000000111010001101000011001010010000<br>
|
||||
00111000001100001011100110111001101110111011011110111001<br>
|
||||
00110010000100000011010000110000101110011001011100010000<br>
|
||||
00100100101101110001000000111010001101000011001010010000<br>
|
||||
00110110101100101011000010110111001110100011010010110110<br>
|
||||
10110010100101100001000000111010001101000011010010111001<br>
|
||||
10010000001100011011011110110111001110011011011110110110<br>
|
||||
00110010100100000011000110110000101101110001000000111001<br>
|
||||
00110010101110110011001010110000101101100001000000111100<br>
|
||||
10110111101110101011100100010000001110100011100100111010<br>
|
||||
10110010100100000011010010110111001110100011001010110111<br>
|
||||
00111010001101001011011110110111001110011001000000110100<br>
|
||||
10110011000100000011110010110111101110101001000000110110<br>
|
||||
00110010101110100001000000111001101101111011011010110010<br>
|
||||
10110111101101110011001010010000001100001011000110110001<br>
|
||||
10110010101110011011100110010000001101001011101000010111<br>
|
||||
00010000001001101011000010110101101100101001000000111001<br>
|
||||
10111010101110010011001010010000001101110011011110010000<br>
|
||||
00110100001110101011011010110000101101110011100110010000<br>
|
||||
00110010101101110011101000110010101110010001000000111010<br>
|
||||
00110100001100101001000000111001001101111011011110110110<br>
|
||||
10010000001100100011101010111001001101001011011100110011<br>
|
||||
10010000001110100011010000110000101110100001000000111010<br>
|
||||
001101001011011010110010100101110"}
|
||||
|
||||
//Fake messages
|
||||
if(3)
|
||||
dat += "<center><A href='?src=[REF(src)];back=1'>Back</a> - <A href='?src=[REF(src)];Reset=1'>Reset</a></center><hr>"
|
||||
|
||||
dat += {"<table border='1' width='100%'>
|
||||
<tr><td width='20%'><A href='?src=[REF(src)];select=Sender'>Sender</a></td>
|
||||
<td width='20%'><A href='?src=[REF(src)];select=RecJob'>Sender's Job</a></td>
|
||||
<td width='20%'><A href='?src=[REF(src)];select=Recepient'>Recipient</a></td>
|
||||
<td width='300px' word-wrap: break-word><A href='?src=[REF(src)];select=Message'>Message</a></td></tr>"}
|
||||
//Sender - Sender's Job - Recepient - Message
|
||||
//Al Green- Your Dad - Your Mom - WHAT UP!?
|
||||
|
||||
dat += {"<tr><td width='20%'>[customsender]</td>
|
||||
<td width='20%'>[customjob]</td>
|
||||
<td width='20%'>[customrecepient ? customrecepient.owner : "NONE"]</td>
|
||||
<td width='300px'>[custommessage]</td></tr>"}
|
||||
dat += "</table><br><center><A href='?src=[REF(src)];select=Send'>Send</a>"
|
||||
|
||||
//Request Console Logs
|
||||
if(4)
|
||||
|
||||
var/index = 0
|
||||
/* data_rc_msg
|
||||
X - 5%
|
||||
var/rec_dpt = "Unspecified" //name of the person - 15%
|
||||
var/send_dpt = "Unspecified" //name of the sender- 15%
|
||||
var/message = "Blank" //transferred message - 300px
|
||||
var/stamp = "Unstamped" - 15%
|
||||
var/id_auth = "Unauthenticated" - 15%
|
||||
var/priority = "Normal" - 10%
|
||||
*/
|
||||
dat += "<center><A href='?src=[REF(src)];back=1'>Back</a> - <A href='?src=[REF(src)];refresh=1'>Refresh</center><hr>"
|
||||
dat += {"<table border='1' width='100%'><tr><th width = '5%'>X</th><th width='15%'>Sending Dep.</th><th width='15%'>Receiving Dep.</th>
|
||||
<th width='300px' word-wrap: break-word>Message</th><th width='15%'>Stamp</th><th width='15%'>ID Auth.</th><th width='15%'>Priority.</th></tr>"}
|
||||
for(var/datum/data_rc_msg/rc in src.linkedServer.rc_msgs)
|
||||
index++
|
||||
if(index > 3000)
|
||||
break
|
||||
// Del - Sender - Recepient - Message
|
||||
// X - Al Green - Your Mom - WHAT UP!?
|
||||
dat += {"<tr><td width = '5%'><center><A href='?src=[REF(src)];deleter=[REF(rc)]' style='color: rgb(255,0,0)'>X</a></center></td><td width='15%'>[rc.send_dpt]</td>
|
||||
<td width='15%'>[rc.rec_dpt]</td><td width='300px'>[rc.message]</td><td width='15%'>[rc.stamp]</td><td width='15%'>[rc.id_auth]</td><td width='15%'>[rc.priority]</td></tr>"}
|
||||
dat += "</table>"
|
||||
|
||||
message = defaultmsg
|
||||
var/datum/browser/popup = new(user, "hologram_console", name, 700, 700)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/message_monitor/proc/BruteForce(mob/user)
|
||||
if(isnull(linkedServer))
|
||||
to_chat(user, "<span class='warning'>Could not complete brute-force: Linked Server Disconnected!</span>")
|
||||
else
|
||||
var/currentKey = src.linkedServer.decryptkey
|
||||
to_chat(user, "<span class='warning'>Brute-force completed! The key is '[currentKey]'.</span>")
|
||||
src.hacking = 0
|
||||
src.screen = 0 // Return the screen back to normal
|
||||
|
||||
/obj/machinery/computer/message_monitor/proc/UnmagConsole()
|
||||
emagged = FALSE
|
||||
|
||||
/obj/machinery/computer/message_monitor/proc/ResetMessage()
|
||||
customsender = "System Administrator"
|
||||
customrecepient = null
|
||||
custommessage = "This is a test, please ignore."
|
||||
customjob = "Admin"
|
||||
|
||||
/obj/machinery/computer/message_monitor/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr))
|
||||
//Authenticate
|
||||
if (href_list["auth"])
|
||||
if(!linkedServer || linkedServer.stat & (NOPOWER|BROKEN))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
auth = 0
|
||||
screen = 0
|
||||
else
|
||||
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
|
||||
if(dkey && dkey != "")
|
||||
if(src.linkedServer.decryptkey == dkey)
|
||||
auth = 1
|
||||
else
|
||||
message = incorrectkey
|
||||
|
||||
//Turn the server on/off.
|
||||
if (href_list["active"])
|
||||
if(auth)
|
||||
linkedServer.active = !linkedServer.active
|
||||
//Find a server
|
||||
if (href_list["find"])
|
||||
if(GLOB.message_servers && GLOB.message_servers.len > 1)
|
||||
src.linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in GLOB.message_servers
|
||||
message = "<span class='alert'>NOTICE: Server selected.</span>"
|
||||
else if(GLOB.message_servers && GLOB.message_servers.len > 0)
|
||||
linkedServer = GLOB.message_servers[1]
|
||||
message = "<span class='notice'>NOTICE: Only Single Server Detected - Server selected.</span>"
|
||||
else
|
||||
message = noserver
|
||||
|
||||
//View the logs - KEY REQUIRED
|
||||
if (href_list["view"])
|
||||
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.screen = 1
|
||||
|
||||
//Clears the logs - KEY REQUIRED
|
||||
if (href_list["clear"])
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.linkedServer.pda_msgs = list()
|
||||
message = "<span class='notice'>NOTICE: Logs cleared.</span>"
|
||||
//Clears the request console logs - KEY REQUIRED
|
||||
if (href_list["clearr"])
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.linkedServer.rc_msgs = list()
|
||||
message = "<span class='notice'>NOTICE: Logs cleared.</span>"
|
||||
//Change the password - KEY REQUIRED
|
||||
if (href_list["pass"])
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
var/dkey = trim(stripped_input(usr, "Please enter the decryption key."))
|
||||
if(dkey && dkey != "")
|
||||
if(src.linkedServer.decryptkey == dkey)
|
||||
var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):"))
|
||||
if(length(newkey) <= 3)
|
||||
message = "<span class='notice'>NOTICE: Decryption key too short!</span>"
|
||||
else if(length(newkey) > 16)
|
||||
message = "<span class='notice'>NOTICE: Decryption key too long!</span>"
|
||||
else if(newkey && newkey != "")
|
||||
src.linkedServer.decryptkey = newkey
|
||||
message = "<span class='notice'>NOTICE: Decryption key set.</span>"
|
||||
else
|
||||
message = incorrectkey
|
||||
|
||||
//Hack the Console to get the password
|
||||
if (href_list["hack"])
|
||||
if(issilicon(usr) && is_special_character(usr))
|
||||
src.hacking = 1
|
||||
src.screen = 2
|
||||
//Time it takes to bruteforce is dependant on the password length.
|
||||
spawn(100*length(src.linkedServer.decryptkey))
|
||||
if(src && src.linkedServer && usr)
|
||||
BruteForce(usr)
|
||||
//Delete the log.
|
||||
if (href_list["delete"])
|
||||
//Are they on the view logs screen?
|
||||
if(screen == 1)
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else //if(istype(href_list["delete"], /datum/data_pda_msg))
|
||||
src.linkedServer.pda_msgs -= locate(href_list["delete"])
|
||||
message = "<span class='notice'>NOTICE: Log Deleted!</span>"
|
||||
//Delete the request console log.
|
||||
if (href_list["deleter"])
|
||||
//Are they on the view logs screen?
|
||||
if(screen == 4)
|
||||
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else //if(istype(href_list["delete"], /datum/data_pda_msg))
|
||||
src.linkedServer.rc_msgs -= locate(href_list["deleter"])
|
||||
message = "<span class='notice'>NOTICE: Log Deleted!</span>"
|
||||
//Create a custom message
|
||||
if (href_list["msg"])
|
||||
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.screen = 3
|
||||
//Fake messaging selection - KEY REQUIRED
|
||||
if (href_list["select"])
|
||||
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
screen = 0
|
||||
else
|
||||
switch(href_list["select"])
|
||||
|
||||
//Reset
|
||||
if("Reset")
|
||||
ResetMessage()
|
||||
|
||||
//Select Your Name
|
||||
if("Sender")
|
||||
customsender = stripped_input(usr, "Please enter the sender's name.")
|
||||
|
||||
//Select Receiver
|
||||
if("Recepient")
|
||||
//Get out list of viable PDAs
|
||||
var/list/obj/item/device/pda/sendPDAs = get_viewable_pdas()
|
||||
if(GLOB.PDAs && GLOB.PDAs.len > 0)
|
||||
customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortNames(sendPDAs)
|
||||
else
|
||||
customrecepient = null
|
||||
|
||||
//Enter custom job
|
||||
if("RecJob")
|
||||
customjob = stripped_input(usr, "Please enter the sender's job.")
|
||||
|
||||
//Enter message
|
||||
if("Message")
|
||||
custommessage = stripped_input(usr, "Please enter your message.")
|
||||
|
||||
//Send message
|
||||
if("Send")
|
||||
|
||||
if(isnull(customsender) || customsender == "")
|
||||
customsender = "UNKNOWN"
|
||||
|
||||
if(isnull(customrecepient))
|
||||
message = "<span class='notice'>NOTICE: No recepient selected!</span>"
|
||||
return src.attack_hand(usr)
|
||||
|
||||
if(isnull(custommessage) || custommessage == "")
|
||||
message = "<span class='notice'>NOTICE: No message entered!</span>"
|
||||
return src.attack_hand(usr)
|
||||
|
||||
var/obj/item/device/pda/PDARec = null
|
||||
for (var/obj/item/device/pda/P in get_viewable_pdas())
|
||||
if(P.owner == customsender)
|
||||
PDARec = P
|
||||
//Sender isn't faking as someone who exists
|
||||
if(isnull(PDARec))
|
||||
src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]")
|
||||
customrecepient.tnote += "<i><b>← From <a href='byond://?src=[REF(customrecepient)];choice=Message;target=[REF(src)]'>[customsender]</a> ([customjob]):</b></i><br>[custommessage]<br>"
|
||||
if (!customrecepient.silent)
|
||||
playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
customrecepient.audible_message("[icon2html(customrecepient, viewers(customrecepient))] *[customrecepient.ttone]*", null, 3)
|
||||
if( customrecepient.loc && ishuman(customrecepient.loc) )
|
||||
var/mob/living/carbon/human/H = customrecepient.loc
|
||||
to_chat(H, "[icon2html(customrecepient, viewers(H))] <b>Message from [customsender] ([customjob]), </b>\"[custommessage]\" (<a href='byond://?src=[REF(src)];choice=Message;skiprefresh=1;target=[REF(src)]'>Reply</a>)")
|
||||
log_talk(usr,"[key_name(usr)] (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]",LOGPDA)
|
||||
customrecepient.cut_overlays()
|
||||
customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r"))
|
||||
//Sender is faking as someone who exists
|
||||
else
|
||||
src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]")
|
||||
customrecepient.tnote += "<i><b>← From <a href='byond://?src=[REF(customrecepient)];choice=Message;target=[REF(PDARec)]'>[PDARec.owner]</a> ([customjob]):</b></i><br>[custommessage]<br>"
|
||||
if (!customrecepient.silent)
|
||||
playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
customrecepient.audible_message("[icon2html(customrecepient, viewers(customrecepient))] *[customrecepient.ttone]*", null, 3)
|
||||
if( customrecepient.loc && ishuman(customrecepient.loc) )
|
||||
var/mob/living/carbon/human/H = customrecepient.loc
|
||||
to_chat(H, "[icon2html(customrecepient, H)] <b>Message from [PDARec.owner] ([customjob]), </b>\"[custommessage]\" (<a href='byond://?src=[REF(customrecepient)];choice=Message;skiprefresh=1;target=[REF(PDARec)]'>Reply</a>)")
|
||||
log_talk(usr,"[key_name(usr)] (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]",LOGPDA)
|
||||
customrecepient.cut_overlays()
|
||||
customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r"))
|
||||
//Finally..
|
||||
ResetMessage()
|
||||
|
||||
//Request Console Logs - KEY REQUIRED
|
||||
if(href_list["viewr"])
|
||||
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
|
||||
message = noserver
|
||||
else
|
||||
if(auth)
|
||||
src.screen = 4
|
||||
|
||||
if (href_list["back"])
|
||||
src.screen = 0
|
||||
|
||||
return src.attack_hand(usr)
|
||||
|
||||
|
||||
/obj/item/paper/monitorkey
|
||||
//..()
|
||||
name = "monitor decryption key"
|
||||
var/obj/machinery/message_server/server = null
|
||||
|
||||
/obj/item/paper/monitorkey/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/item/paper/monitorkey/LateInitialize()
|
||||
if(GLOB.message_servers)
|
||||
for(var/obj/machinery/message_server/server in GLOB.message_servers)
|
||||
if(!isnull(server))
|
||||
if(!isnull(server.decryptkey))
|
||||
info = "<center><h2>Daily Key Reset</h2></center><br>The new message monitor key is '[server.decryptkey]'.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one."
|
||||
info_links = info
|
||||
add_overlay("paper_words")
|
||||
break
|
||||
|
||||
@@ -48,21 +48,21 @@
|
||||
if(connected)
|
||||
var/d2
|
||||
if(timing) //door controls do not need timers.
|
||||
d2 = "<A href='?src=\ref[src];time=0'>Stop Time Launch</A>"
|
||||
d2 = "<A href='?src=[REF(src)];time=0'>Stop Time Launch</A>"
|
||||
else
|
||||
d2 = "<A href='?src=\ref[src];time=1'>Initiate Time Launch</A>"
|
||||
dat += "<HR>\nTimer System: [d2]\nTime Left: [DisplayTimeText(time)] <A href='?src=\ref[src];tp=-30'>-</A> <A href='?src=\ref[src];tp=-1'>-</A> <A href='?src=\ref[src];tp=1'>+</A> <A href='?src=\ref[src];tp=30'>+</A>"
|
||||
d2 = "<A href='?src=[REF(src)];time=1'>Initiate Time Launch</A>"
|
||||
dat += "<HR>\nTimer System: [d2]\nTime Left: [DisplayTimeText(time)] <A href='?src=[REF(src)];tp=-30'>-</A> <A href='?src=[REF(src)];tp=-1'>-</A> <A href='?src=[REF(src)];tp=1'>+</A> <A href='?src=[REF(src)];tp=30'>+</A>"
|
||||
var/temp = ""
|
||||
var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 )
|
||||
for(var/t in L)
|
||||
if(t == connected.power)
|
||||
temp += "[t] "
|
||||
else
|
||||
temp += "<A href = '?src=\ref[src];power=[t]'>[t]</A> "
|
||||
dat += "<HR>\nPower Level: [temp]<BR>\n<A href = '?src=\ref[src];alarm=1'>Firing Sequence</A><BR>\n<A href = '?src=\ref[src];drive=1'>Test Fire Driver</A><BR>\n<A href = '?src=\ref[src];door=1'>Toggle Outer Door</A><BR>"
|
||||
temp += "<A href = '?src=[REF(src)];power=[t]'>[t]</A> "
|
||||
dat += "<HR>\nPower Level: [temp]<BR>\n<A href = '?src=[REF(src)];alarm=1'>Firing Sequence</A><BR>\n<A href = '?src=[REF(src)];drive=1'>Test Fire Driver</A><BR>\n<A href = '?src=[REF(src)];door=1'>Toggle Outer Door</A><BR>"
|
||||
else
|
||||
dat += "<BR>\n<A href = '?src=\ref[src];door=1'>Toggle Outer Door</A><BR>"
|
||||
dat += "<BR><BR><A href='?src=\ref[user];mach_close=computer'>Close</A>"
|
||||
dat += "<BR>\n<A href = '?src=[REF(src)];door=1'>Toggle Outer Door</A><BR>"
|
||||
dat += "<BR><BR><A href='?src=[REF(user)];mach_close=computer'>Close</A>"
|
||||
add_fingerprint(usr)
|
||||
var/datum/browser/popup = new(user, "computer", title, 400, 500)
|
||||
popup.set_content(dat)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user