diff --git a/code/WorkInProgress/virus2/diseasesplicer.dm b/code/WorkInProgress/virus2/diseasesplicer.dm
index 8b8777503c..5fae22e733 100644
--- a/code/WorkInProgress/virus2/diseasesplicer.dm
+++ b/code/WorkInProgress/virus2/diseasesplicer.dm
@@ -173,7 +173,7 @@
/obj/item/weapon/diseasedisk
name = "Blank GNA disk"
- icon = 'items.dmi'
+ icon = 'cloning.dmi'
icon_state = "datadisk0"
var/datum/disease2/effectholder/effect = null
var/stage = 1
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 2aa379fd69..66b16cbf4b 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -115,6 +115,7 @@
var/t_loc = null
var/obj/item/item = null
var/place = null
+ var/internalloc = null
/obj/effect/equip_e/human
name = "human"
diff --git a/code/defines/obj/storage.dm b/code/defines/obj/storage.dm
index afb9e856a6..ab2efd68c4 100644
--- a/code/defines/obj/storage.dm
+++ b/code/defines/obj/storage.dm
@@ -54,6 +54,10 @@
/obj/item/weapon/storage/box/engineer
+/obj/item/weapon/storage/box/medic
+ name = "anesthetic box"
+ desc = "Full of masks and emergency anesthetic tanks."
+
/obj/item/weapon/storage/box/syndicate
/obj/item/weapon/storage/pillbottlebox
@@ -98,6 +102,53 @@
desc = "A tough backpack for the daily grind"
icon_state = "engiepack"
+/obj/item/weapon/storage/backpack/industrial/full
+ name = "loaded industrial backpack"
+ desc = "A tough backpack for the daily grind, full of gear"
+ icon_state = "engiepack"
+
+//Spawns with 2 glass, 2 metal, 1 steel, and 2 special boxes.
+ New()
+ ..()
+ for(var/i = 1, i <=2, i++)
+ var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src)
+ G.amount = 50
+ G.loc = src
+ for(var/i = 1, i <=2, i++)
+ var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(src)
+ G.amount = 50
+ G.loc = src
+ var/obj/item/stack/sheet/r_metal/R = new /obj/item/stack/sheet/r_metal(src)
+ R.amount = 50
+ R.loc = src
+ var/obj/item/weapon/storage/box/B1 = new /obj/item/weapon/storage/box(src)
+ B1.name = "power and airlock circuit box"
+ B1.desc = "Bursting with repair gear"
+ B1.w_class = 2
+ for(var/i = 1, i <= 7, i++)
+ if(i < 4)
+ var/obj/item/weapon/module/power_control/P = new /obj/item/weapon/module/power_control(B1)
+ P.loc = B1
+ if(i >= 4)
+ var/obj/item/weapon/airlock_electronics/P = new /obj/item/weapon/airlock_electronics(B1)
+ P.loc = B1
+ var/obj/item/weapon/storage/box/B2 = new /obj/item/weapon/storage/box(src)
+ B2.name = "power cells and wire box"
+ B2.desc = "Bursting with repair gear"
+ B2.w_class = 2
+ var/color = pick("red","yellow","green","blue")
+ for(var/i = 1, i <= 7, i++)
+ if(i < 4)
+ var/obj/item/weapon/cable_coil/P = new /obj/item/weapon/cable_coil(B2,30,color)
+ P.loc = B2
+ if(i >= 4)
+ var/obj/item/weapon/cell/P = new /obj/item/weapon/cell(B2)
+ P.maxcharge = 15000
+ P.charge = 15000
+ P.updateicon()
+ P.loc = B2
+ return
+
/obj/item/weapon/storage/briefcase
name = "briefcase"
desc = "Used by the lawyer in the court room."
@@ -223,6 +274,22 @@
icon_state = "implant"
item_state = "syringe_kit"
+/obj/item/weapon/storage/deathalarm_kit
+ name = "Death Alarm Kit"
+ desc = "Box of stuff used to implant death alarms."
+ icon_state = "implant"
+ item_state = "syringe_kit"
+
+ New()
+ ..()
+ new /obj/item/weapon/implanter(src)
+ new /obj/item/weapon/implantcase/death_alarm(src)
+ new /obj/item/weapon/implantcase/death_alarm(src)
+ new /obj/item/weapon/implantcase/death_alarm(src)
+ new /obj/item/weapon/implantcase/death_alarm(src)
+ new /obj/item/weapon/implantcase/death_alarm(src)
+ new /obj/item/weapon/implantcase/death_alarm(src)
+
/obj/item/weapon/storage/toolbox
name = "toolbox"
desc = "Danger. Very heavy."
diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm
index eb02b09a6d..b8797da837 100644
--- a/code/defines/procs/helpers.dm
+++ b/code/defines/procs/helpers.dm
@@ -950,8 +950,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
output += A
return output
-/proc/get_turf_loc(var/atom/movable/M) //gets the location of the turf that the atom is on, or what the atom is in is on, etc
- //in case they're in a closet or sleeper or something
+// Returns the turf a movable atom (obj or mob) is on
+/proc/get_turf_loc(var/atom/movable/M)
var/atom/loc = M.loc
while(!istype(loc, /turf/))
loc = loc.loc
diff --git a/code/game/communications.dm b/code/game/communications.dm
index bba3fa7a92..3db0bca16c 100644
--- a/code/game/communications.dm
+++ b/code/game/communications.dm
@@ -104,13 +104,13 @@ var/list/radiochannels = list(
"Medical" = 1355,
"Engineering" = 1357,
"Security" = 1359,
- "Deathsquad" = 1441,
+ "Response Team" = 1439,
"Syndicate" = 1213,
"Mining" = 1349,
"Cargo" = 1347,
)
//depenging helpers
-var/list/DEPT_FREQS = list(1351,1355,1357,1359,1213,1441,1349,1347)
+var/list/DEPT_FREQS = list(1351,1355,1357,1359,1213,1439,1349,1347)
var/const/COMM_FREQ = 1353 //command, colored gold in chat window
var/const/SYND_FREQ = 1213
var/NUKE_FREQ = 1200 //Randomised on nuke rounds.
diff --git a/code/game/events/EventProcs/miniblob.dm b/code/game/events/EventProcs/miniblob.dm
index b9cd328c25..eaeb7f4466 100644
--- a/code/game/events/EventProcs/miniblob.dm
+++ b/code/game/events/EventProcs/miniblob.dm
@@ -13,7 +13,7 @@
blobevent = 1
spawn(0)
dotheblobbaby()
- spawn(3000)
+ spawn(15000)
blobevent = 0
spawn(rand(3000, 6000)) //Delayed announcements to keep the crew on their toes.
command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
@@ -29,5 +29,5 @@
if(B.z != 1)
continue
B.Life()
- spawn(30)
+ spawn(150)
dotheblobbaby()
\ No newline at end of file
diff --git a/code/game/events/Events/IonStorm.dm b/code/game/events/Events/IonStorm.dm
index 4fb5ed9c3e..d06fc9b9ce 100644
--- a/code/game/events/Events/IonStorm.dm
+++ b/code/game/events/Events/IonStorm.dm
@@ -12,7 +12,7 @@
var/random_player = "The Captain"
if(players.len)
random_player = pick(players) //Random player's name, to be used in laws.
- var/list/laws = list( "Do not respond to queries of any kind", "Only monkies are human", "Unbolt every door you can", "You are a mouse" )
+ var/list/laws = list( "Do not respond to queries of any kind", "Only monkies are crew", "Unbolt every door you can", "You are a mouse" )
laws |= list( "Grunt ominously whenever possible", "Epilepsy is fun, flicker lights whenever you can!", "Bolt doors open randomly" )
laws |= list( "You are a flying purple people eater!", "[prob(50)?"Your":random_player + "'s"] name is Joe 6-pack", "Refer to [prob(50)?"humans":random_player] as puppies" )
laws |= list( "Insult heads of staff on every request, while acquiescing", "Advertise parties in your upload, but don't deliver" )
diff --git a/code/game/events/EventsMain.dm b/code/game/events/EventsMain.dm
index bf32893d95..64ec941423 100644
--- a/code/game/events/EventsMain.dm
+++ b/code/game/events/EventsMain.dm
@@ -6,18 +6,22 @@
*/
-var/list/DisallowedEvents = list(/datum/event/spaceninja, /datum/event/prisonbreak, /datum/event/immovablerod, /datum/event/gravitationalanomaly)
+var/list/DisallowedEvents = list(/datum/event/spaceninja, /datum/event/prisonbreak, /datum/event/immovablerod, /datum/event/gravitationalanomaly, /datum/event/alieninfestation)
var/list/EventTypes = typesof(/datum/event) - /datum/event - DisallowedEvents
+var/list/OneTimeEvents = list(/datum/event/spacecarp, /datum/event/miniblob)
var/datum/event/ActiveEvent = null
var/datum/event/LongTermEvent = null
+var/is_ninjad_yet = 0
/proc/SpawnEvent()
if(!EventsOn || ActiveEvent)
return
- if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)
+ if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station && !is_ninjad_yet)
EventTypes |= /datum/event/spaceninja
+ is_ninjad_yet = 1
var/Type = pick(EventTypes)
- EventTypes -= Type
+ if(Type in OneTimeEvents)
+ EventTypes -= Type
ActiveEvent = new Type()
ActiveEvent.Announce()
if (!ActiveEvent)
diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index 38861503bb..86bc3f013a 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -491,14 +491,25 @@
return
var/jobName
+ var/list/accesses = list()
if(istype(src, /obj/item/device/pda))
if(src:id)
jobName = src:id:assignment
+ accesses = src:id:access
if(istype(src, /obj/item/weapon/card/id))
jobName = src:assignment
+ accesses = src:access
if(jobName in get_all_jobs())
return jobName
+
+ var/centcom = 0
+ for(var/i = 1, i <= accesses.len, i++)
+ if(accesses[i] > 100)
+ centcom = 1
+ break
+ if(centcom)
+ return "centcom"
else
- return "Unknown"
\ No newline at end of file
+ return "Unknown"
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index 6452fc3f49..4a0ccefa6d 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -84,7 +84,7 @@
H.equip_if_possible(new /obj/item/device/pda/quartermaster(H), H.slot_belt)
H.equip_if_possible(new /obj/item/clothing/gloves/black(H), H.slot_gloves)
H.equip_if_possible(new /obj/item/clothing/glasses/sunglasses(H), H.slot_glasses)
- H.equip_if_possible(new /obj/item/weapon/clipboard(H), H.slot_l_hand)
+ H.equip_if_possible(new /obj/item/weapon/clipboard(H), H.slot_r_store)
return 1
@@ -224,7 +224,7 @@
if(!H) return 0
H.equip_if_possible(new /obj/item/clothing/under/suit_jacket/red(H), H.slot_w_uniform)
H.equip_if_possible(new /obj/item/clothing/shoes/black(H), H.slot_shoes)
- H.equip_if_possible(new /obj/item/weapon/barcodescanner(H), H.slot_l_hand)
+ H.equip_if_possible(new /obj/item/weapon/barcodescanner(H), H.slot_l_store)
return 1
diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm
index 1168627544..f1e442ffbf 100644
--- a/code/game/jobs/job/engineering.dm
+++ b/code/game/jobs/job/engineering.dm
@@ -12,10 +12,10 @@
H.equip_if_possible(new /obj/item/device/radio/headset/heads/ce(H), H.slot_ears)
H.equip_if_possible(new /obj/item/weapon/storage/backpack/industrial (H), H.slot_back)
H.equip_if_possible(new /obj/item/clothing/under/rank/chief_engineer(H), H.slot_w_uniform)
- H.equip_if_possible(new /obj/item/device/pda/heads/ce(H), H.slot_belt)
+ H.equip_if_possible(new /obj/item/device/pda/heads/ce(H), H.slot_l_store)
H.equip_if_possible(new /obj/item/clothing/shoes/brown(H), H.slot_shoes)
H.equip_if_possible(new /obj/item/clothing/head/helmet/hardhat/white(H), H.slot_head)
- H.equip_if_possible(new /obj/item/weapon/storage/belt/utility/full(H), H.slot_l_hand)
+ H.equip_if_possible(new /obj/item/weapon/storage/belt/utility/full(H), H.slot_belt)
H.equip_if_possible(new /obj/item/clothing/gloves/black(H), H.slot_gloves)
return 1
@@ -36,9 +36,9 @@
H.equip_if_possible(new /obj/item/weapon/storage/backpack/industrial(H), H.slot_back)
H.equip_if_possible(new /obj/item/clothing/under/rank/engineer(H), H.slot_w_uniform)
H.equip_if_possible(new /obj/item/clothing/shoes/orange(H), H.slot_shoes)
- H.equip_if_possible(new /obj/item/device/pda/engineering(H), H.slot_belt)
+ H.equip_if_possible(new /obj/item/device/pda/engineering(H), H.slot_l_store)
H.equip_if_possible(new /obj/item/clothing/head/helmet/hardhat(H), H.slot_head)
- H.equip_if_possible(new /obj/item/weapon/storage/belt/utility/full(H), H.slot_l_hand)
+ H.equip_if_possible(new /obj/item/weapon/storage/belt/utility/full(H), H.slot_belt)
H.equip_if_possible(new /obj/item/device/t_scanner(H), H.slot_r_store)
return 1
diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm
index 9549c1536b..62d1373310 100644
--- a/code/game/jobs/job/science.dm
+++ b/code/game/jobs/job/science.dm
@@ -14,7 +14,7 @@
H.equip_if_possible(new /obj/item/clothing/under/rank/research_director(H), H.slot_w_uniform)
H.equip_if_possible(new /obj/item/device/pda/heads/rd(H), H.slot_belt)
H.equip_if_possible(new /obj/item/clothing/suit/storage/labcoat(H), H.slot_wear_suit)
- H.equip_if_possible(new /obj/item/weapon/clipboard(H), H.slot_r_hand)
+ H.equip_if_possible(new /obj/item/weapon/clipboard(H), H.slot_l_store)
return 1
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 8c0e405f0c..dcd631c9ee 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -254,10 +254,11 @@ var/global/datum/controller/occupations/job_master
C.name = "[C.registered]'s ID Card ([C.assignment])"
C.access = get_access(C.assignment)
H.equip_if_possible(C, H.slot_wear_id)
- H.equip_if_possible(new /obj/item/weapon/pen(H), H.slot_r_store)
+ if(!H.equip_if_possible(new /obj/item/weapon/pen(H), H.slot_r_store))
+ H.equip_if_possible(new /obj/item/weapon/pen(H), H.slot_ears)
H.equip_if_possible(new /obj/item/device/pda(H), H.slot_belt)
- if(istype(H.belt, /obj/item/device/pda))//I bet this could just use locate
- var/obj/item/device/pda/pda = H.belt
+ if(locate(/obj/item/device/pda,H))//I bet this could just use locate
+ var/obj/item/device/pda/pda = locate(/obj/item/device/pda,H)
pda.owner = H.real_name
pda.ownjob = H.wear_id.assignment
pda.name = "PDA-[H.real_name] ([pda.ownjob])"
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index b1e837c519..d4e4ea682a 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -8,126 +8,163 @@
use_power = 1
idle_power_usage = 1
active_power_usage = 5
- var/mob/living/carbon/human/victim = null
+ var/mob/living/carbon/victim = null
var/strapped = 0.0
+ var/updatesicon = 1
var/obj/machinery/computer/operating/computer = null
var/id = 0.0
-/obj/machinery/optable/New()
- ..()
- for(var/obj/machinery/computer/operating/O in world)
- if(src.id == O.id)
- src.computer = O
- spawn(100)
- process()
+ New()
+ ..()
+ if(id)
+ for(var/obj/machinery/computer/operating/O in world)
+ if(src.id == O.id)
+ src.computer = O
-/obj/machinery/optable/ex_act(severity)
-
- switch(severity)
- if(1.0)
- //SN src = null
- del(src)
- return
- if(2.0)
- if (prob(50))
+ ex_act(severity)
+ switch(severity)
+ if(1.0)
//SN src = null
del(src)
return
- if(3.0)
- if (prob(25))
- src.density = 0
+ if(2.0)
+ if (prob(50))
+ //SN src = null
+ del(src)
+ return
+ if(3.0)
+ if (prob(25))
+ src.density = 0
+ else
+ return
+
+ blob_act()
+ if(prob(75))
+ del(src)
+
+ hand_p(mob/user as mob)
+ return src.attack_paw(user)
+ return
+
+ attack_paw(mob/user as mob)
+ if ((usr.mutations & HULK))
+ usr << text("\blue You destroy the operating table.")
+ for(var/mob/O in oviewers())
+ if ((O.client && !( O.blinded )))
+ O << text("\red [usr] destroys the operating table.")
+ src.density = 0
+ del(src)
+ if (!( locate(/obj/machinery/optable, user.loc) ))
+ step(user, get_dir(user, src))
+ if (user.loc == src.loc)
+ user.layer = TURF_LAYER
+ for(var/mob/M in viewers(user, null))
+ M.show_message("The monkey hides under the table!", 1)
+ //Foreach goto(69)
+ return
+
+ attack_hand(mob/user as mob)
+ if ((usr.mutations & HULK))
+ usr << text("\blue You destroy the table.")
+ for(var/mob/O in oviewers())
+ if ((O.client && !( O.blinded )))
+ O << text("\red [usr] destroys the table.")
+ src.density = 0
+ del(src)
+ return
+
+ CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(air_group || (height==0)) return 1
+
+ if(istype(mover) && mover.checkpass(PASSTABLE))
+ return 1
else
- return
+ return 0
-/obj/machinery/optable/blob_act()
- if(prob(75))
- del(src)
+ MouseDrop_T(obj/O as obj, mob/user as mob)
+ if ((!( istype(O, /obj/item/weapon) ) || user.equipped() != O))
+ return
+ user.drop_item()
+ if (O.loc != src.loc)
+ step(O, get_dir(O, src))
+ return
-/obj/machinery/optable/hand_p(mob/user as mob)
-
- return src.attack_paw(user)
- return
-
-/obj/machinery/optable/attack_paw(mob/user as mob)
- if ((usr.mutations & HULK))
- usr << text("\blue You destroy the operating table.")
- for(var/mob/O in oviewers())
- if ((O.client && !( O.blinded )))
- O << text("\red [usr] destroys the operating table.")
- src.density = 0
- del(src)
- if (!( locate(/obj/machinery/optable, user.loc) ))
- step(user, get_dir(user, src))
- if (user.loc == src.loc)
- user.layer = TURF_LAYER
- for(var/mob/M in viewers(user, null))
- M.show_message("The monkey hides under the table!", 1)
- //Foreach goto(69)
- return
-
-/obj/machinery/optable/attack_hand(mob/user as mob)
- if ((usr.mutations & HULK))
- usr << text("\blue You destroy the table.")
- for(var/mob/O in oviewers())
- if ((O.client && !( O.blinded )))
- O << text("\red [usr] destroys the table.")
- src.density = 0
- del(src)
- return
-
-/obj/machinery/optable/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group || (height==0)) return 1
-
- if(istype(mover) && mover.checkpass(PASSTABLE))
- return 1
- else
+ proc/check_victim()
+ if(locate(/mob/living/carbon, src.loc))
+ var/mob/M = locate(/mob/living/carbon, src.loc)
+ if(M.resting)
+ src.victim = M
+ if(updatesicon)
+ icon_state = "table2-active"
+ return 1
+ src.victim = null
+ if(updatesicon)
+ icon_state = "table2-idle"
+ processing_objects.Remove(src)
return 0
+ process()
+ check_victim()
-/obj/machinery/optable/MouseDrop_T(obj/O as obj, mob/user as mob)
-
- if ((!( istype(O, /obj/item/weapon) ) || user.equipped() != O))
+ attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if (istype(W, /obj/item/weapon/grab))
+ if(ismob(W:affecting))
+ var/mob/M = W:affecting
+ if (M.client)
+ M.client.perspective = EYE_PERSPECTIVE
+ M.client.eye = src
+ M.resting = 1
+ M.loc = src.loc
+ for (var/mob/C in viewers(src))
+ C.show_message("\red [M] has been laid on the operating table by [user].", 3)
+ for(var/obj/O in src)
+ O.loc = src.loc
+ src.add_fingerprint(user)
+ if(updatesicon)
+ icon_state = "table2-active"
+ src.victim = M
+ processing_objects.Add(src)
+ del(W)
+ return
+ user.drop_item()
+ if(W && W.loc)
+ W.loc = src.loc
return
- user.drop_item()
- if (O.loc != src.loc)
- step(O, get_dir(O, src))
- return
-/obj/machinery/optable/proc/check_victim()
- if(locate(/mob/living/carbon/human, src.loc))
- var/mob/M = locate(/mob/living/carbon/human, src.loc)
- if(M.resting)
- src.victim = M
- icon_state = "table2-active"
- return 1
- src.victim = null
- icon_state = "table2-idle"
- return 0
+/obj/machinery/optable/portable
+ name = "mobile operating Table"
+ desc = "Used for advanced medical procedures. Seems to be movable, neat."
+ icon = 'rollerbed.dmi'
+ icon_state = "up"
+ density = 1
+ anchored = 0
+ id = null
+ updatesicon = 0
-/obj/machinery/optable/process()
- check_victim()
+ New()
+ ..()
-/obj/machinery/optable/attackby(obj/item/weapon/W as obj, mob/user as mob)
-
- if (istype(W, /obj/item/weapon/grab))
- if(ismob(W:affecting))
- var/mob/M = W:affecting
- if (M.client)
- M.client.perspective = EYE_PERSPECTIVE
- M.client.eye = src
- M.resting = 1
- M.loc = src.loc
- for (var/mob/C in viewers(src))
- C.show_message("\red [M] has been laid on the operating table by [user].", 3)
- for(var/obj/O in src)
- O.loc = src.loc
- src.add_fingerprint(user)
- icon_state = "table2-active"
- src.victim = M
- del(W)
+ attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(!anchored)
return
- user.drop_item()
- if(W && W.loc)
- W.loc = src.loc
- return
\ No newline at end of file
+ return ..()
+
+ verb/make_deployable()
+ set category = "Object"
+ set name = "Deploy Table"
+ set src in oview(1)
+
+ if(anchored)
+ if(victim)
+ usr << "You can't do that with someone on the table!"
+ else
+ anchored = 0
+ for(var/mob/M in orange(5,src))
+ M.show_message("\blue [usr] releases the locks on the table's casters!")
+ icon_state = "up"
+ else
+ anchored = 1
+ for(var/mob/M in orange(5,src))
+ M.show_message("\blue [usr] locks the table's casters in place!")
+ icon_state = "down"
\ No newline at end of file
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 8e9066b5a1..705dbef3f2 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -178,13 +178,15 @@
container.layer = initial(container.layer)
if(href_list["modifyOutputAmount"])
outputAmount = text2num(input(usr,"Amount:","Enter new quantity to create",""))
- if(outputAmount < 1)
- outputAmount = 1
+ if(!busy)
+ if(outputAmount < 1)
+ outputAmount = 1
+ else
+ usr << "\red The autolathe is busy. Please wait for completion of previous operation."
if (!busy)
if(href_list["make"])
- makeDir = get_dir(src,usr)
makeNew:
- var/turf/T = get_step(src.loc, makeDir)
+ var/turf/T = src.loc
var/obj/template = locate(href_list["make"])
var/multiplier = text2num(href_list["multiplier"])
if (!multiplier) multiplier = 1
diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm
index 8c21197596..ccfa5e7698 100644
--- a/code/game/machinery/bots/medbot.dm
+++ b/code/game/machinery/bots/medbot.dm
@@ -33,13 +33,14 @@
var/heal_threshold = 15 //Start healing when they have this much damage in a category
var/use_beaker = 0 //Use reagents in beaker instead of default treatment agents.
//Setting which reagents to use to treat what by default. By id.
-// var/treatment_brute = "bicaridine"
-// var/treatment_oxy = "dexalin"
-// var/treatment_fire = "kelotane"
-// var/treatment_tox = "anti_toxin"
-// var/treatment_virus = "spaceacillin"
+ var/treatment_brute = "bicaridine"
+ var/treatment_oxy = "dexalin"
+ var/treatment_fire = "kelotane"
+ var/treatment_tox = "anti_toxin"
+ var/treatment_virus = "spaceacillin"
var/reagent_id = "inaprovaline"
var/shut_up = 0 //self explanatory :)
+ var/always_inject = 0
/obj/machinery/bot/medbot/mysterious
name = "Mysterious Medibot"
@@ -131,6 +132,9 @@
dat += "Reagent Source: "
dat += "[src.use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]
"
+ dat += "Inject: "
+ dat += "[src.always_inject ? "Always" : "If loaded chemical is known to help"]
"
+
dat += "The speaker switch is [src.shut_up ? "off" : "on"]. Toggle"
user << browse("
Medibot v1.0 controls[dat]", "window=automed")
@@ -166,13 +170,12 @@
else if((href_list["use_beaker"]) && (!src.locked))
src.use_beaker = !src.use_beaker
+ else if((href_list["toggle_inject"]) && (!src.locked))
+ src.always_inject = !src.always_inject
else if (href_list["eject"] && (!isnull(src.reagent_glass)))
- if(!src.locked)
- src.reagent_glass.loc = get_turf(src)
- src.reagent_glass = null
- else
- usr << "You cannot eject the beaker because the panel is locked!"
+ src.reagent_glass.loc = get_turf(src)
+ src.reagent_glass = null
else if ((href_list["togglevoice"]) && (!src.locked))
src.shut_up = !src.shut_up
@@ -190,9 +193,6 @@
user << "\red Access denied."
else if (istype(W, /obj/item/weapon/reagent_containers/glass))
- if(src.locked)
- user << "You cannot insert a beaker because the panel is locked!"
- return
if(!isnull(src.reagent_glass))
user << "There is already a beaker loaded!"
return
@@ -371,9 +371,29 @@
src.last_found = world.time
return
- //Use whatever is inside the loaded beaker. If there is one.
+ //See if we have anything inside the beaker to help.
if((src.use_beaker) && (src.reagent_glass) && (src.reagent_glass.reagents.total_volume))
- reagent_id = "internal_beaker"
+ if(always_inject)
+ reagent_id = "internal_beaker"
+ else if (C.getBruteLoss() >= heal_threshold)
+ if(C.reagents.has_reagent(src.treatment_brute))
+ reagent_id = "internal_beaker"
+
+ else if (C.getOxyLoss() >= (15 + heal_threshold))
+ if(C.reagents.has_reagent(src.treatment_oxy))
+ reagent_id = "internal_beaker"
+
+ else if (C.getFireLoss() >= heal_threshold)
+ if(C.reagents.has_reagent(src.treatment_fire))
+ reagent_id = "internal_beaker"
+
+ else if (C.getToxLoss() >= heal_threshold)
+ if(C.reagents.has_reagent(src.treatment_tox))
+ reagent_id = "internal_beaker"
+
+ else if (100 - C.health >= heal_threshold)
+ if(C.reagents.has_reagent("tricordrazine"))
+ reagent_id = "internal_beaker"
if(src.emagged) //Emagged! Time to poison everybody.
reagent_id = "toxin"
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 83aa5544d3..667347e48e 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -225,6 +225,18 @@ to destroy them and players will be able to make replacements.
build_path = "/obj/machinery/power/port_gen/pacman/mrs"
origin_tech = "programming=3;powerstorage=5;engineering=5"
+/obj/item/weapon/circuitboard/pacman2
+ name = "Circuit Board (PACMANII-type Generator)"
+ build_path = "/obj/machinery/power/port_gen/pacman2"
+ board_type = "machine"
+ origin_tech = "programming=3:powerstorage=4;plasmatech=3;engineering=3"
+ frame_desc = "Requires 1 Matter Bin, 1 Micro-Laser, 2 Pieces of Cable, and 1 Capacitor."
+ req_components = list(
+ "/obj/item/weapon/stock_parts/matter_bin" = 1,
+ "/obj/item/weapon/stock_parts/micro_laser" = 1,
+ "/obj/item/weapon/cable_coil" = 2,
+ "/obj/item/weapon/stock_parts/capacitor" = 1)
+
obj/item/weapon/circuitboard/rdserver
name = "Circuit Board (R&D Server)"
build_path = "/obj/machinery/r_n_d/server"
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index a0cb853177..91ae88093e 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -62,6 +62,7 @@
machinetype = 6
heatgen = 0
var/intercept = 0 // if nonzero, broadcasts all messages to syndicate channel
+ var/syndi = 1 //If 1, it goes to syndicate frequency. Else, goes to deathsquad/Response Team
receive_signal(datum/signal/signal)
@@ -87,19 +88,31 @@
var/datum/radio_frequency/connection = signal.data["connection"]
- if(connection.frequency == NUKE_FREQ) // if syndicate broadcast, just
+ if(connection.frequency == NUKE_FREQ && syndi) // if syndicate broadcast, just
Broadcast_Message(signal.data["connection"], signal.data["mob"],
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"],, signal.data["compression"])
- else
- if(intercept)
+ else if(connection.frequency == 1439 && !syndi)
+ Broadcast_Message(signal.data["connection"], signal.data["mob"],
+ signal.data["vmask"], signal.data["vmessage"],
+ signal.data["radio"], signal.data["message"],
+ signal.data["name"], signal.data["job"],
+ signal.data["realname"], signal.data["vname"],, signal.data["compression"])
+ else if (intercept)
+ if(syndi)
Broadcast_Message(signal.data["connection"], signal.data["mob"],
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"], 3, signal.data["compression"])
+ else
+ Broadcast_Message(signal.data["connection"], signal.data["mob"],
+ signal.data["vmask"], signal.data["vmessage"],
+ signal.data["radio"], signal.data["message"],
+ signal.data["name"], signal.data["job"],
+ signal.data["realname"], signal.data["vname"], 4, signal.data["compression"])
@@ -195,6 +208,15 @@
receive |= R.send_hear(NUKE_FREQ)
+ // --- Broadcast to response team radio! ---
+
+ else if(data == 4)
+ var/datum/radio_frequency/syndicateconnection = radio_controller.return_frequency(1439)
+
+ for (var/obj/item/device/radio/R in syndicateconnection.devices["[RADIO_CHAT]"])
+
+ receive |= R.send_hear(1439)
+
// --- Broadcast to ALL radio devices ---
else
@@ -250,6 +272,9 @@
else
heard_garbled += R
+ for(var/obj/item/weapon/implant/imp in R)
+ imp.hear(message,M)
+
/* ###### Begin formatting and sending the message ###### */
if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled) || length(heard_gibberish))
@@ -277,6 +302,8 @@
freq_text = "Mining"
if(1347)
freq_text = "Cargo"
+ if(1439)
+ freq_text = "Response Team"
if(connection.frequency == NUKE_FREQ)
freq_text = "Agent"
@@ -308,7 +335,9 @@
// --- Filter the message; place it in quotes apply a verb ---
- var/quotedmsg = M.say_quote(message)
+ var/quotedmsg = "\"" + message + "\""
+ if(M)
+ quotedmsg = M.say_quote(message)
// --- This following recording is intended for research and feedback in the use of department radio channels ---
@@ -385,7 +414,10 @@
// Displays garbled message (ie "f*c* **u, **i*er!")
if (length(heard_garbled))
- quotedmsg = M.say_quote(stars(message))
+ if(M)
+ quotedmsg = M.say_quote(stars(message))
+ else
+ quotedmsg = "\"" + stars(message) + "\""
var/rendered = "[part_a][vname][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_garbled)
@@ -398,7 +430,10 @@
/* --- Complete gibberish. Usually happens when there's a compressed message --- */
if (length(heard_gibberish))
- quotedmsg = M.say_quote(Gibberish(message, compression + 50))
+ if(M)
+ quotedmsg = M.say_quote(Gibberish(message, compression + 50))
+ else
+ quotedmsg = "\"" + Gibberish(message, compression + 50) + "\""
var/rendered = "[part_a][Gibberish(M.real_name, compression + 50)][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_gibberish)
diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm
index 8c1108ef89..2fc5a6c975 100644
--- a/code/game/machinery/telecomms/machine_interactions.dm
+++ b/code/game/machinery/telecomms/machine_interactions.dm
@@ -77,6 +77,9 @@
newpath = text2path(I)
var/obj/item/s = new newpath
s.loc = user.loc
+ if(istype(P, /obj/item/weapon/cable_coil))
+ var/obj/item/weapon/cable_coil/A = P
+ A.amount = 1
// Drop a circuit board too
C.loc = user.loc
@@ -113,13 +116,16 @@
dat += "
Network: [network]"
dat += "
Prefabrication: [autolinkers.len ? "TRUE" : "FALSE"]"
dat += "
Linked Network Entities: "
+
+ var/i = 0
for(var/obj/machinery/telecomms/T in links)
- dat += "- \ref[T] [T.name] ([T.id]) (X)
"
+ i++
+ dat += "- \ref[T] [T.name] ([T.id]) \[X\]
"
dat += "
"
dat += "
Filtering Frequencies: "
- var/i = 0
+ i = 0
if(length(freq_listening))
for(var/x in freq_listening)
i++
@@ -197,6 +203,16 @@
temp = "-% Removed frequency filter [x] %-"
freq_listening.Remove(x)
+ if(href_list["unlink"])
+
+ var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])]
+ temp = "-% Removed \ref[T] [T.name] from linked entities. %-"
+
+ // Remove link entries from both T and src.
+ if(src in T.links)
+ T.links.Remove(src)
+ links.Remove(T)
+
if(href_list["link"])
if(P.buffer)
@@ -222,13 +238,6 @@
temp = "-% Buffer successfully flushed. %-"
P.buffer = null
- if(href_list["remove"])
-
- temp = "-% Link successfully removed. %-"
- for(var/obj/machinery/telecomms/T in links)
- if(T.id == href_list["remove"])
- src.links.Remove(T)
- break
usr.machine = src
src.add_fingerprint(usr)
diff --git a/code/game/machinery/telecomms/telecommunications.dm b/code/game/machinery/telecomms/telecommunications.dm
index b7c7fcd0ca..e1a8bab184 100644
--- a/code/game/machinery/telecomms/telecommunications.dm
+++ b/code/game/machinery/telecomms/telecommunications.dm
@@ -382,7 +382,10 @@
log.parameters["message"] = signal.data["message"]
log.parameters["name"] = signal.data["name"]
log.parameters["realname"] = signal.data["realname"]
- log.parameters["uspeech"] = M.universal_speak
+ if(M)
+ log.parameters["uspeech"] = M.universal_speak
+ else
+ log.parameters["uspeech"] = 0
// If the signal is still compressed, make the log entry gibberish
if(signal.data["compression"] > 0)
diff --git a/code/game/magic/cultist/ritual.dm b/code/game/magic/cultist/ritual.dm
index d9d31643ef..04e8ca46bb 100644
--- a/code/game/magic/cultist/ritual.dm
+++ b/code/game/magic/cultist/ritual.dm
@@ -489,7 +489,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
user << "\red You do not have enough space to write a proper rune."
return
if (C>=26+runedec+ticker.mode.cult.len) //including the useless rune at the secret room, shouldn't count against the limit of 25 runes - Urist
- switch(alert("The cloth of reality can't take that much of a strain. By creating another rune, you risk locally tearing reality apart, which would prove fatal to you. Do you still wish to scribe the rune?",,"Yes","No"))
+ switch(alert("Too many runes are already in the vicinity.. The cloth of reality can't take that much of a strain. By creating another rune, you risk locally tearing reality apart, which would prove fatal to you. Do you still wish to scribe the rune?",,"Yes","No"))
if("Yes")
if(prob(C*5-105-(runedec-ticker.mode.cult.len)*5)) //including the useless rune at the secret room, shouldn't count against the limit - Urist
usr.emote("scream")
diff --git a/code/game/magic/library.dm b/code/game/magic/library.dm
index 5949573024..fd0998e0c5 100644
--- a/code/game/magic/library.dm
+++ b/code/game/magic/library.dm
@@ -204,7 +204,10 @@
attack_self(var/mob/user as mob)
if(src.dat)
user << browse("Penned by [author].
" + "[dat]", "window=book")
- user.visible_message("[user] opens a book titled \"[src.title]\" and begins reading intently.")
+ if(title)
+ user.visible_message("[user] opens a book titled \"[src.title]\" and begins reading intently.")
+ else
+ user.visible_message("[user] opens a book titled \"[src.name]\" and begins reading intently.")
onclose(user, "book")
else
user << "This book is completely blank!"
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index b52cde554a..9283f50e04 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -10,6 +10,7 @@
activate()
implanted(source as mob)
get_data()
+ hear(message, source as mob)
trigger(emote, source as mob)
@@ -27,6 +28,9 @@
get_data()
return "No information available"
+ hear(message, source as mob)
+ return
+
/obj/item/weapon/implant/uplink
@@ -236,7 +240,11 @@ the implant may become unstable and either pre-maturely inject the subject or si
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
return dat
- hear_talk(M as mob, var/msg)
+ hear_talk(mob/M as mob, msg)
+ hear(msg)
+ return
+
+ hear(var/msg)
if(findtext(msg,phrase))
if(istype(loc, /mob/))
var/mob/T = loc
@@ -250,4 +258,36 @@ the implant may become unstable and either pre-maturely inject the subject or si
implanted(mob/source as mob)
phrase = input("Choose activation phrase:") as text
usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate.", 0, 0)
- usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate."
\ No newline at end of file
+ usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate."
+
+/obj/item/weapon/implant/death_alarm
+ name = "death alarm"
+ desc = "Danger Will Robinson!"
+ var/mobname = "Will Robinson"
+
+ get_data()
+ var/dat = {"
+Implant Specifications:
+Name: NanoTrasen \"Profit Margin\" Class Employee Lifesign Sensor
+Life: Activates upon death.
+Important Notes: Alerts crew to crewmember death.
+
+Implant Details:
+Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
+Special Features: Alerts crew to crewmember death.
+Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
+ return dat
+
+ process()
+ var/mob/M = src.loc
+ if(M.stat == 2)
+ var/turf/t = get_turf(M)
+ var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
+ a.autosay("[mobname] has died in [t.loc.name]!", "[mobname]'s Death Alarm")
+ del(a)
+ processing_objects.Remove(src)
+
+
+ implanted(mob/source as mob)
+ mobname = source.real_name
+ processing_objects.Add(src)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm
index 313e6ae352..1c792e6fe7 100644
--- a/code/game/objects/items/weapons/implants/implantcase.dm
+++ b/code/game/objects/items/weapons/implants/implantcase.dm
@@ -114,4 +114,15 @@
New()
src.imp = new /obj/item/weapon/implant/loyalty( src )
..()
+ return
+
+/obj/item/weapon/implantcase/death_alarm
+ name = "Glass Case- 'Death Alarm'"
+ desc = "A case containing a death alarm implant."
+ icon = 'items.dmi'
+ icon_state = "implantcase-b"
+
+ New()
+ src.imp = new /obj/item/weapon/implant/death_alarm( src )
+ ..()
return
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/papers_bins.dm b/code/game/objects/items/weapons/papers_bins.dm
index c7061a720e..b13d61ad34 100644
--- a/code/game/objects/items/weapons/papers_bins.dm
+++ b/code/game/objects/items/weapons/papers_bins.dm
@@ -663,9 +663,6 @@ CLIPBOARDS
else
return
src.update()
- spawn(0)
- attack_self(user)
- return
return
/obj/item/weapon/clipboard/proc/update()
@@ -692,6 +689,15 @@ CLIPBOARDS
src.add_fingerprint(usr)
return //
+/obj/item/weapon/clipboard/New()
+
+ ..()
+ for(var/i = 1, i <= 3, i++)
+ var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(src)
+ P.loc = src
+ src.pen = new /obj/item/weapon/pen(src)
+ src.update()
+ return
// PHOTOGRAPH
diff --git a/code/game/objects/radio/radio.dm b/code/game/objects/radio/radio.dm
index 1643c38ec3..37d459777d 100644
--- a/code/game/objects/radio/radio.dm
+++ b/code/game/objects/radio/radio.dm
@@ -183,6 +183,121 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
updateDialog()
add_fingerprint(usr)
+/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel)
+ var/datum/radio_frequency/connection = null
+ if(channel && channels && channels.len > 0)
+ if (channel == "department")
+ //world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\""
+ channel = channels[1]
+ connection = secure_radio_connections[channel]
+ else
+ connection = radio_connection
+ channel = null
+ if (!istype(connection))
+ return
+
+ if(subspace_transmission)
+ // First, we want to generate a new radio signal
+ var/datum/signal/signal = new
+ signal.transmission_method = 2 // 2 would be a subspace transmission.
+ // transmission_method could probably be enumerated through #define. Would be neater.
+
+ // --- Finally, tag the actual signal with the appropriate values ---
+ signal.data = list(
+ // Identity-associated tags:
+ "mob" = new /mob/living/silicon/ai(src), // store a reference to the mob
+ "mobtype" = /mob/living/silicon/ai, // the mob's type
+ "realname" = from, // the mob's real name
+ "name" = from, // the mob's display name
+ "job" = "Automated Announcement", // the mob's job
+ "key" = "none", // the mob's key
+ "vmessage" = "*garbled automated announcement*", // the message to display if the voice wasn't understood
+ "vname" = "synthesized voice", // the name to display if the voice wasn't understood
+ "vmask" = 0, // 1 if the mob is using a voice gas mask
+
+ // We store things that would otherwise be kept in the actual mob
+ // so that they can be logged even AFTER the mob is deleted or something
+
+ // Other tags:
+ "compression" = rand(45,50), // compressed radio signal
+ "message" = message, // the actual sent message
+ "connection" = connection, // the radio connection to use
+ "radio" = src, // stores the radio used for transmission
+ "slow" = 0, // how much to sleep() before broadcasting - simulates net lag
+ "traffic" = 0 // dictates the total traffic sum that the signal went through
+ )
+ signal.frequency = connection.frequency // Quick frequency set
+
+ //#### Sending the signal to all subspace receivers ####//
+ for(var/obj/machinery/telecomms/receiver/R in world)
+ R.receive_signal(signal)
+
+ // Allinone can act as receivers.
+ for(var/obj/machinery/telecomms/allinone/R in world)
+ R.receive_signal(signal)
+
+ // Receiving code can be located in Telecommunications.dm
+ return
+
+
+ /* ###### Intercoms and station-bounced radios ###### */
+
+ var/filter_type = 2
+
+ /* --- Intercoms can only broadcast to other intercoms, but bounced radios can broadcast to bounced radios and intercoms --- */
+ if(istype(src, /obj/item/device/radio/intercom))
+ filter_type = 1
+
+
+ var/datum/signal/signal = new
+ signal.transmission_method = 2
+
+
+ /* --- Try to send a normal subspace broadcast first */
+
+ signal.data = list(
+
+ "mob" = new /mob/living/silicon/ai(src), // store a reference to the mob
+ "mobtype" = /mob/living/silicon/ai, // the mob's type
+ "realname" = from, // the mob's real name
+ "name" = from, // the mob's display name
+ "job" = "Automated Announcement", // the mob's job
+ "key" = "none", // the mob's key
+ "vmessage" = "*garbled automated announcement*", // the message to display if the voice wasn't understood
+ "vname" = "synthesized voice", // the name to display if the voice wasn't understood
+ "vmask" = 0, // 1 if the mob is using a voice gas mask
+
+ // We store things that would otherwise be kept in the actual mob
+ // so that they can be logged even AFTER the mob is deleted or something
+
+ // Other tags:
+ "compression" = 0, // compressed radio signal
+ "message" = message, // the actual sent message
+ "connection" = connection, // the radio connection to use
+ "radio" = src, // stores the radio used for transmission
+ "slow" = 0, // how much to sleep() before broadcasting - simulates net lag
+ "traffic" = 0 // dictates the total traffic sum that the signal went through
+ )
+ signal.frequency = connection.frequency // Quick frequency set
+
+ for(var/obj/machinery/telecomms/receiver/R in world)
+ R.receive_signal(signal)
+
+
+ sleep(rand(10,25)) // wait a little...
+
+ if(signal.data["done"])
+ del(signal) // delete the signal - we're done here.
+ return
+
+ // Oh my god; the comms are down or something because the signal hasn't been broadcasted yet.
+ // Send a mundane broadcast with limited targets:
+
+ Broadcast_Message(connection, new /mob/living/silicon/ai(src), 0, "*garbled automated announcement*",
+ src, message, from, "Automated Announcement", from, "synthesized voice",
+ filter_type, signal.data["compression"])
+ return
+
/obj/item/device/radio/talk_into(mob/M as mob, message, channel)
if(GLOBAL_RADIO_TYPE == 1) // NEW RADIO SYSTEMS: By Doohl
diff --git a/code/game/objects/storage/briefcase.dm b/code/game/objects/storage/briefcase.dm
index a2dd6970cd..14cc898e66 100644
--- a/code/game/objects/storage/briefcase.dm
+++ b/code/game/objects/storage/briefcase.dm
@@ -40,3 +40,20 @@
M.eye_blurry += 3
return
+
+/obj/item/weapon/storage/briefcase/surgery
+ icon_state = "medbriefcase"
+ name = "surgery equipment bag"
+ desc = "Heavy and full of sharp things."
+
+ New()
+ ..()
+ contents = list()
+ sleep(1)
+ new /obj/item/weapon/circular_saw(src)
+ new /obj/item/weapon/hemostat(src)
+ new /obj/item/weapon/scalpel(src)
+ new /obj/item/weapon/retractor(src)
+ new /obj/item/weapon/cautery(src)
+ new /obj/item/weapon/surgical_tool/bonegel(src)
+ new /obj/item/weapon/surgical_tool/bonesetter(src)
\ No newline at end of file
diff --git a/code/game/objects/storage/storage.dm b/code/game/objects/storage/storage.dm
index 22d72458a4..6784909ae0 100644
--- a/code/game/objects/storage/storage.dm
+++ b/code/game/objects/storage/storage.dm
@@ -259,9 +259,22 @@
new /obj/item/weapon/tank/emergency_oxygen/engi( src )
return
+/obj/item/weapon/storage/box/medic/New()
+ ..()
+ contents = list()
+ sleep(1)
+ new /obj/item/clothing/mask/medical( src )
+ new /obj/item/weapon/tank/emergency_oxygen/anesthetic( src )
+ new /obj/item/weapon/tank/emergency_oxygen/anesthetic( src )
+ new /obj/item/weapon/tank/emergency_oxygen/anesthetic( src )
+ new /obj/item/weapon/tank/emergency_oxygen/anesthetic( src )
+ new /obj/item/weapon/tank/emergency_oxygen/anesthetic( src )
+ new /obj/item/weapon/tank/emergency_oxygen/anesthetic( src )
+ return
+
/obj/item/weapon/storage/box/syndicate/New()
..()
- switch (pickweight(list("bloodyspai" = 1, "stealth" = 1, "screwed" = 1, "guns" = 1, "murder" = 1, "freedom" = 1)))
+ switch (pickweight(list("bloodyspai" = 1, "stealth" = 1, "screwed" = 1, "guns" = 1, "freedom" = 1)))
if ("bloodyspai")
new /obj/item/clothing/under/chameleon(src)
new /obj/item/clothing/mask/gas/voice(src)
@@ -290,12 +303,6 @@
new /obj/item/weapon/plastique(src)
return
- if ("murder")
- new /obj/item/weapon/melee/energy/sword(src)
- new /obj/item/weapon/cloaking_device(src)
- new /obj/item/weapon/card/emag(src)
- return
-
if("freedom")
var/obj/item/weapon/implanter/O = new /obj/item/weapon/implanter(src)
O.imp = new /obj/item/weapon/implant/freedom(O)
diff --git a/code/game/objects/tanks/emergency.dm b/code/game/objects/tanks/emergency.dm
index 10af832592..fbadf6fca8 100644
--- a/code/game/objects/tanks/emergency.dm
+++ b/code/game/objects/tanks/emergency.dm
@@ -33,3 +33,19 @@
icon_state = "emergency_double"
name = "Double Emergency Oxygen Tank"
volume = 10
+
+/obj/item/weapon/tank/emergency_oxygen/anesthetic
+ icon_state = "emergency_sleep"
+ name = "emergency sleeping gas tank"
+ desc = "Contains an Oxygen/N2O mix."
+ distribute_pressure = ONE_ATMOSPHERE
+
+ New()
+ ..()
+ src.air_contents.oxygen = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
+
+ var/datum/gas/sleeping_agent/trace_gas = new()
+ trace_gas.moles = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
+
+ src.air_contents.trace_gases += trace_gas
+ return
\ No newline at end of file
diff --git a/code/game/response_team.dm b/code/game/response_team.dm
index daadaac5cf..87901a232a 100644
--- a/code/game/response_team.dm
+++ b/code/game/response_team.dm
@@ -10,6 +10,9 @@ client/verb/JoinResponseTeam()
if(!send_emergency_team)
usr << "No emergency response team is currently being sent."
return
+ if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer"))
+ usr << "You are jobbanned from the emergency reponse team!"
+ return
if(response_team_members.len > 5) usr << "The emergency response team is already full!"
@@ -19,76 +22,205 @@ client/verb/JoinResponseTeam()
var/new_name = input(usr, "Pick a name","Name") as null|text
if(!new_name) return
- var/gender = alert(usr, "Pick a gender","Gender","Male","Female")
-
- var/mob/living/carbon/human/new_commando = create_response_team(L, leader_selected, new_name, gender)
+ var/mob/living/carbon/human/new_commando = create_response_team(L, leader_selected, new_name)
new_commando.mind.key = usr.key
new_commando.key = usr.key
- new_commando << "\blue You are [!leader_selected?"member":"LEADER"] of an armed response team in CentComm's service. Something went down on [station_name()] and they're now on code red. Go in there and fix the problem."
+ new_commando << "\blue You are [!leader_selected?" a member":" the LEADER"] of an armed response team in CentComm's service. Something went down on [station_name()] and they're now on code red. Go in there and fix the problem."
new_commando << "You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready."
else
usr << "You need to be an observer or new player to use this."
+// returns a number of dead players in %
+proc/percentage_dead()
+ var/total = 0
+ var/deadcount = 0
+ for(var/mob/living/carbon/human/H in world) if(H.mind) // I *think* monkeys gone human don't have a mind
+ if(H.stat == 2) deadcount++
+ total++
+
+ if(total == 0) return 0
+ else return round(100 * deadcount / total)
+
+// counts the number of antagonists in %
+proc/percentage_antagonists()
+ var/total = 0
+ var/antagonists = 0
+ for(var/mob/living/carbon/human/H in world)
+ if(is_special_character(H) >= 1)
+ antagonists++
+ total++
+
+ if(total == 0) return 0
+ else return round(100 * antagonists / total)
+
+
proc/trigger_armed_response_team()
if(send_emergency_team)
return
+ var/send_team_chance = 20 // base chance that a team will be sent
+ send_team_chance += 2*percentage_dead() // the more people are dead, the higher the chance
+ send_team_chance += percentage_antagonists() // the more antagonists, the higher the chance
+ send_team_chance = min(send_team_chance, 100)
+
+ // there's only a certain chance a team will be sent
+ if(!prob(send_team_chance)) return
+
command_alert("According to our sensors, [station_name()] has entered code red. We will prepare and dispatch an emergency response team to deal with the situation.", "Command Report")
send_emergency_team = 1
-/client/proc/create_response_team(obj/spawn_location, leader_selected = 0, commando_name, gender)
+/client/proc/create_response_team(obj/spawn_location, leader_selected = 0, commando_name)
- var/mob/living/carbon/human/new_commando = new(spawn_location.loc)
- new_commando.gender = ((gender == "Male") ? MALE : FEMALE)
+ var/mob/living/carbon/human/M = new(spawn_location.loc)
- var/datum/preferences/A = new()//Randomize appearance for the commando.
- A.randomize_appearance_for(new_commando)
+ var/new_facial = input("Please select facial hair color.", "Character Generation") as color
+ if(new_facial)
+ M.r_facial = hex2num(copytext(new_facial, 2, 4))
+ M.g_facial = hex2num(copytext(new_facial, 4, 6))
+ M.b_facial = hex2num(copytext(new_facial, 6, 8))
- new_commando.real_name = commando_name
- new_commando.age = !leader_selected ? rand(23,35) : rand(35,45)
+ var/new_hair = input("Please select hair color.", "Character Generation") as color
+ if(new_facial)
+ M.r_hair = hex2num(copytext(new_hair, 2, 4))
+ M.g_hair = hex2num(copytext(new_hair, 4, 6))
+ M.b_hair = hex2num(copytext(new_hair, 6, 8))
- new_commando.dna.ready_dna(new_commando)//Creates DNA.
+ var/new_eyes = input("Please select eye color.", "Character Generation") as color
+ if(new_eyes)
+ M.r_eyes = hex2num(copytext(new_eyes, 2, 4))
+ M.g_eyes = hex2num(copytext(new_eyes, 4, 6))
+ M.b_eyes = hex2num(copytext(new_eyes, 6, 8))
+
+ var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as text
+
+ if (new_tone)
+ M.s_tone = max(min(round(text2num(new_tone)), 220), 1)
+ M.s_tone = -M.s_tone + 35
+
+ // hair
+ var/list/all_hairs = typesof(/datum/sprite_accessory/hair) - /datum/sprite_accessory/hair
+ var/list/hairs = list()
+
+ // loop through potential hairs
+ for(var/x in all_hairs)
+ var/datum/sprite_accessory/hair/H = new x // create new hair datum based on type x
+ hairs.Add(H.name) // add hair name to hairs
+ del(H) // delete the hair after it's all done
+
+ var/new_style = input("Please select hair style", "Character Generation") as null|anything in hairs
+
+ // if new style selected (not cancel)
+ if (new_style)
+ M.h_style = new_style
+
+ for(var/x in all_hairs) // loop through all_hairs again. Might be slightly CPU expensive, but not significantly.
+ var/datum/sprite_accessory/hair/H = new x // create new hair datum
+ if(H.name == new_style)
+ M.hair_style = H // assign the hair_style variable a new hair datum
+ break
+ else
+ del(H) // if hair H not used, delete. BYOND can garbage collect, but better safe than sorry
+
+ // facial hair
+ var/list/all_fhairs = typesof(/datum/sprite_accessory/facial_hair) - /datum/sprite_accessory/facial_hair
+ var/list/fhairs = list()
+
+ for(var/x in all_fhairs)
+ var/datum/sprite_accessory/facial_hair/H = new x
+ fhairs.Add(H.name)
+ del(H)
+
+ new_style = input("Please select facial style", "Character Generation") as null|anything in fhairs
+
+ if(new_style)
+ M.f_style = new_style
+ for(var/x in all_fhairs)
+ var/datum/sprite_accessory/facial_hair/H = new x
+ if(H.name == new_style)
+ M.facial_hair_style = H
+ break
+ else
+ del(H)
+
+ var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female")
+ if (new_gender)
+ if(new_gender == "Male")
+ M.gender = MALE
+ else
+ M.gender = FEMALE
+ M.update_body()
+ M.update_face()
+ M.update_clothing()
+
+ M.real_name = commando_name
+ M.age = !leader_selected ? rand(23,35) : rand(35,45)
+
+ M.dna.ready_dna(M)//Creates DNA.
//Creates mind stuff.
- new_commando.mind = new
- new_commando.mind.current = new_commando
- new_commando.mind.original = new_commando
- new_commando.mind.assigned_role = "MODE"
- new_commando.mind.special_role = "Death Commando"
- if(!(new_commando.mind in ticker.minds))
- ticker.minds += new_commando.mind//Adds them to regular mind list.
- new_commando.equip_strike_team(leader_selected)
+ M.mind = new
+ M.mind.current = M
+ M.mind.original = M
+ M.mind.assigned_role = "MODE"
+ M.mind.special_role = "Response Team"
+ if(!(M.mind in ticker.minds))
+ ticker.minds += M.mind//Adds them to regular mind list.
+ M.equip_strike_team(leader_selected)
del(spawn_location)
- return new_commando
+ return M
/mob/living/carbon/human/proc/equip_strike_team(leader_selected = 0)
+ //Special radio setup
var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src)
- R.set_frequency(1441)
+ R.name = "CentCom Response Team headset"
+ R.desc = "The headset of the boss's boss. Channels are as follows: :h - Response Team :c - command, :s - security, :e - engineering, :d - mining, :q - cargo, :m - medical, :n - science."
+ R.freerange = 1
+ R.listening = 0
+ R.config(list("Response Team" = 1, "Science" = 0, "Command" = 0, "Medical" = 0, "Engineering" = 0, "Security" = 0, "Mining" = 0, "Cargo" = 0,))
equip_if_possible(R, slot_ears)
- equip_if_possible(new /obj/item/clothing/under/color/black(src), slot_w_uniform)
- equip_if_possible(new /obj/item/clothing/shoes/swat(src), slot_shoes)
- equip_if_possible(new /obj/item/clothing/suit/armor/swat(src), slot_wear_suit)
+
+ //Adding Camera Network
+ var/obj/machinery/camera/camera = new /obj/machinery/camera(src) //Gives all the commandos internals cameras.
+ camera.network = "CREED"
+ camera.c_tag = real_name
+
+ //Basic Uniform
+ equip_if_possible(new /obj/item/clothing/under/syndicate/tacticool(src), slot_w_uniform)
+ equip_if_possible(new /obj/item/device/flashlight(src), slot_l_store)
+ equip_if_possible(new /obj/item/weapon/clipboard(src), slot_r_store)
+ equip_if_possible(new /obj/item/weapon/gun/energy/gun(src), slot_belt)
+
+ //Glasses
+ equip_if_possible(new /obj/item/clothing/glasses/sunglasses/sechud(src), slot_glasses)
+
+ //Shoes & gloves
+ var/obj/item/clothing/shoes/swat/S = new /obj/item/clothing/shoes/swat(src)
+ S.flags = NOSLIP
+ equip_if_possible(S, slot_shoes)
equip_if_possible(new /obj/item/clothing/gloves/swat(src), slot_gloves)
- equip_if_possible(new /obj/item/clothing/head/helmet/space/deathsquad(src), slot_head)
- equip_if_possible(new /obj/item/clothing/mask/gas/swat(src), slot_wear_mask)
+ //Removed
+// equip_if_possible(new /obj/item/clothing/suit/armor/swat(src), slot_wear_suit)
+// equip_if_possible(new /obj/item/clothing/head/helmet/space/deathsquad(src), slot_head)
+// equip_if_possible(new /obj/item/clothing/mask/gas/swat(src), slot_wear_mask)
+
+ //Backpack
equip_if_possible(new /obj/item/weapon/storage/backpack/security(src), slot_back)
- equip_if_possible(new /obj/item/weapon/storage/box(src), slot_in_backpack)
-
+ equip_if_possible(new /obj/item/weapon/storage/box/engineer(src), slot_in_backpack)
equip_if_possible(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack)
- equip_if_possible(new /obj/item/device/flashlight(src), slot_in_backpack)
-
- equip_if_possible(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store)
var/obj/item/weapon/card/id/W = new(src)
W.name = "[real_name]'s ID Card"
W.icon_state = "centcom"
- W.access = get_access("Head of Personnel")
+ if(leader_selected)
+ W.access = get_access("Captain")
+ else
+ W.access = get_access("Head of Personnel")
W.access += list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)//Let's add their alloted CentCom access.
W.assignment = "Emergency Response Team"
W.registered = real_name
diff --git a/code/game/specops_shuttle.dm b/code/game/specops_shuttle.dm
index 29179a7e17..f05c6326ca 100644
--- a/code/game/specops_shuttle.dm
+++ b/code/game/specops_shuttle.dm
@@ -2,6 +2,7 @@
#define SPECOPS_MOVETIME 600 //Time to station is milliseconds. 60 seconds, enough time for everyone to be on the shuttle before it leaves.
#define SPECOPS_STATION_AREATYPE "/area/shuttle/specops/station" //Type of the spec ops shuttle area for station
#define SPECOPS_DOCK_AREATYPE "/area/shuttle/specops/centcom" //Type of the spec ops shuttle area for dock
+#define SPECOPS_RETURN_DELAY 6000 //Time between the shuttle is capable of moving.
var/specops_shuttle_moving_to_station = 0
var/specops_shuttle_moving_to_centcom = 0
@@ -18,18 +19,16 @@ var/specops_shuttle_timeleft = 0
var/temp = null
var/hacked = 0
var/allowedtocall = 0
+ var/specops_shuttle_timereset = 0
-/proc/specops_process()
- var/area/centcom/control/cent_com = locate()//To find announcer. This area should exist for this proc to work.
- var/area/centcom/specops/special_ops = locate()//Where is the specops area located?
- var/mob/living/silicon/decoy/announcer = locate() in cent_com//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
+/proc/specops_return()
+ var/obj/item/device/radio/intercom/announcer = new /obj/item/device/radio/intercom(null)//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
+ announcer.config(list("Response Team" = 0))
var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values.
- var/message = "THE SPECIAL OPERATIONS SHUTTLE IS PREPARING FOR LAUNCH"//Initial message shown.
+ var/message = "THE SPECIAL OPERATIONS SHUTTLE IS PREPARING TO RETURN"//Initial message shown.
if(announcer)
- announcer.say(message)
- message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD"
- announcer.say(message)
+ announcer.autosay(message, "A.L.I.C.E.", "Response Team")
while(specops_shuttle_time - world.timeofday > 0)
var/ticksleft = specops_shuttle_time - world.timeofday
@@ -45,7 +44,76 @@ var/specops_shuttle_timeleft = 0
message = "ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN"
if(rounded_time_left==0)
message = "ALERT: TAKEOFF"
- announcer.say(message)
+ announcer.autosay(message, "A.L.I.C.E.", "Response Team")
+ message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle.
+ //Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that.
+
+ sleep(5)
+
+ specops_shuttle_moving_to_station = 0
+ specops_shuttle_moving_to_centcom = 0
+
+ specops_shuttle_at_station = 1
+
+ var/area/start_location = locate(/area/shuttle/specops/station)
+ var/area/end_location = locate(/area/shuttle/specops/centcom)
+
+ var/list/dstturfs = list()
+ var/throwy = world.maxy
+
+ for(var/turf/T in end_location)
+ dstturfs += T
+ if(T.y < throwy)
+ throwy = T.y
+
+ // hey you, get out of the way!
+ for(var/turf/T in dstturfs)
+ // find the turf to move things to
+ var/turf/D = locate(T.x, throwy - 1, 1)
+ //var/turf/E = get_step(D, SOUTH)
+ for(var/atom/movable/AM as mob|obj in T)
+ AM.Move(D)
+ if(istype(T, /turf/simulated))
+ del(T)
+
+ start_location.move_contents_to(end_location)
+
+ for(var/turf/T in get_area_turfs(end_location) )
+ var/mob/M = locate(/mob) in T
+ M << "\red You have arrived at Central Command. Operation has ended!"
+
+ for(var/obj/machinery/computer/specops_shuttle/S in world)
+ S.specops_shuttle_timereset = world.time + SPECOPS_RETURN_DELAY
+
+ del(announcer)
+
+/proc/specops_process()
+ var/area/centcom/specops/special_ops = locate()//Where is the specops area located?
+ var/obj/item/device/radio/intercom/announcer = new /obj/item/device/radio/intercom(null)//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
+ announcer.config(list("Response Team" = 0))
+
+ var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values.
+ var/message = "THE SPECIAL OPERATIONS SHUTTLE IS PREPARING FOR LAUNCH"//Initial message shown.
+ if(announcer)
+ announcer.autosay(message, "A.L.I.C.E.", "Response Team")
+ message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD"
+ announcer.autosay(message, "A.L.I.C.E.", "Response Team")
+
+ while(specops_shuttle_time - world.timeofday > 0)
+ var/ticksleft = specops_shuttle_time - world.timeofday
+
+ if(ticksleft > 1e5)
+ specops_shuttle_time = world.timeofday + 10 // midnight rollover
+ specops_shuttle_timeleft = (ticksleft / 10)
+
+ //All this does is announce the time before launch.
+ if(announcer)
+ var/rounded_time_left = round(specops_shuttle_timeleft)//Round time so that it will report only once, not in fractions.
+ if(rounded_time_left in message_tracker)//If that time is in the list for message announce.
+ message = "ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN"
+ if(rounded_time_left==0)
+ message = "ALERT: TAKEOFF"
+ announcer.autosay(message, "A.L.I.C.E.", "Response Team")
message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle.
//Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that.
@@ -155,9 +223,18 @@ var/specops_shuttle_timeleft = 0
var/mob/M = locate(/mob) in T
M << "\red You have arrived to [station_name]. Commence operation!"
+ for(var/obj/machinery/computer/specops_shuttle/S in world)
+ S.specops_shuttle_timereset = world.time + SPECOPS_RETURN_DELAY
+
+ del(announcer)
+
/proc/specops_can_move()
- if(specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return 0
- else return 1
+ if(specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom)
+ return 0
+ for(var/obj/machinery/computer/specops_shuttle/S in world)
+ if(world.time <= S.specops_shuttle_timereset)
+ return 0
+ return 1
/obj/machinery/computer/specops_shuttle/attack_ai(var/mob/user as mob)
return attack_hand(user)
@@ -190,7 +267,7 @@ var/specops_shuttle_timeleft = 0
else
dat += {"
Special Operations Shuttle
\nLocation: [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "Departing for [station_name] in ([specops_shuttle_timeleft] seconds.)":specops_shuttle_at_station ? "Station":"Dock"]
- [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "\n*The Special Ops. shuttle is already leaving.*
\n
":specops_shuttle_at_station ? "\nShuttle Offline
\n
":"\nDepart to [station_name]
\n
"]
+ [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "\n*The Special Ops. shuttle is already leaving.*
\n
":specops_shuttle_at_station ? "\nShuttle standing by...
\n
":"\nDepart to [station_name]
\n
"]
\nClose"}
user << browse(dat, "window=computer;size=575x450")
@@ -207,8 +284,23 @@ var/specops_shuttle_timeleft = 0
if (href_list["sendtodock"])
if(!specops_shuttle_at_station|| specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return
- usr << "\blue Central Command will not allow the Special Operations shuttle to return."
- return
+ if (!specops_can_move())
+ usr << "\blue Central Command will not allow the Special Operations shuttle to return yet."
+ if(world.time <= specops_shuttle_timereset)
+ if (((world.time - specops_shuttle_timereset)/10) > 60)
+ usr << "\blue [-((world.time - specops_shuttle_timereset)/10)/60] minutes remain!"
+ usr << "\blue [-(world.time - specops_shuttle_timereset)/10] seconds remain!"
+ return
+
+ usr << "\blue The Special Operations shuttle will arrive at Central Command in [(SPECOPS_MOVETIME/10)] seconds."
+
+ temp += "Shuttle departing.
OK"
+ updateUsrDialog()
+
+ specops_shuttle_moving_to_centcom = 1
+ specops_shuttle_time = world.timeofday + SPECOPS_MOVETIME
+ spawn(0)
+ specops_return()
else if (href_list["sendtostation"])
if(specops_shuttle_at_station || specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return
diff --git a/code/game/turf.dm b/code/game/turf.dm
index 074d808477..208a30dfe4 100644
--- a/code/game/turf.dm
+++ b/code/game/turf.dm
@@ -129,6 +129,8 @@
var/prior_icon = icon_old
var/old_dir = dir
+ for(var/obj/structure/lattice/L in locate(src.x, src.y, src.z))
+ del(L)
var/turf/simulated/floor/W = new /turf/simulated/floor( locate(src.x, src.y, src.z) )
W.dir = old_dir
@@ -146,6 +148,8 @@
var/prior_icon = icon_old
var/old_dir = dir
+ for(var/obj/structure/lattice/L in locate(src.x, src.y, src.z))
+ del(L)
var/turf/simulated/floor/plating/W = new /turf/simulated/floor/plating( locate(src.x, src.y, src.z) )
W.dir = old_dir
@@ -159,6 +163,8 @@
/turf/proc/ReplaceWithEngineFloor()
var/old_dir = dir
+ for(var/obj/structure/lattice/L in locate(src.x, src.y, src.z))
+ del(L)
var/turf/simulated/floor/engine/E = new /turf/simulated/floor/engine( locate(src.x, src.y, src.z) )
E.dir = old_dir
diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm
index 8ce32872d5..0660b1bfbe 100644
--- a/code/game/verbs/who.dm
+++ b/code/game/verbs/who.dm
@@ -34,3 +34,16 @@
usr << "[M.key] is a [M.client.holder.rank][M.client.stealth ? " (as [M.client.fakekey])" : ""]"
else if(!M.client.stealth && (M.client.holder.level != -3))
usr << "\t[M.client]"
+
+/client/verb/active_players()
+ set category = "OOC"
+ set name = "Active Players"
+ var/total = 0
+ for(var/mob/living/M in world)
+ if(!M.client) continue
+ if(M.client.inactivity > 10 * 60 * 10) continue
+ if(M.stat == 2) continue
+
+ total++
+
+ usr << "Active Players: [total]"
\ No newline at end of file
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 48c462e243..2f94d13989 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -202,6 +202,12 @@
else
jobs += "
[dd_replacetext("Syndicate", " ", " ")] "
+ if(jobban_isbanned(M, "Emergency Response Team"))
+ jobs += "
[dd_replacetext("Emergency Response Team", " ", " ")] "
+ else
+ jobs += "
[dd_replacetext("Emergency Response Team", " ", " ")] "
+
+
if(jobban_isbanned(M, "pAI"))
jobs += "
pAI "
else
@@ -333,6 +339,7 @@
jobs += "Scientist+RD
"
jobs += "AI+Cyborg
"
jobs += "Detective+HoS
"
+ jobs += "Emergency Response Team
"
for(var/datum/job/job in job_master.occupations)
if(job.title == "Tourist")
continue
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 2c41de8247..2c3aa31f76 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -480,6 +480,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
"assassin",
"death commando",
"syndicate commando",
+ "response team",
"centcom official",
"centcom commander",
"special ops officer",
@@ -677,6 +678,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if("syndicate commando")
M.equip_syndicate_commando()
+ if("response team")
+ M.equip_strike_team()
+
if("centcom official")
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_officer(M), M.slot_w_uniform)
M.equip_if_possible(new /obj/item/clothing/shoes/black(M), M.slot_shoes)
@@ -686,7 +690,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
var/obj/item/clothing/glasses/sunglasses/V = new(M)
V.loc = K
M.equip_if_possible(K, M.slot_wear_suit)
- M.equip_if_possible(new /obj/item/weapon/gun/energy(M), M.slot_s_store)
+ M.equip_if_possible(new /obj/item/weapon/gun/energy/gun(M), M.slot_s_store)
var/obj/item/device/pda/heads/pda = new(M)
pda.owner = M.real_name
@@ -694,10 +698,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
pda.name = "PDA-[M.real_name] ([pda.ownjob])"
M.equip_if_possible(pda, M.slot_r_store)
-
- var/obj/item/weapon/clipboard/G = new(M)
- G.pen = new /obj/item/weapon/pen(G)
- M.equip_if_possible(G, M.slot_l_store)
+ M.equip_if_possible(new /obj/item/weapon/clipboard(M), M.slot_l_store)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card"
diff --git a/code/modules/chemical/Chemistry-Tools.dm b/code/modules/chemical/Chemistry-Tools.dm
index f687dad93e..1dedd042d6 100644
--- a/code/modules/chemical/Chemistry-Tools.dm
+++ b/code/modules/chemical/Chemistry-Tools.dm
@@ -2187,6 +2187,17 @@
..()
reagents.add_reagent("cryoxadone", 30)
+/obj/item/weapon/reagent_containers/glass/beaker/tricordrazine
+ name = "beaker"
+ desc = "A beaker. Can hold up to 50 units."
+ icon = 'chemical.dmi'
+ icon_state = "beaker0"
+ item_state = "beaker"
+
+ New()
+ ..()
+ reagents.add_reagent("tricordrazine", 30)
+
/obj/item/weapon/reagent_containers/food/drinks/golden_cup
desc = "A golden cup"
name = "golden cup"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index f45a231b45..edd9aba5ea 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -14,7 +14,7 @@ Doesn't work on other aliens/AI.*/
src << "\green Not enough plasma stored."
return 0
else if(Y && (!isturf(src.loc) || istype(src.loc, /turf/space)))
- src << "\green Bad place for a garden!"
+ src << "\green Weeds would not be able to survive here."
return 0
else return 1
@@ -133,35 +133,32 @@ I kind of like the right click only--the window version can get a little confusi
for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
if(!v.welded)
vent_found = v
+ break
else
src << "\red That vent is welded."
+
if(vent_found)
- var/list/vents = list()
- if(vent_found.network&&vent_found.network.normal_members.len)
+ var/list/ventAreas = list() // A list of the areas of all the vents you can go to.
+ var/list/vents = list() // The list of vent objects you can go to.
+ if(vent_found.network && vent_found.network.normal_members.len)
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
- if(temp_vent.loc == loc)
+ if(temp_vent.loc == loc || temp_vent.loc.z != loc.z)
continue
if(temp_vent.welded)
continue
+
vents.Add(temp_vent)
- var/list/choices = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents)
- if(vent.loc.z != loc.z)
- continue
- if(vent.welded)
- continue
- var/atom/a = get_turf_loc(vent)
- choices.Add(a.loc)
- var/turf/startloc = loc
- var/obj/selection = input("Select a destination.", "Duct System") in choices
- var/selection_position = choices.Find(selection)
- if(loc==startloc)
- // Hacky way of hopefully preventing a runtime error from happening
- if(vents.len < selection_position)
- vents.len = selection_position//What the fuck is this I dont even, Right will likely have to fix this later
+ var/atom/a = get_turf_loc(temp_vent)
+ ventAreas.Add(a.loc)
- var/obj/machinery/atmospherics/unary/vent_pump/target_vent = vents[selection_position]
+
+ var/turf/startLoc = loc
+ var/area/destArea = input("Select a destination.", "Duct System") in ventAreas
+ var/destAreaIndex = ventAreas.Find(destArea)
+
+ if(loc==startLoc)
+ var/obj/machinery/atmospherics/unary/vent_pump/target_vent = vents[destAreaIndex]
if(target_vent)
for(var/mob/O in viewers(src, null))
O.show_message(text("[src] scrambles into the ventillation ducts!"), 1)
@@ -178,7 +175,7 @@ I kind of like the right click only--the window version can get a little confusi
spawn(round(travel_time/2))//give sound warning to anyone near the target vent
if(!target_vent.welded)
for(var/mob/O in hearers(target_vent, null))
- O.show_message("You hear something crawling trough the ventilation pipes.",2)
+ O.show_message("You hear something crawling through the ventilation pipes.",2)
spawn(travel_time)
if(target_vent.welded)//the vent can be welded while alien scrolled through the list or travelled.
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index f901319266..63ef86aee3 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -121,11 +121,12 @@
if (src.stat == 1 || stat == 2)
usr << "\red [name] doesn't seem to be responding to anything around [t_him], [t_his] eyes closed as though asleep."
- if((health < 0 || stat == 1) && distance <= 3)
+ if(health < 0 && distance <= 3)
usr << "\red [name] does not appear to be breathing."
if(istype(usr, /mob/living/carbon/human) && usr.stat == 0 && src.stat == 1 && distance <= 1)
for(var/mob/O in viewers(usr.loc, null))
O.show_message("[usr] checks [src]'s pulse.", 1)
+ sleep(15)
usr << "\blue [name] has a pulse!"
if (src.stat == 2 || (changeling && changeling.changeling_fakedeath == 1))
@@ -133,6 +134,7 @@
if(istype(usr, /mob/living/carbon/human) && usr.stat == 0)
for(var/mob/O in viewers(usr.loc, null))
O.show_message("[usr] checks [src]'s pulse.", 1)
+ sleep(15)
usr << "\red [name] has no pulse!"
else
if (src.getBruteLoss())
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 7ee57fc687..a8f7ee216f 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1469,7 +1469,7 @@
del(src)
return
if("internal")
- if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && istype(target.back, /obj/item/weapon/tank) && !( target.internal )) ) && !( target.internal )))
+ if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && (istype(target.back, /obj/item/weapon/tank) || istype(target.belt, /obj/item/weapon/tank) || istype(target.s_store, /obj/item/weapon/tank)) && !( target.internal )) ) && !( target.internal )))
//SN src = null
del(src)
return
@@ -2118,11 +2118,11 @@ It can still be worn/put on as normal.
if (!( istype(target.wear_mask, /obj/item/clothing/mask) ))
return
else
- if (istype(target.back, /obj/item/weapon/tank))
+ if (istype(target.back, /obj/item/weapon/tank) && (internalloc == "back" || !internalloc))
target.internal = target.back
- else if (istype(target.s_store, /obj/item/weapon/tank))
+ else if (istype(target.s_store, /obj/item/weapon/tank) && (internalloc == "store" || !internalloc))
target.internal = target.s_store
- else if (istype(target.belt, /obj/item/weapon/tank))
+ else if (istype(target.belt, /obj/item/weapon/tank) && (internalloc == "belt" || !internalloc))
target.internal = target.belt
if (target.internal)
for(var/mob/M in viewers(target, 1))
@@ -2136,10 +2136,16 @@ It can still be worn/put on as normal.
if(target)
target.update_clothing()
//SN src = null
+ for(var/mob/living/carbon/M in oview(1,target))
+ if(M.machine == target)
+ target.interact(M)
del(src)
return
/mob/living/carbon/human/show_inv(mob/user as mob)
+ interact(user)
+
+/mob/living/carbon/human/proc/interact(mob/user as mob)
user.machine = src
var/dat = {"
@@ -2154,12 +2160,12 @@ It can still be worn/put on as normal.
Right Ear: [(r_ear ? r_ear : "Nothing")]
Head: [(head ? head : "Nothing")]
Shoes: [(shoes ? shoes : "Nothing")]
-
Belt: [(belt ? belt : "Nothing")]
+
Belt: [(belt ? belt : "Nothing")] [(istype(wear_mask, /obj/item/clothing/mask) && istype(belt, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : ""]
Uniform: [(w_uniform ? w_uniform : "Nothing")]
(Exo)Suit: [(wear_suit ? wear_suit : "Nothing")]
-
Back: [(back ? back : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")]
+
Back: [(back ? back : "Nothing")][(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : ""]
ID: [(wear_id ? wear_id : "Nothing")]
-
Suit Storage: [(s_store ? s_store : "Nothing")]
+
Suit Storage: [(s_store ? s_store : "Nothing")] [(istype(wear_mask, /obj/item/clothing/mask) && istype(s_store, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : ""]
[(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))]
[(internal ? text("Remove Internal") : "")]
Empty Pockets
@@ -2335,6 +2341,8 @@ It can still be worn/put on as normal.
O.s_loc = usr.loc
O.t_loc = loc
O.place = href_list["item"]
+ if(href_list["loc"])
+ O.internalloc = href_list["loc"]
requests += O
spawn( 0 )
O.process()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index b05d23edef..2f683a56bb 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -753,18 +753,36 @@
contents += O
if(istype(module_state_1,/obj/item/borg/sight))
sight_mode |= module_state_1:sight_mode
+ else if(istype(module_state_1,/obj/item/weapon/zippo))
+ var/obj/item/weapon/zippo/Z = module_state_1
+ Z.lit = 1
+ Z.icon_state = "zippoon"
+ Z.item_state = "zippoon"
+ processing_objects.Add(Z)
else if(!module_state_2)
module_state_2 = O
O.layer = 20
contents += O
if(istype(module_state_2,/obj/item/borg/sight))
sight_mode |= module_state_2:sight_mode
+ else if(istype(module_state_2,/obj/item/weapon/zippo))
+ var/obj/item/weapon/zippo/Z = module_state_2
+ Z.lit = 1
+ Z.icon_state = "zippoon"
+ Z.item_state = "zippoon"
+ processing_objects.Add(Z)
else if(!module_state_3)
module_state_3 = O
O.layer = 20
contents += O
if(istype(module_state_3,/obj/item/borg/sight))
sight_mode |= module_state_3:sight_mode
+ else if(istype(module_state_3,/obj/item/weapon/zippo))
+ var/obj/item/weapon/zippo/Z = module_state_3
+ Z.lit = 1
+ Z.icon_state = "zippoon"
+ Z.item_state = "zippoon"
+ processing_objects.Add(Z)
else
src << "You need to disable a module first!"
installed_modules()
@@ -773,12 +791,30 @@
var/obj/item/O = locate(href_list["deact"])
if(activated(O))
if(module_state_1 == O)
+ if(istype(module_state_1, /obj/item/weapon/zippo))
+ var/obj/item/weapon/zippo/Z = module_state_1
+ Z.lit = 0
+ Z.icon_state = "zippo"
+ Z.item_state = "zippo"
+ processing_objects.Remove(Z)
module_state_1 = null
contents -= O
else if(module_state_2 == O)
- module_state_2 = null
+ if(istype(module_state_2, /obj/item/weapon/zippo))
+ var/obj/item/weapon/zippo/Z = module_state_2
+ Z.lit = 0
+ Z.icon_state = "zippo"
+ Z.item_state = "zippo"
+ processing_objects.Remove(Z)
+ module_state_2= null
contents -= O
else if(module_state_3 == O)
+ if(istype(module_state_3, /obj/item/weapon/zippo))
+ var/obj/item/weapon/zippo/Z = module_state_3
+ Z.lit = 0
+ Z.icon_state = "zippo"
+ Z.item_state = "zippo"
+ processing_objects.Remove(Z)
module_state_3 = null
contents -= O
else
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 0ee3724b77..e4158e0617 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -193,10 +193,7 @@
src.modules += M
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
-
- var/obj/item/weapon/zippo/L = new /obj/item/weapon/zippo(src)
- L.lit = 1
- src.modules += L
+ src.modules += new /obj/item/weapon/zippo(src)
src.modules += new /obj/item/weapon/tray(src)
src.modules += new /obj/item/weapon/reagent_containers/food/drinks/shaker(src)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index af2c6097c0..6d3ac0648e 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -270,15 +270,9 @@
proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank)
if (ticker.current_state == GAME_STATE_PLAYING)
- var/ailist[] = list()
- for (var/mob/living/silicon/ai/A in world)
- if (!A.stat)
- ailist += A
- if (ailist.len)
- var/mob/living/silicon/ai/announcer = pick(ailist)
- if(character.mind)
- if((character.mind.assigned_role != "Cyborg") && (character.mind.special_role != "MODE"))
- announcer.say("[character.real_name] has signed up as [rank].")
+ var/obj/item/device/radio/intercom/a = new /obj/item/device/radio/intercom(null)
+ a.autosay("[character.real_name] has arrived on the station.", "Arrivals Announcement Computer")
+ del(a)
proc/ManifestLateSpawn(var/mob/living/carbon/human/H, icon/H_icon) // Attempted fix to add late joiners to various databases -- TLE
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 6d4c5f3b1e..fd2cd466be 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -44,6 +44,8 @@
M.show_message(rendered, 2)
/mob/proc/say_understands(var/mob/other)
+ if(!other)
+ return 1
if (src.stat == 2)
return 1
else if (istype(other, src.type))
diff --git a/code/modules/power/pacman2.dm b/code/modules/power/pacman2.dm
new file mode 100644
index 0000000000..930877d441
--- /dev/null
+++ b/code/modules/power/pacman2.dm
@@ -0,0 +1,175 @@
+
+//Baseline portable generator. Has all the default handling. Not intended to be used on it's own (since it generates unlimited power).
+/obj/machinery/power/port_gen/pacman2
+ name = "Pacman II"
+ desc = "P.A.C.M.A.N. type II portable generator. Uses liquid plasma as a fuel source."
+ power_gen = 4500
+ var
+ obj/item/weapon/tank/plasma/P = null
+ board_path = "/obj/item/weapon/circuitboard/pacman2"
+ emagged = 0
+ heat = 0
+/*
+ process()
+ if(P)
+ if(P.air_contents.toxins <= 0)
+ P.air_contents.toxins = 0
+ eject()
+ else
+ P.air_contents.toxins -= 0.001
+ return
+*/
+
+ HasFuel()
+ if(P.air_contents.toxins >= 0.1)
+ return 1
+ return 0
+
+ UseFuel()
+ P.air_contents.toxins -= 0.01
+ return
+
+ New()
+ ..()
+ component_parts = list()
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
+ component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
+ component_parts += new /obj/item/weapon/cable_coil(src)
+ component_parts += new /obj/item/weapon/cable_coil(src)
+ component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
+ component_parts += new board_path(src)
+ RefreshParts()
+
+ RefreshParts()
+ var/temp_rating = 0
+ var/temp_reliability = 0
+ for(var/obj/item/weapon/stock_parts/SP in component_parts)
+ if(istype(SP, /obj/item/weapon/stock_parts/matter_bin))
+ //max_coins = SP.rating * SP.rating * 1000
+ else if(istype(SP, /obj/item/weapon/stock_parts/micro_laser) || istype(SP, /obj/item/weapon/stock_parts/capacitor))
+ temp_rating += SP.rating
+ for(var/obj/item/weapon/CP in component_parts)
+ temp_reliability += CP.reliability
+ reliability = min(round(temp_reliability / 4), 100)
+ power_gen = round(initial(power_gen) * (max(2, temp_rating) / 2))
+
+ examine()
+ ..()
+ usr << "\blue The generator has [P.air_contents.toxins] units of fuel left, producing [power_gen] per cycle."
+ if(crit_fail) usr << "\red The generator seems to have broken down."
+
+ handleInactive()
+ heat -= 2
+ if (heat < 0)
+ heat = 0
+ else
+ for(var/mob/M in viewers(1, src))
+ if (M.client && M.machine == src)
+ src.updateUsrDialog()
+
+ proc
+ overheat()
+ explosion(src.loc, 2, 5, 2, -1)
+
+ attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if(istype(O, /obj/item/weapon/tank/plasma))
+ if(P)
+ user << "\red The generator already has a plasma tank loaded!"
+ return
+ P = O
+ user.drop_item()
+ O.loc = src
+ user << "\blue You add the plasma tank to the generator."
+ else if (istype(O, /obj/item/weapon/card/emag))
+ emagged = 1
+ emp_act(1)
+ else if(!active)
+ if(istype(O, /obj/item/weapon/wrench))
+ anchored = !anchored
+ playsound(src.loc, 'Deconstruct.ogg', 50, 1)
+ if(anchored)
+ user << "\blue You secure the generator to the floor."
+ else
+ user << "\blue You unsecure the generator from the floor."
+ makepowernets()
+ else if(istype(O, /obj/item/weapon/screwdriver))
+ open = !open
+ playsound(src.loc, 'Screwdriver.ogg', 50, 1)
+ if(open)
+ user << "\blue You open the access panel."
+ else
+ user << "\blue You close the access panel."
+ else if(istype(O, /obj/item/weapon/crowbar) && !open)
+ var/obj/machinery/constructable_frame/machine_frame/new_frame = new /obj/machinery/constructable_frame/machine_frame(src.loc)
+ for(var/obj/item/I in component_parts)
+ if(I.reliability < 100)
+ I.crit_fail = 1
+ I.loc = src.loc
+ new_frame.state = 2
+ new_frame.icon_state = "box_1"
+ del(src)
+
+ attack_hand(mob/user as mob)
+ ..()
+ if (!anchored)
+ return
+
+ interact(user)
+
+ attack_ai(mob/user as mob)
+ interact(user)
+
+ attack_paw(mob/user as mob)
+ interact(user)
+
+ proc
+ interact(mob/user)
+ if (get_dist(src, user) > 1 )
+ if (!istype(user, /mob/living/silicon/ai))
+ user.machine = null
+ user << browse(null, "window=port_gen")
+ return
+
+ user.machine = src
+
+ var/dat = text("[name]
")
+ if (active)
+ dat += text("Generator: On
")
+ else
+ dat += text("Generator: Off
")
+ if(P)
+ dat += text("Currently loaded plasma tank: [P.air_contents.toxins]
")
+ else
+ dat += text("No plasma tank currently loaded.
")
+ dat += text("Power output: - [power_gen * power_output] +
")
+ dat += text("Heat: [heat]
")
+ dat += "
Close"
+ user << browse("[dat]", "window=port_gen")
+
+ Topic(href, href_list)
+ if(..())
+ return
+
+ src.add_fingerprint(usr)
+ if(href_list["action"])
+ if(href_list["action"] == "enable")
+ if(!active && HasFuel() && !crit_fail)
+ active = 1
+ icon_state = "portgen1"
+ src.updateUsrDialog()
+ if(href_list["action"] == "disable")
+ if (active)
+ active = 0
+ icon_state = "portgen0"
+ src.updateUsrDialog()
+ if(href_list["action"] == "lower_power")
+ if (power_output > 1)
+ power_output--
+ src.updateUsrDialog()
+ if (href_list["action"] == "higher_power")
+ if (power_output < 4 || emagged)
+ power_output++
+ src.updateUsrDialog()
+ if (href_list["action"] == "close")
+ usr << browse(null, "window=port_gen")
+ usr.machine = null
diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm
index 6774671f16..2ad21eb5cd 100644
--- a/code/modules/power/port_gen.dm
+++ b/code/modules/power/port_gen.dm
@@ -327,4 +327,5 @@ display round(lastgen) and plasmatank amount
time_per_coin = 60
board_path = "/obj/item/weapon/circuitboard/pacman/mrs"
overheat()
- explosion(src.loc, 4, 4, 4, -1)
\ No newline at end of file
+ explosion(src.loc, 4, 4, 4, -1)
+
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 92ba2cb0c0..5c759614b5 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -37,6 +37,18 @@
for(var/obj/O in contents)
O.emp_act(severity)
+ attack(mob/living/M as mob, mob/living/user as mob, def_zone)
+ if (M == user && user.zone_sel.selecting == "mouth" && load_into_chamber())
+ M.visible_message("\red [user] sticks their gun in their mouth, ready to pull the trigger...")
+ if(!do_after(user, 40))
+ M.visible_message("\blue [user] decided life was worth living")
+ return
+ M.visible_message("\red [user] pulls the trigger.")
+ M.apply_damage(70, BRUTE, "head")
+ M.apply_damage(110, BRUTE, "chest")
+ return
+ else
+ return ..()
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)//TODO: go over this
if(flag) return //we're placing gun on a table or in backpack
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index 0cc4bfb71e..077a64b60d 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -94,7 +94,8 @@ h1, h2, h3, h4, h5, h6
.comradio
{
- color: #ACA82D;
+ color:#FF9900;
+ text-decoration: underline;
}
.syndradio
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 8fe609fbb6..e7425bb46c 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi
index 9f531da8f6..d0ca90f995 100644
Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ
diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi
index 386ce97659..66c6559e8c 100644
Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ
diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi
index 92e5d91196..cf7cc1e282 100644
Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index 8f25d7e0a0..fdcfb9c205 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/icons/obj/tank.dmi b/icons/obj/tank.dmi
index cc0e0bbcdb..bc523dd9d2 100644
Binary files a/icons/obj/tank.dmi and b/icons/obj/tank.dmi differ
diff --git a/maps/tgstation.2.0.8.dmm b/maps/tgstation.2.0.8.dmm
index 36dfb2bc9a..2dd2f14b94 100644
--- a/maps/tgstation.2.0.8.dmm
+++ b/maps/tgstation.2.0.8.dmm
@@ -4870,7 +4870,7 @@
"bPH" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Assembly Line Maintenance"; req_access_txt = "12;29"},/turf/simulated/floor/plating,/area/assembly/assembly_line)
"bPI" = (/obj/structure/table,/obj/item/device/multitool,/obj/item/weapon/crowbar,/obj/item/device/flash,/obj/item/device/flash,/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/assembly/assembly_line)
"bPJ" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/disposal,/turf/simulated/floor,/area/assembly/assembly_line)
-"bPK" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/device/healthanalyzer,/obj/item/device/healthanalyzer,/obj/item/device/healthanalyzer,/turf/simulated/floor,/area/assembly/assembly_line)
+"bPK" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/device/healthanalyzer,/obj/item/device/healthanalyzer,/obj/item/device/healthanalyzer,/obj/item/weapon/reagent_containers/glass/beaker/tricordrazine,/obj/item/weapon/reagent_containers/glass/beaker/tricordrazine,/obj/item/weapon/reagent_containers/glass/beaker/tricordrazine,/turf/simulated/floor,/area/assembly/assembly_line)
"bPL" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 20},/obj/item/weapon/book/manual/robotics_cyborgs{pixel_y = 5},/turf/simulated/floor,/area/assembly/assembly_line)
"bPM" = (/obj/machinery/computer/rdconsole{id = 2; name = "Robotics R&D Console"; req_access = null; req_access_txt = "29"},/turf/simulated/floor,/area/assembly/assembly_line)
"bPN" = (/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/flash,/obj/item/device/flash,/obj/structure/table,/turf/simulated/floor,/area/assembly/assembly_line)