diff --git a/code/game/antagonist/_antagonist_setup.dm b/code/game/antagonist/_antagonist_setup.dm
index fa99f001f32..a5212256026 100644
--- a/code/game/antagonist/_antagonist_setup.dm
+++ b/code/game/antagonist/_antagonist_setup.dm
@@ -26,6 +26,7 @@
#define ANTAG_RANDSPAWN 256 // Potentially randomly spawns due to events.
#define ANTAG_VOTABLE 512 // Can be voted as an additional antagonist before roundstart.
#define ANTAG_SET_APPEARANCE 1024 // Causes antagonists to use an appearance modifier on spawn.
+#define ANTAG_RANDOM_EXCEPTED 2048 // If a game mode randomly selects antag types, antag types with this flag should be excluded.
// Globals.
var/global/list/all_antag_types = list()
diff --git a/code/game/antagonist/antagonist_helpers.dm b/code/game/antagonist/antagonist_helpers.dm
index adc706734fd..1a3f9aa67d0 100644
--- a/code/game/antagonist/antagonist_helpers.dm
+++ b/code/game/antagonist/antagonist_helpers.dm
@@ -47,4 +47,12 @@
return 1
/datum/antagonist/proc/is_latejoin_template()
- return (flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
\ No newline at end of file
+ return (flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
+
+/proc/all_random_antag_types()
+ // No caching as the ANTAG_RANDOM_EXCEPTED flag can be added/removed mid-round.
+ var/list/antag_candidates = all_antag_types.Copy()
+ for(var/datum/antagonist/antag in antag_candidates)
+ if(antag.flags & ANTAG_RANDOM_EXCEPTED)
+ antag_candidates -= antag
+ return antag_candidates
diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm
index 4cc8afff6ce..ca0b39aaefe 100644
--- a/code/game/antagonist/outsider/deathsquad.dm
+++ b/code/game/antagonist/outsider/deathsquad.dm
@@ -7,7 +7,7 @@ var/datum/antagonist/deathsquad/deathsquad
role_text_plural = "Death Commandos"
welcome_text = "You work in the service of corporate Asset Protection, answering directly to the Board of Directors."
landmark_id = "Commando"
- flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER
+ flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER | ANTAG_RANDOM_EXCEPTED
default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
antaghud_indicator = "huddeathsquad"
diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm
index 98a44442dc6..e8517dbf4e8 100644
--- a/code/game/antagonist/outsider/ert.dm
+++ b/code/game/antagonist/outsider/ert.dm
@@ -11,7 +11,7 @@ var/datum/antagonist/ert/ert
landmark_id = "Response Team"
id_type = /obj/item/weapon/card/id/centcom/ERT
- flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME
+ flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME | ANTAG_RANDOM_EXCEPTED
antaghud_indicator = "hudloyalist"
hard_cap = 5
diff --git a/code/game/gamemodes/calamity/calamity.dm b/code/game/gamemodes/calamity/calamity.dm
index 3104e624e34..b17277aaae9 100644
--- a/code/game/gamemodes/calamity/calamity.dm
+++ b/code/game/gamemodes/calamity/calamity.dm
@@ -11,19 +11,17 @@
event_delay_mod_major = 0.75
/datum/game_mode/calamity/create_antagonists()
+ var/list/antag_candidates = all_random_antag_types()
- //Let's not modify global lists for trivial reasons, even if it seems harmless right now.
- var/list/antag_candidates = all_antag_types.Copy()
-
var/grab_antags = round(num_players()/ANTAG_TYPE_RATIO)+1
while(antag_candidates.len && antag_tags.len < grab_antags)
var/antag_id = pick(antag_candidates)
antag_candidates -= antag_id
antag_tags |= antag_id
-
+
..()
/datum/game_mode/calamity/check_victory()
world << "This terrible, terrible day has finally ended!"
-#undef ANTAG_TYPE_RATIO
\ No newline at end of file
+#undef ANTAG_TYPE_RATIO
diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm
index c42f76623c4..b511fb432b4 100644
--- a/code/modules/mob/language/language.dm
+++ b/code/modules/mob/language/language.dm
@@ -212,4 +212,10 @@
else
return ..()
+/proc/transfer_languages(var/mob/source, var/mob/target, var/except_flags)
+ for(var/datum/language/L in source.languages)
+ if(L.flags & except_flags)
+ continue
+ target.add_language(L.name)
+
#undef SCRAMBLE_CACHE_LEN
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 6997e5d945c..ef8605f460a 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -8,34 +8,34 @@
equipment_tint_total += C.tint;
/mob/living/carbon/human/can_eat(var/food, var/feedback = 1)
- var/status = can_eat_status()
- if(status == HUMAN_EATING_NO_ISSUE)
+ var/list/status = can_eat_status()
+ if(status[0] == HUMAN_EATING_NO_ISSUE)
return 1
if(feedback)
- if(status == HUMAN_EATING_NO_MOUTH)
+ if(status[0] == HUMAN_EATING_NO_MOUTH)
src << "Where do you intend to put \the [food]? You don't have a mouth!"
- else if(status == HUMAN_EATING_BLOCKED_MOUTH)
- src << "\The [blocked] is in the way!"
+ else if(status[0] == HUMAN_EATING_BLOCKED_MOUTH)
+ src << "\The [status[1]] is in the way!"
return 0
/mob/living/carbon/human/can_force_feed(var/feeder, var/food, var/feedback = 1)
- var/status = can_eat_status()
- if(status == HUMAN_EATING_NO_ISSUE)
+ var/list/status = can_eat_status()
+ if(status[0] == HUMAN_EATING_NO_ISSUE)
return 1
if(feedback)
- if(status == HUMAN_EATING_NO_MOUTH)
+ if(status[0] == HUMAN_EATING_NO_MOUTH)
feeder << "Where do you intend to put \the [food]? \The [src] doesn't have a mouth!"
- else if(status == HUMAN_EATING_BLOCKED_MOUTH)
- feeder << "\The [blocked] is in the way!"
+ else if(status[0] == HUMAN_EATING_BLOCKED_MOUTH)
+ feeder << "\The [status[1]] is in the way!"
return 0
/mob/living/carbon/human/proc/can_eat_status()
if(!check_has_mouth())
- return HUMAN_EATING_NO_MOUTH
+ return list(HUMAN_EATING_NO_MOUTH)
var/obj/item/blocked = check_mouth_coverage()
if(blocked)
- return HUMAN_EATING_BLOCKED_MOUTH
- return HUMAN_EATING_NO_ISSUE
+ return list(HUMAN_EATING_BLOCKED_MOUTH, blocked)
+ return list(HUMAN_EATING_NO_ISSUE)
#undef HUMAN_EATING_NO_ISSUE
#undef HUMAN_EATING_NO_MOUTH
diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm
index 50f46b4bb41..1728b61008d 100644
--- a/code/modules/mob/living/carbon/human/human_powers.dm
+++ b/code/modules/mob/living/carbon/human/human_powers.dm
@@ -224,11 +224,14 @@
set name = "Split"
set desc = "Split your humanoid form into its constituent nymphs."
set category = "Abilities"
+ diona_split_into_nymphs(5) // Separate proc to void argments being supplied when used as a verb
+/mob/living/carbon/human/proc/diona_split_into_nymphs(var/number_of_resulting_nymphs)
var/turf/T = get_turf(src)
var/mob/living/carbon/alien/diona/S = new(T)
S.set_dir(dir)
+ transfer_languages(src, S)
if(mind)
mind.transfer_to(S)
@@ -239,20 +242,18 @@
for(var/mob/living/carbon/alien/diona/D in src)
nymphs++
- D.loc = T
+ D.forceMove(T)
+ transfer_languages(src, D, WHITELISTED|RESTRICTED)
D.set_dir(pick(NORTH, SOUTH, EAST, WEST))
- if(nymphs < 5)
- for(var/i in nymphs to 4)
+ if(nymphs < number_of_resulting_nymphs)
+ for(var/i in nymphs to (number_of_resulting_nymphs - 1))
var/mob/M = new /mob/living/carbon/alien/diona(T)
+ transfer_languages(src, M, WHITELISTED|RESTRICTED)
M.set_dir(pick(NORTH, SOUTH, EAST, WEST))
-
for(var/obj/item/W in src)
drop_from_inventory(W)
visible_message("\The [src] quivers slightly, then splits apart with a wet slithering noise.")
-
qdel(src)
-
-
diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm
index 98184b34042..4fa41f1a5ba 100644
--- a/code/modules/mob/living/carbon/human/species/station/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station/station.dm
@@ -242,19 +242,7 @@
return ..()
/datum/species/diona/handle_death(var/mob/living/carbon/human/H)
-
- var/mob/living/carbon/alien/diona/S = new(get_turf(H))
-
- if(H.mind)
- H.mind.transfer_to(S)
-
- for(var/mob/living/carbon/alien/diona/D in H.contents)
- if(D.client)
- D.loc = H.loc
- else
- qdel(D)
-
- H.visible_message("[H] splits apart with a wet slithering noise!")
+ H.diona_split_into_nymphs(0)
/datum/species/machine
name = "Machine"
diff --git a/icons/mob/screen1_alien.dmi b/icons/mob/screen1_alien.dmi
index b21cd203dd5..4ee41ca91c6 100644
Binary files a/icons/mob/screen1_alien.dmi and b/icons/mob/screen1_alien.dmi differ
diff --git a/maps/exodus-2.dmm b/maps/exodus-2.dmm
index 67d159407ee..580720dae71 100644
--- a/maps/exodus-2.dmm
+++ b/maps/exodus-2.dmm
@@ -1817,6 +1817,7 @@
"IW" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{on = 0; pixel_x = -3; pixel_y = 8},/obj/item/weapon/reagent_containers/food/drinks/flask/barflask,/obj/item/device/radio/intercom/syndicate{dir = 4; pixel_x = 22},/turf/simulated/floor/carpet,/area/wizard_station)
"IX" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/gloves/yellow/vox,/obj/item/clothing/under/vox/vox_casual,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"})
"IY" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/gloves/yellow/vox,/obj/item/clothing/glasses/thermal/plain/monocle,/obj/item/clothing/under/vox/vox_robes,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"})
+"IZ" = (/obj/effect/landmark{name = "ninjastart"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership{name = "\improper Ninja Base"})
"Ja" = (/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"})
"Jb" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/material/ashtray/bronze{pixel_x = -1; pixel_y = 1},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding)
"Jc" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/material/ashtray/bronze{pixel_x = -1; pixel_y = 1},/obj/machinery/camera/network/crescent{c_tag = "Crescent Bar East"; dir = 4},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding)
@@ -2025,7 +2026,7 @@ aTbeaRaZbdaSaZbdaSbeaRaZbdaSbeaRaZbdaSbeaRaZbdaSbfbbaXaMaMaMaMbeahakadaiaaaoamaj
bcbbaUaVaTaZaVaTaZbbaUaVaTaZbbaUaVaTaZbbaUaVaTaZaRaYaWaMaMaMaMaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMdjhegWheiAaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaMaMaMaMaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMheiCiBiDheaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjaiBjriBjaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjtiBiBiBjtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjtIZiBIZjtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjtiBiBiBjtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjviBiBiBjvaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhejxjwjAheaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM