diff --git a/baystation12.dme b/baystation12.dme
index 9ad0f589c33..9a806182266 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -943,11 +943,13 @@
#include "code\modules\events\comms_blackout.dm"
#include "code\modules\events\communications_blackout.dm"
#include "code\modules\events\disease_outbreak.dm"
+#include "code\modules\events\dust.dm"
#include "code\modules\events\electrical_storm.dm"
#include "code\modules\events\event.dm"
#include "code\modules\events\event_container.dm"
#include "code\modules\events\event_dynamic.dm"
#include "code\modules\events\event_manager.dm"
+#include "code\modules\events\gravity.dm"
#include "code\modules\events\grid_check.dm"
#include "code\modules\events\infestation.dm"
#include "code\modules\events\ion_storm.dm"
diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm
index 3e5454d8ac0..9db70929281 100644
--- a/code/defines/procs/announce.dm
+++ b/code/defines/procs/announce.dm
@@ -15,17 +15,17 @@
log = do_log
newscast = do_newscast
-/datum/announcement/priority/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
+/datum/announcement/priority/New(var/do_log = 1, var/new_sound = 'sound/misc/notice2.ogg', var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "Priority Announcement"
announcement_type = "Priority Announcement"
-/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
+/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = 'sound/misc/notice2.ogg', var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "[command_name()] Update"
announcement_type = "[command_name()] Update"
-/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
+/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound = 'sound/misc/notice2.ogg', var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "Security Announcement"
announcement_type = "Security Announcement"
@@ -33,8 +33,8 @@
/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast)
if(!message)
return
- var/tmp/message_title = new_title ? new_title : title
- var/tmp/message_sound = new_sound ? sound(new_sound) : sound
+ var/message_title = new_title ? new_title : title
+ var/message_sound = new_sound ? new_sound : sound
message = sanitize(message, extra = 0)
message_title = sanitizeSafe(message_title)
@@ -102,8 +102,8 @@ datum/announcement/proc/Sound(var/message_sound)
PlaySound(message_sound)
datum/announcement/priority/Sound(var/message_sound)
- if(sound)
- world << sound
+ if(message_sound)
+ world << message_sound
datum/announcement/priority/command/Sound(var/message_sound)
PlaySound(message_sound)
diff --git a/code/game/antagonist/antagonist_build.dm b/code/game/antagonist/antagonist_build.dm
index f0f92c62b7a..34631d36fba 100644
--- a/code/game/antagonist/antagonist_build.dm
+++ b/code/game/antagonist/antagonist_build.dm
@@ -28,7 +28,9 @@
// This could use work.
if(flags & ANTAG_CLEAR_EQUIPMENT)
for(var/obj/item/thing in player.contents)
- del(thing)
+ player.drop_from_inventory(thing)
+ if(thing.loc != player)
+ del(thing)
return 1
if(flags & ANTAG_SET_APPEARANCE)
@@ -80,6 +82,7 @@
/datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player)
var/obj/item/weapon/card/id/W = new id_type(player)
+ if(!W) return
W.name = "[player.real_name]'s ID Card"
W.access |= default_access
W.assignment = "[assignment]"
diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm
index 05fb6d1ec9b..73c2c7fd78a 100644
--- a/code/game/antagonist/outsider/deathsquad.dm
+++ b/code/game/antagonist/outsider/deathsquad.dm
@@ -44,8 +44,9 @@ var/datum/antagonist/deathsquad/deathsquad
player.implant_loyalty(player)
var/obj/item/weapon/card/id/id = create_id("Asset Protection", player)
- id.access |= get_all_accesses()
- id.icon_state = "centcom"
+ if(id)
+ id.access |= get_all_accesses()
+ id.icon_state = "centcom"
create_radio(DTH_FREQ, player)
/datum/antagonist/deathsquad/apply(var/datum/mind/player)
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index 9bfdf9f0b65..e1fda4965c3 100644
--- a/code/game/dna/dna2_helpers.dm
+++ b/code/game/dna/dna2_helpers.dm
@@ -165,7 +165,7 @@
if((0 < beard) && (beard <= facial_hair_styles_list.len))
H.f_style = facial_hair_styles_list[beard]
- H.update_body(0)
+ H.force_update_limbs()
H.update_hair()
return 1
diff --git a/code/game/gamemodes/events/dust.dm b/code/game/gamemodes/events/dust.dm
index f2c510b9b98..2e8b3b13289 100644
--- a/code/game/gamemodes/events/dust.dm
+++ b/code/game/gamemodes/events/dust.dm
@@ -80,10 +80,11 @@ The "dust" will damage the hull of the station causin minor hull breaches.
startx = (TRANSITIONEDGE+1)
endy = rand(TRANSITIONEDGE,world.maxy-TRANSITIONEDGE)
endx = world.maxx-TRANSITIONEDGE
- var/goal = locate(endx, endy, 1)
+ var/z_level = pick(config.station_levels)
+ var/goal = locate(endx, endy, z_level)
src.x = startx
src.y = starty
- src.z = pick(config.station_levels)
+ src.z = z_level
spawn(0)
walk_towards(src, goal, 1)
return
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 544776d1447..8ad65194d18 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -98,8 +98,8 @@ var/global/datum/controller/gameticker/ticker
src.mode = config.pick_mode(master_mode)
if(!mode_started && !src.mode.can_start())
world << "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby."
- del(mode)
current_state = GAME_STATE_PREGAME
+ mode = null
job_master.ResetOccupations()
return 0
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 9b5cfaa526c..d537d113f9b 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -189,7 +189,7 @@
var/obj/item/stack/stack = eating
stack.use(max(1, round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials.
else
- user.drop_item(O)
+ user.remove_from_mob(O)
del(O)
updateUsrDialog()
diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm
index a038ece4140..e56e5446492 100644
--- a/code/game/machinery/camera/camera_assembly.dm
+++ b/code/game/machinery/camera/camera_assembly.dm
@@ -125,7 +125,7 @@
if(is_type_in_list(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
user << "You attach \the [W] into the assembly inner circuits."
upgrades += W
- user.drop_item(W)
+ user.remove_from_mob(W)
W.loc = src
return
diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm
index 4778ac13ead..4418586e9dd 100644
--- a/code/game/machinery/seed_extractor.dm
+++ b/code/game/machinery/seed_extractor.dm
@@ -11,7 +11,7 @@ obj/machinery/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob
// Fruits and vegetables.
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown) || istype(O, /obj/item/weapon/grown))
- user.drop_item(O)
+ user.remove_from_mob(O)
var/datum/seed/new_seed_type
if(istype(O, /obj/item/weapon/grown))
diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm
index ac3e89000cf..a54c40b755e 100644
--- a/code/game/objects/structures/coathanger.dm
+++ b/code/game/objects/structures/coathanger.dm
@@ -21,8 +21,7 @@
if (can_hang && !coat)
user.visible_message("[user] hangs [W] on \the [src].", "You hang [W] on the \the [src]")
coat = W
- user.drop_item(src)
- coat.loc = src
+ user.drop_from_inventory(coat, src)
update_icon()
else
user << "You cannot hang [W] on [src]"
diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
index 0728a9befae..8dacfa4c40f 100644
--- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
@@ -61,7 +61,7 @@
user << "\red Unwield the axe first."
return
fireaxe = O
- user.drop_item(O)
+ user.remove_from_mob(O)
src.contents += O
user << "\blue You place the fire axe back in the [src.name]."
update_icon()
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 6b857ae4cf3..d14ddf1405f 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -431,7 +431,7 @@
user.visible_message("The [src] was sliced apart by [user]!")
destroy()
- user.drop_item(src)
+ user.drop_item(src.loc)
return
/obj/structure/table/proc/straight_table_check(var/direction)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index d83d4da7474..41c27789a23 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -84,7 +84,8 @@ var/list/admin_verbs_admin = list(
/client/proc/empty_ai_core_toggle_latejoin,
/client/proc/aooc,
/client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */
- /client/proc/change_human_appearance_self /* Allows the human-based mob itself change its basic appearance */
+ /client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */
+ /client/proc/change_security_level
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
@@ -762,6 +763,17 @@ var/list/admin_verbs_mentor = list(
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/client/proc/change_security_level()
+ set name = "Set security level"
+ set desc = "Sets the station security level"
+ set category = "Admin"
+
+ if(!check_rights(R_ADMIN)) return
+ var sec_level = input(usr, "It's currently code [get_security_level()].", "Select Security Level") as null|anything in (list("green","blue","red","delta")-get_security_level())
+ if(alert("Switch from code [get_security_level()] to code [sec_level]?","Change security level?","Yes","No") == "Yes")
+ set_security_level(sec_level)
+ log_admin("[key_name(usr)] changed the security level to code [sec_level].")
+
//---- bs12 verbs ----
diff --git a/code/modules/events/communications_blackout.dm b/code/modules/events/communications_blackout.dm
index 181f66d9c0e..fabfdd33365 100644
--- a/code/modules/events/communications_blackout.dm
+++ b/code/modules/events/communications_blackout.dm
@@ -12,7 +12,7 @@
A << "
"
if(prob(30)) //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts.
- command_announcement.Announce(alert, new_sound = 'sound/misc/interference.ogg')
+ command_announcement.Announce(alert, new_sound = sound('sound/misc/interference.ogg', volume=50))
/datum/event/communications_blackout/start()
diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm
new file mode 100644
index 00000000000..12be475fc82
--- /dev/null
+++ b/code/modules/events/dust.dm
@@ -0,0 +1,22 @@
+/datum/event/dust
+ startWhen = 10
+ endWhen = 30
+
+/datum/event/dust/announce()
+ command_announcement.Announce("The station is now passing through a belt of space dust.", "Dust Alert")
+
+/datum/event/dust/start()
+ dust_swarm(get_severity())
+
+/datum/event/dust/end()
+ command_announcement.Announce("The station has now passed through the belt of space dust.", "Dust Notice")
+
+/datum/event/dust/proc/get_severity()
+ switch(severity)
+ if(EVENT_LEVEL_MUNDANE)
+ return "weak"
+ if(EVENT_LEVEL_MODERATE)
+ return prob(80) ? "norm" : "strong"
+ if(EVENT_LEVEL_MAJOR)
+ return "super"
+ return "weak"
diff --git a/code/modules/events/event.dm b/code/modules/events/event.dm
index 408c85900e6..0b69dc89bb4 100644
--- a/code/modules/events/event.dm
+++ b/code/modules/events/event.dm
@@ -37,16 +37,6 @@
return total_weight
-/datum/event_meta/alien/get_weight(var/list/active_with_role)
- if(config.aliens_allowed)
- return ..(active_with_role)
- return 0
-
-/datum/event_meta/ninja/get_weight(var/list/active_with_role)
- if(config.ninjas_allowed)
- return ..(active_with_role)
- return 0
-
/datum/event //NOTE: Times are measured in master controller ticks!
var/startWhen = 0 //When in the lifetime to call start().
var/announceWhen = 0 //When in the lifetime to call announce().
diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm
index df392cfada4..54e2da314e1 100644
--- a/code/modules/events/event_container.dm
+++ b/code/modules/events/event_container.dm
@@ -124,14 +124,15 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
available_events = list(
// Severity level, event name, even type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 100),
- new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50),
- new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15),
- new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 1, 10, 25),
- new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300),
- new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400),
- new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300),
- new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lost Carp", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10), 1),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Brand Intelligence",/datum/event/brand_intelligence,20, list(ASSIGNMENT_JANITOR = 25), 1),
+ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300),
+ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 1, 10, 25),
+ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15),
+ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lost Carp", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10), 1),
+ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300),
+ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50),
+ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Space Dust", /datum/event/dust , 30, list(ASSIGNMENT_ENGINEER = 5), 0, 0, 50),
+ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)),
)
@@ -140,30 +141,32 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
severity = EVENT_LEVEL_MODERATE
available_events = list(
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 1230),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, 100, list(ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SECURITY = 20), 1),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 20, list(ASSIGNMENT_SECURITY = 20)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space vines", /datum/event/spacevine, 200, list(ASSIGNMENT_ENGINEER = 10)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_shower, 0, list(ASSIGNMENT_ENGINEER = 20)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 500, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_ENGINEER = 60)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 250, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 50), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Appendicitis", /datum/event/spontaneous_appendicitis, 0, list(ASSIGNMENT_MEDICAL = 10), 1),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, 100, list(ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SECURITY = 20), 1),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 500, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 250, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravity Failure", /datum/event/gravity, 75, list(ASSIGNMENT_ENGINEER = 60)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_SCIENTIST = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
- new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Random Antagonist", /datum/event/random_antag, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_shower, 0, list(ASSIGNMENT_ENGINEER = 20)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 50), 1),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Random Antagonist", /datum/event/random_antag, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 20, list(ASSIGNMENT_SECURITY = 20)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 30, list(ASSIGNMENT_ENGINEER = 5)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)),
)
/datum/event_container/major
severity = EVENT_LEVEL_MAJOR
available_events = list(
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
- new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
- new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 60), 1),
+ new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
+ new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 0, list(ASSIGNMENT_ENGINEER = 15), 1),
+ new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
)
diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm
index 2cc225eaf6a..0dbe3a5017c 100644
--- a/code/modules/events/event_dynamic.dm
+++ b/code/modules/events/event_dynamic.dm
@@ -201,7 +201,7 @@ var/list/event_last_fired = list()
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "medical robot module")
active_with_role["Medical"]++
- if(M.mind.assigned_role in list("Chief Medical Officer", "Medical Doctor"))
+ if(M.mind.assigned_role in medical_positions)
active_with_role["Medical"]++
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "security robot module")
diff --git a/code/modules/events/gravity.dm b/code/modules/events/gravity.dm
new file mode 100644
index 00000000000..078e632842a
--- /dev/null
+++ b/code/modules/events/gravity.dm
@@ -0,0 +1,24 @@
+/datum/event/gravity
+ announceWhen = 5
+
+/datum/event/gravity/setup()
+ endWhen = rand(15, 60)
+
+/datum/event/gravity/announce()
+ command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes.", "Gravity Failure")
+
+/datum/event/gravity/start()
+ gravity_is_on = 0
+ for(var/area/A in world)
+ if(A.z in config.station_levels)
+ A.gravitychange(gravity_is_on, A)
+
+/datum/event/gravity/end()
+ if(!gravity_is_on)
+ gravity_is_on = 1
+
+ for(var/area/A in world)
+ if(A.z in config.station_levels)
+ A.gravitychange(gravity_is_on, A)
+
+ command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.", "Gravity Restored")
diff --git a/code/modules/events/meteors.dm b/code/modules/events/meteors.dm
index 33bee714ffb..45d59ca8cd0 100644
--- a/code/modules/events/meteors.dm
+++ b/code/modules/events/meteors.dm
@@ -1,12 +1,10 @@
-//cael - two events here
-
//meteor storms are much heavier
/datum/event/meteor_wave
startWhen = 6
endWhen = 33
/datum/event/meteor_wave/setup()
- endWhen = rand(10,25) * 3
+ endWhen = rand(15,30) * 3
/datum/event/meteor_wave/announce()
command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
@@ -26,7 +24,7 @@
var/waves = 1
/datum/event/meteor_shower/setup()
- waves = rand(1,4)
+ waves = rand(2,5)
/datum/event/meteor_shower/announce()
command_announcement.Announce("The station is now in a meteor shower.", "Meteor Alert")
diff --git a/code/modules/events/random_antagonist.dm b/code/modules/events/random_antagonist.dm
index dbdaa70983c..10f8778b3b3 100644
--- a/code/modules/events/random_antagonist.dm
+++ b/code/modules/events/random_antagonist.dm
@@ -10,4 +10,4 @@
valid_types |= antag
if(valid_types.len)
var/datum/antagonist/antag = pick(valid_types)
- antag.random_spawn()
\ No newline at end of file
+ antag.random_spawn()
diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm
index 07bdccef521..7200711b605 100644
--- a/code/modules/holodeck/HolodeckObjects.dm
+++ b/code/modules/holodeck/HolodeckObjects.dm
@@ -277,7 +277,7 @@
del(W)
return
else if (istype(W, /obj/item) && get_dist(src,user)<2)
- user.drop_item(src)
+ user.drop_item(src.loc)
visible_message("[user] dunks [W] into the [src]!", 3)
return
diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm
index 469896018e8..0ee7c6175e7 100644
--- a/code/modules/hydroponics/seed_storage.dm
+++ b/code/modules/hydroponics/seed_storage.dm
@@ -225,7 +225,7 @@
/obj/machinery/seed_storage/proc/add(var/obj/item/seeds/O as obj)
if (istype(O.loc, /mob))
var/mob/user = O.loc
- user.drop_item(O)
+ user.remove_from_mob(O)
else if(istype(O.loc,/obj/item/weapon/storage))
var/obj/item/weapon/storage/S = O.loc
S.remove_from_storage(O, src)
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 97acaf86de9..0d20e00166f 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -151,7 +151,7 @@ var/list/slot_equipment_priority = list( \
remove_from_mob(W)
if(!W) return 1 // self destroying objects (tk, grabs)
-
+
W.forceMove(Target)
update_icons()
return 1
@@ -165,7 +165,7 @@ var/list/slot_equipment_priority = list( \
/mob/proc/drop_r_hand(var/atom/Target)
return drop_from_inventory(r_hand, Target)
-//Drops the item in our active hand.
+//Drops the item in our active hand. TODO: rename this to drop_active_hand or something
/mob/proc/drop_item(var/atom/Target)
if(hand) return drop_l_hand(Target)
else return drop_r_hand(Target)
@@ -173,11 +173,11 @@ var/list/slot_equipment_priority = list( \
/*
Removes the object from any slots the mob might have, calling the appropriate icon update proc.
Does nothing else.
-
+
DO NOT CALL THIS PROC DIRECTLY. It is meant to be called only by other inventory procs.
It's probably okay to use it if you are transferring the item between slots on the same mob,
but chances are you're safer calling remove_from_mob() or drop_from_inventory() anyways.
-
+
As far as I can tell the proc exists so that mobs with different inventory slots can override
the search through all the slots, without having to duplicate the rest of the item dropping.
*/
@@ -216,7 +216,7 @@ var/list/slot_equipment_priority = list( \
O.screen_loc = null
if(istype(O, /obj/item))
var/obj/item/I = O
- I.dropped()
+ I.dropped(src)
return 1
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index d2aa61e635b..05ceed79162 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -2,6 +2,9 @@
name = "brain"
health = 400 //They need to live awhile longer than other organs.
desc = "A piece of juicy meat found in a person's head."
+ organ_tag = "brain"
+ parent_organ = "head"
+ vital = 1
icon_state = "brain2"
force = 1.0
w_class = 2.0
@@ -46,7 +49,7 @@
/obj/item/organ/brain/removed(var/mob/living/user)
- ..()
+ name = "[owner.real_name]'s brain"
var/mob/living/simple_animal/borer/borer = owner.has_brain_worms()
@@ -57,6 +60,8 @@
if(istype(B) && istype(owner))
B.transfer_identity(owner)
+ ..()
+
/obj/item/organ/brain/replaced(var/mob/living/target)
if(target.key)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 63eba6e781d..da10a9ea00d 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -31,10 +31,9 @@
var/d = rand(round(I.force / 4), I.force)
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
- var/organ = H.get_organ("chest")
- if (istype(organ, /obj/item/organ/external))
- var/obj/item/organ/external/temp = organ
- if(temp.take_damage(d, 0))
+ var/obj/item/organ/external/organ = H.get_organ("chest")
+ if (istype(organ))
+ if(organ.take_damage(d, 0))
H.UpdateDamageIcon()
H.updatehealth()
else
@@ -328,7 +327,7 @@
if(!item) return //Grab processing has a chance of returning null
-
+
src.remove_from_mob(item)
item.loc = src.loc
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index 311942ca021..e2ef586f05c 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -117,7 +117,7 @@
g_skin = green
b_skin = blue
- update_body()
+ force_update_limbs()
return 1
/mob/living/carbon/human/proc/change_skin_tone(var/tone)
@@ -126,7 +126,7 @@
s_tone = tone
- update_body()
+ force_update_limbs()
return 1
/mob/living/carbon/human/proc/update_dna()
@@ -186,3 +186,8 @@
/proc/q()
var/mob/living/carbon/human/H = usr
H.change_appearance(APPEARANCE_ALL)
+
+/mob/living/carbon/human/proc/force_update_limbs()
+ for(var/obj/item/organ/external/O in organs)
+ O.sync_colour_to_human(src)
+ update_body(0)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 9c3057c52d8..1e693fd63fc 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -20,6 +20,9 @@
else
set_species()
+ if(species)
+ name = species.get_random_name(gender)
+
var/datum/reagents/R = new/datum/reagents(1000)
reagents = R
R.my_atom = src
@@ -326,8 +329,8 @@
//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable
/mob/living/carbon/human/proc/get_face_name()
- var/obj/item/organ/external/head/head = get_organ("head")
- if( !head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
+ var/obj/item/organ/external/head = get_organ("head")
+ if(!head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
return "Unknown"
return real_name
@@ -1119,8 +1122,6 @@
species = all_species[new_species]
- species.create_organs(src)
-
if(species.language)
add_language(species.language)
@@ -1137,6 +1138,8 @@
g_skin = 0
b_skin = 0
+ species.create_organs(src)
+
species.handle_post_spawn(src)
maxHealth = species.total_health
@@ -1361,3 +1364,8 @@
U << "You pop [S]'s [current_limb.joint] back in!"
S << "[U] pops your [current_limb.joint] back in!"
current_limb.undislocate()
+
+/mob/living/carbon/human/drop_from_inventory(var/obj/item/W, var/atom/Target = null)
+ if(W in organs)
+ return
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
index 853fb4e8d47..c037d81fb73 100644
--- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
@@ -45,7 +45,7 @@
"heart" = /obj/item/organ/heart,
"lungs" = /obj/item/organ/lungs,
"liver" = /obj/item/organ/liver,
- "kidneys" = /obj/item/organ/kidney,
+ "kidneys" = /obj/item/organ/kidneys,
"brain" = /obj/item/organ/brain,
"eyes" = /obj/item/organ/eyes,
"stack" = /obj/item/organ/stack/vox
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 09f3360d45e..b97e8ceed67 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -110,7 +110,7 @@
"heart" = /obj/item/organ/heart,
"lungs" = /obj/item/organ/lungs,
"liver" = /obj/item/organ/liver,
- "kidneys" = /obj/item/organ/kidney,
+ "kidneys" = /obj/item/organ/kidneys,
"brain" = /obj/item/organ/brain,
"appendix" = /obj/item/organ/appendix,
"eyes" = /obj/item/organ/eyes
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 00802c5da91..0bf49782972 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -967,6 +967,11 @@ default behaviour is:
/mob/living/proc/slip(var/slipped_on,stun_duration=8)
return 0
+/mob/living/carbon/drop_from_inventory(var/obj/item/W, var/atom/Target = null)
+ if(W in internal_organs)
+ return
+ ..()
+
/mob/living/carbon/proc/spin(spintime, speed)
spawn()
var/D = dir
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index e4405c57672..482ec2e3a19 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -729,7 +729,7 @@ note dizziness decrements automatically in the mob's Life() proc.
stat(null,"Location:\t([x], [y], [z])")
stat(null,"CPU:\t[world.cpu]")
stat(null,"Instances:\t[world.contents.len]")
- if(statpanel("Status") && processScheduler.getIsRunning())
+ if(statpanel("Status") && processScheduler && processScheduler.getIsRunning())
var/datum/controller/process/process
process = processScheduler.getProcess("ticker")
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 90e201b3828..1d67b712f51 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -473,6 +473,7 @@
//new_character.dna.UpdateSE()
// Do the initial caching of the player's body icons.
+ new_character.force_update_limbs()
new_character.regenerate_icons()
new_character.key = key //Manually transfer the key to log them in
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 5d307fffcf2..f97df890809 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -235,12 +235,14 @@ var/list/organ_cache = list()
owner.internal_organs_by_name[organ_tag] = null
owner.internal_organs_by_name -= organ_tag
+ owner.internal_organs_by_name -= null
owner.internal_organs -= src
var/obj/item/organ/external/affected = owner.get_organ(parent_organ)
if(affected) affected.internal_organs -= src
loc = owner.loc
+ processing_objects |= src
rejecting = null
var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list
if(!organ_blood || !organ_blood.data["blood_DNA"])
@@ -269,6 +271,7 @@ var/list/organ_cache = list()
transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"]
owner = target
+ processing_objects -= src
target.internal_organs |= src
affected.internal_organs |= src
target.internal_organs_by_name[organ_tag] = src
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index b6f14b64bce..d8ba25d750b 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -3,13 +3,16 @@
****************************************************/
/obj/item/organ/external
name = "external"
+ min_broken_damage = 30
+ max_damage = 0
+ dir = SOUTH
+ organ_tag = "limb"
+
var/icon_name = null
var/body_part = null
var/icon_position = 0
-
var/model
var/force_icon
-
var/damage_state = "00"
var/brute_dam = 0
var/burn_dam = 0
@@ -18,7 +21,7 @@
var/icon/mob_icon
var/gendered_icon = 0
var/limb_name
- var/disfigured = 1
+ var/disfigured = 0
var/cannot_amputate
var/cannot_break
var/s_tone
@@ -26,38 +29,25 @@
var/list/wounds = list()
var/number_wounds = 0 // cache the number of wounds, which is NOT wounds.len!
var/perma_injury = 0
-
var/obj/item/organ/external/parent
var/list/obj/item/organ/external/children
-
- // Internal organs of this body part
- var/list/internal_organs = list()
-
+ var/list/internal_organs = list() // Internal organs of this body part
var/damage_msg = "\red You feel an intense pain"
var/broken_description
-
var/open = 0
var/stage = 0
var/cavity = 0
var/sabotaged = 0 // If a prosthetic limb is emagged, it will detonate when it fails.
var/encased // Needs to be opened with a saw to access the organs.
-
var/obj/item/hidden = null
var/list/implants = list()
-
- // how often wounds should be updated, a higher number means less often
- var/wound_update_accuracy = 1
-
+ var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often
var/joint = "joint" // Descriptive string used in dislocation.
var/amputation_point // Descriptive string used in amputation.
var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ.
var/can_grasp
var/can_stand
- min_broken_damage = 30
- max_damage = 0
- dir = SOUTH
-
/obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob)
switch(stage)
if(0)
@@ -650,8 +640,8 @@ Note that amputating the affected organ does in fact remove the infection from t
wounds.Cut()
if(parent)
var/datum/wound/W
- if(max_damage < 50)
- W = new/datum/wound/lost_limb/small(max_damage)
+ if(clean || max_damage < 50)
+ W = new/datum/wound/lost_limb/small(max_damage/2)
else
W = new/datum/wound/lost_limb(max_damage)
parent.children -= src
@@ -940,6 +930,7 @@ Note that amputating the affected organ does in fact remove the infection from t
gendered_icon = 1
cannot_amputate = 1
parent_organ = null
+ encased = "ribcage"
/obj/item/organ/external/groin
name = "lower body"
@@ -1061,9 +1052,11 @@ Note that amputating the affected organ does in fact remove the infection from t
joint = "jaw"
amputation_point = "neck"
gendered_icon = 1
+ encased = "skull"
/obj/item/organ/external/head/removed()
if(owner)
+ name = "[owner.real_name]'s head"
owner.u_equip(owner.glasses)
owner.u_equip(owner.head)
owner.u_equip(owner.l_ear)
diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm
index d5b6bf2a4e1..b0e23df3d25 100644
--- a/code/modules/organs/organ_icon.dm
+++ b/code/modules/organs/organ_icon.dm
@@ -16,7 +16,9 @@ var/global/list/limb_icon_cache = list()
/obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human)
s_tone = null
s_col = null
- if(human.s_tone && (human.species.flags & HAS_SKIN_TONE))
+ if(status & ORGAN_ROBOT)
+ return
+ if(!isnull(human.s_tone) && (human.species.flags & HAS_SKIN_TONE))
s_tone = human.s_tone
if(human.species.flags & HAS_SKIN_COLOR)
s_col = list(human.r_skin, human.g_skin, human.b_skin)
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index c552631abfd..46e22e1e5fa 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -44,7 +44,7 @@
organ_tag = "kidneys"
parent_organ = "groin"
-/obj/item/organ/kidney/process()
+/obj/item/organ/kidneys/process()
..()
@@ -61,7 +61,6 @@
else if(is_broken())
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
-
/obj/item/organ/eyes
name = "eyeballs"
icon_state = "eyes"
@@ -113,7 +112,7 @@
name = "liver"
icon_state = "liver"
organ_tag = "liver"
- parent_organ = "chest"
+ parent_organ = "groin"
/obj/item/organ/liver/process()
@@ -175,6 +174,7 @@
name = "appendix"
icon_state = "appendix"
parent_organ = "groin"
+ organ_tag = "appendix"
/obj/item/organ/appendix/removed()
diff --git a/code/modules/projectiles/targeting.dm b/code/modules/projectiles/targeting.dm
index 388b53a2566..4e49a785e76 100644
--- a/code/modules/projectiles/targeting.dm
+++ b/code/modules/projectiles/targeting.dm
@@ -23,7 +23,7 @@
//Removing the lock and the buttons.
/obj/item/weapon/gun/dropped(mob/user as mob)
stop_aim()
- if (user.client)
+ if(user && user.client)
user.client.remove_gun_icons()
return ..()
@@ -47,7 +47,7 @@
/obj/item/weapon/gun/proc/PreFire(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, params)
//Lets not spam it.
if(lock_time > world.time - 2) return
-
+
user.set_dir(get_cardinal_dir(src, A))
if(isliving(A) && !(A in aim_targets))
Aim(A) //Clicked a mob, aim at them
@@ -58,7 +58,7 @@
if(isliving(M) && (M in view(user)) && !(M in aim_targets))
Aim(M) //Aha! Aim at them!
return 1
-
+
return 0
//Aiming at the target mob.
@@ -83,12 +83,12 @@
if(src != M.get_active_hand())
stop_aim()
return
-
+
//reflex firing is disabled when help intent is set
if (M.a_intent == I_HELP)
M << "\red You refrain from firing your [src] as your intent is set to help."
return
-
+
M.last_move_intent = world.time
var/firing_check = can_hit(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing.
if(firing_check > 0)
diff --git a/code/modules/reagents/dispenser/dispenser2.dm b/code/modules/reagents/dispenser/dispenser2.dm
index fb7299fcd96..8decba10d49 100644
--- a/code/modules/reagents/dispenser/dispenser2.dm
+++ b/code/modules/reagents/dispenser/dispenser2.dm
@@ -89,6 +89,10 @@
C.loc = loc
else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food))
+ if(container)
+ user << "There is already \a [container] on \the [src]!"
+ return
+
var/obj/item/weapon/reagent_containers/RC = W
if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food))
@@ -172,4 +176,4 @@
/obj/machinery/chemical_dispenser/attack_hand(mob/user as mob)
if(stat & BROKEN)
return
- ui_interact(user)
\ No newline at end of file
+ ui_interact(user)
diff --git a/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm b/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm
index 2437eeb0672..5a74061a239 100644
--- a/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm
+++ b/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm
@@ -14,9 +14,8 @@
if(held_container)
user << "\red You must remove the [held_container] first."
else
- user.drop_item(src)
held_container = W
- held_container.loc = src
+ user.drop_from_inventory(held_container, src)
user << "\blue You put the [held_container] onto the [src]."
var/image/I = image("icon"=W, "layer"=FLOAT_LAYER)
underlays += I
diff --git a/code/modules/security levels/security levels.dm b/code/modules/security levels/security levels.dm
index e96ed5b334d..1892af891ed 100644
--- a/code/modules/security levels/security levels.dm
+++ b/code/modules/security levels/security levels.dm
@@ -57,7 +57,7 @@
FA.overlays += image('icons/obj/monitors.dmi', "overlay_red")
if(SEC_LEVEL_DELTA)
- security_announcement_up.Announce("[config.alert_desc_delta]", "Attention! Delta security level reached!")
+ security_announcement_up.Announce("[config.alert_desc_delta]", "Attention! Delta security level reached!", new_sound = 'sound/effects/siren.ogg')
security_level = SEC_LEVEL_DELTA
for(var/obj/machinery/firealarm/FA in machines)
if(FA.z in config.contact_levels)
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index cbfea6912e0..8f5d7155dd8 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -343,9 +343,11 @@
var/o_a = (O.gender == PLURAL) ? "" : "a "
var/o_do = (O.gender == PLURAL) ? "don't" : "doesn't"
- if(target.species.has_organ[O.organ_tag])
+ if(O.organ_tag == "limb")
+ return 0
+ else if(target.species.has_organ[O.organ_tag])
- if(!O.health)
+ if(O.is_damaged())
user << "\red \The [O.organ_tag] [o_is] in no state to be transplanted."
return 2
@@ -355,7 +357,7 @@
user << "\red \The [target] already has [o_a][O.organ_tag]."
return 2
- if(O && affected.name == O.parent_organ)
+ if(O && affected.limb_name == O.parent_organ)
organ_compatible = 1
else
user << "\red \The [O.organ_tag] [o_do] normally go in \the [affected.name]."
@@ -377,9 +379,9 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] has transplanted \the [tool] into [target]'s [affected.name].", \
"\blue You have transplanted \the [tool] into [target]'s [affected.name].")
- user.drop_item(tool)
var/obj/item/organ/O = tool
if(istype(O))
+ user.remove_from_mob(O)
O.replaced(target,affected)
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
diff --git a/code/modules/surgery/robolimbs.dm b/code/modules/surgery/robolimbs.dm
index 5b524288f9c..e845d8bb7b7 100644
--- a/code/modules/surgery/robolimbs.dm
+++ b/code/modules/surgery/robolimbs.dm
@@ -39,8 +39,11 @@
if(L.part)
for(var/part_name in L.part)
- if(!isnull(target.get_organ(part_name))) continue
+ if(!isnull(target.get_organ(part_name)))
+ continue
var/list/organ_data = target.species.has_limbs["[target_zone]"]
+ if(!organ_data)
+ continue
var/new_limb_type = organ_data["path"]
var/obj/item/organ/external/new_limb = new new_limb_type(target)
new_limb.robotize(L.model_info)
diff --git a/tools/Event Probabilities/Event Probabilities.xls b/tools/Event Probabilities/Event Probabilities.xls
new file mode 100644
index 00000000000..e8085e8d9df
Binary files /dev/null and b/tools/Event Probabilities/Event Probabilities.xls differ