Merge remote-tracking branch 'refs/remotes/Citadel-Station-13/master' into IHAVENOIDEAWHATTHEFUCKIMDOING

This commit is contained in:
deathride58
2017-11-20 00:21:38 -05:00
1218 changed files with 80559 additions and 76738 deletions
+58 -49
View File
@@ -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 -2
View File
@@ -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
View File
@@ -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)
+2 -1
View File
@@ -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"
+2
View File
@@ -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"
+5 -4
View File
@@ -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
+4 -2
View File
@@ -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"
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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"
+14 -1
View File
@@ -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
+1
View File
@@ -2,6 +2,7 @@
/area/spacecontent
name = "space"
ambientsounds = AWAY_MISSION
/area/spacecontent/a1
icon_state = "spacecontent1"
+21 -31
View File
@@ -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
+3 -6
View File
@@ -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
View File
@@ -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)
+4 -4
View File
@@ -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")
+39 -48
View File
@@ -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(..())
+9 -5
View File
@@ -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
+19 -18
View File
@@ -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"
+2 -2
View File
@@ -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"
+14 -360
View File
@@ -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
+36 -34
View File
@@ -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
+121 -118
View File
@@ -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)
+12 -1
View File
@@ -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
+2 -1
View File
@@ -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)
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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>")
+1 -1
View File
@@ -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()
+2 -3
View File
@@ -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
+13 -18
View File
@@ -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.
+4 -2
View File
@@ -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
+23 -19
View File
@@ -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
+14 -10
View File
@@ -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))
+1 -1
View File
@@ -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)
+139 -139
View File
@@ -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()
+16 -16
View File
@@ -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")
+2 -1
View File
@@ -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>"
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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()
+4 -4
View File
@@ -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
+17 -17
View File
@@ -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)
+2 -2
View File
@@ -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)
+15 -15
View File
@@ -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>"
+3 -3
View File
@@ -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>")
+27 -9
View File
@@ -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()
+54 -52
View File
@@ -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
+16 -14
View File
@@ -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.
+168 -172
View File
@@ -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
+2 -4
View File
@@ -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)
..()
+1 -6
View File
@@ -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
+72 -74
View File
@@ -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
+2 -2
View File
@@ -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))
+22 -22
View File
@@ -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"])
+47 -47
View File
@@ -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
+24 -24
View File
@@ -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, " ", "&nbsp")]</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, " ", "&nbsp")]</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), " ", "&nbsp")]</font></a> "
accesses += "<a href='?src=[REF(src)];choice=access;access_target=[A];allowed=0'><font color=\"red\">[replacetext(get_centcom_access_desc(A), " ", "&nbsp")]</font></a> "
else
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=1'>[replacetext(get_centcom_access_desc(A), " ", "&nbsp")]</a> "
accesses += "<a href='?src=[REF(src)];choice=access;access_target=[A];allowed=1'>[replacetext(get_centcom_access_desc(A), " ", "&nbsp")]</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), " ", "&nbsp")]</font></a> "
accesses += "<a href='?src=[REF(src)];choice=access;access_target=[A];allowed=0'><font color=\"red\">[replacetext(get_access_desc(A), " ", "&nbsp")]</font></a> "
else
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=1'>[replacetext(get_access_desc(A), " ", "&nbsp")]</a> "
accesses += "<a href='?src=[REF(src)];choice=access;access_target=[A];allowed=1'>[replacetext(get_access_desc(A), " ", "&nbsp")]</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)
+24 -25
View File
@@ -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."
+210 -164
View File
@@ -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
+3 -7
View File
@@ -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)
+32 -32
View File
@@ -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'>&nbsp;&nbsp;\> 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())
+51 -51
View File
@@ -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'>&nbsp;[active1.fields["sex"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Age:</td><td><A href='?src=\ref[src];field=age'>&nbsp;[active1.fields["age"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Species:</td><td><A href='?src=\ref[src];field=species'>&nbsp;[active1.fields["species"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Fingerprint:</td><td><A href='?src=\ref[src];field=fingerprint'>&nbsp;[active1.fields["fingerprint"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Physical Status:</td><td><A href='?src=\ref[src];field=p_stat'>&nbsp;[active1.fields["p_stat"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Mental Status:</td><td><A href='?src=\ref[src];field=m_stat'>&nbsp;[active1.fields["m_stat"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Sex:</td><td><A href='?src=[REF(src)];field=sex'>&nbsp;[active1.fields["sex"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Age:</td><td><A href='?src=[REF(src)];field=age'>&nbsp;[active1.fields["age"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Species:</td><td><A href='?src=[REF(src)];field=species'>&nbsp;[active1.fields["species"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Fingerprint:</td><td><A href='?src=[REF(src)];field=fingerprint'>&nbsp;[active1.fields["fingerprint"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Physical Status:</td><td><A href='?src=[REF(src)];field=p_stat'>&nbsp;[active1.fields["p_stat"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Mental Status:</td><td><A href='?src=[REF(src)];field=m_stat'>&nbsp;[active1.fields["m_stat"]]&nbsp;</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'>&nbsp;[active2.fields["blood_type"]]&nbsp;</A></td></tr>"
dat += "<tr><td>DNA:</td><td><A href='?src=\ref[src];field=b_dna'>&nbsp;[active2.fields["b_dna"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Minor Disabilities:</td><td><br><A href='?src=\ref[src];field=mi_dis'>&nbsp;[active2.fields["mi_dis"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Details:</td><td><A href='?src=\ref[src];field=mi_dis_d'>&nbsp;[active2.fields["mi_dis_d"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Major Disabilities:</td><td><br><A href='?src=\ref[src];field=ma_dis'>&nbsp;[active2.fields["ma_dis"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Details:</td><td><A href='?src=\ref[src];field=ma_dis_d'>&nbsp;[active2.fields["ma_dis_d"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Allergies:</td><td><br><A href='?src=\ref[src];field=alg'>&nbsp;[active2.fields["alg"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Details:</td><td><A href='?src=\ref[src];field=alg_d'>&nbsp;[active2.fields["alg_d"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Current Diseases:</td><td><br><A href='?src=\ref[src];field=cdi'>&nbsp;[active2.fields["cdi"]]&nbsp;</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'>&nbsp;[active2.fields["cdi_d"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Important Notes:</td><td><br><A href='?src=\ref[src];field=notes'>&nbsp;[active2.fields["notes"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Blood Type:</td><td><A href='?src=[REF(src)];field=blood_type'>&nbsp;[active2.fields["blood_type"]]&nbsp;</A></td></tr>"
dat += "<tr><td>DNA:</td><td><A href='?src=[REF(src)];field=b_dna'>&nbsp;[active2.fields["b_dna"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Minor Disabilities:</td><td><br><A href='?src=[REF(src)];field=mi_dis'>&nbsp;[active2.fields["mi_dis"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Details:</td><td><A href='?src=[REF(src)];field=mi_dis_d'>&nbsp;[active2.fields["mi_dis_d"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Major Disabilities:</td><td><br><A href='?src=[REF(src)];field=ma_dis'>&nbsp;[active2.fields["ma_dis"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Details:</td><td><A href='?src=[REF(src)];field=ma_dis_d'>&nbsp;[active2.fields["ma_dis_d"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Allergies:</td><td><br><A href='?src=[REF(src)];field=alg'>&nbsp;[active2.fields["alg"]]&nbsp;</A></td></tr>"
dat += "<tr><td>Details:</td><td><A href='?src=[REF(src)];field=alg_d'>&nbsp;[active2.fields["alg_d"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Current Diseases:</td><td><br><A href='?src=[REF(src)];field=cdi'>&nbsp;[active2.fields["cdi"]]&nbsp;</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'>&nbsp;[active2.fields["cdi_d"]]&nbsp;</A></td></tr>"
dat += "<tr><td><br>Important Notes:</td><td><br><A href='?src=[REF(src)];field=notes'>&nbsp;[active2.fields["notes"]]&nbsp;</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
+472 -473
View File
@@ -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'>&#09;<font color='green'>\[Authenticated\]</font></a>&#09;/"
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'>&#09;<font color='red'>\[Unauthenticated\]</font></a>&#09;/"
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)
//&#09; = TAB
var/i = 0
dat += "<dd><A href='?src=\ref[src];find=1'>&#09;[++i]. Link To A Server</a></dd>"
if(auth)
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
dat += "<dd><A>&#09;ERROR: Server not found!</A><br></dd>"
else
dat += "<dd><A href='?src=\ref[src];view=1'>&#09;[++i]. View Message Logs </a><br></dd>"
dat += "<dd><A href='?src=\ref[src];viewr=1'>&#09;[++i]. View Request Console Logs </a></br></dd>"
dat += "<dd><A href='?src=\ref[src];clear=1'>&#09;[++i]. Clear Message Logs</a><br></dd>"
dat += "<dd><A href='?src=\ref[src];clearr=1'>&#09;[++i]. Clear Request Console Logs</a><br></dd>"
dat += "<dd><A href='?src=\ref[src];pass=1'>&#09;[++i]. Set Custom Key</a><br></dd>"
dat += "<dd><A href='?src=\ref[src];msg=1'>&#09;[++i]. Send Admin Message</a><br></dd>"
else
for(var/n = ++i; n <= optioncount; n++)
dat += "<dd><font color='blue'>&#09;[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>&larr; 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>&larr; 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'>&#09;<font color='green'>\[Authenticated\]</font></a>&#09;/"
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'>&#09;<font color='red'>\[Unauthenticated\]</font></a>&#09;/"
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)
//&#09; = TAB
var/i = 0
dat += "<dd><A href='?src=[REF(src)];find=1'>&#09;[++i]. Link To A Server</a></dd>"
if(auth)
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
dat += "<dd><A>&#09;ERROR: Server not found!</A><br></dd>"
else
dat += "<dd><A href='?src=[REF(src)];view=1'>&#09;[++i]. View Message Logs </a><br></dd>"
dat += "<dd><A href='?src=[REF(src)];viewr=1'>&#09;[++i]. View Request Console Logs </a></br></dd>"
dat += "<dd><A href='?src=[REF(src)];clear=1'>&#09;[++i]. Clear Message Logs</a><br></dd>"
dat += "<dd><A href='?src=[REF(src)];clearr=1'>&#09;[++i]. Clear Request Console Logs</a><br></dd>"
dat += "<dd><A href='?src=[REF(src)];pass=1'>&#09;[++i]. Set Custom Key</a><br></dd>"
dat += "<dd><A href='?src=[REF(src)];msg=1'>&#09;[++i]. Send Admin Message</a><br></dd>"
else
for(var/n = ++i; n <= optioncount; n++)
dat += "<dd><font color='blue'>&#09;[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>&larr; 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>&larr; 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
+7 -7
View File
@@ -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