From 82a331e777c2f5cb2edf1c8ada4a5f73a3a506cf Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Thu, 2 Jun 2022 13:39:09 +0300
Subject: [PATCH 01/55] Update computer.dm
---
code/modules/shuttle/computer.dm | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/code/modules/shuttle/computer.dm b/code/modules/shuttle/computer.dm
index 829da6224a1c..642305964b0d 100644
--- a/code/modules/shuttle/computer.dm
+++ b/code/modules/shuttle/computer.dm
@@ -137,3 +137,7 @@
/obj/machinery/computer/shuttle/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
if(port && (shuttleId == initial(shuttleId) || override))
shuttleId = port.id
+
+/obj/machinery/computer/shuttle/AltClick(user)
+ if(istype(user, /mob/living/carbon) || istype(user, /mob/living/simple_animal/hostile/asteroid/elite))
+ ui_interact(user, null)
From 3fc045e2e54c27799a4d48a9f1d8365041afce81 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sat, 4 Jun 2022 16:50:12 +0300
Subject: [PATCH 02/55] Update meat.dm
---
code/modules/food_and_drinks/food/snacks/meat.dm | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/code/modules/food_and_drinks/food/snacks/meat.dm b/code/modules/food_and_drinks/food/snacks/meat.dm
index 15c73412feb7..12abbd676081 100644
--- a/code/modules/food_and_drinks/food/snacks/meat.dm
+++ b/code/modules/food_and_drinks/food/snacks/meat.dm
@@ -340,18 +340,6 @@
icon_state = "shadowmeat"
desc = "It is covered in a strange darkness. This slab's magical properties appear to be drastically weakened due to the synthetic nature of the meat."
-/obj/item/reagent_containers/food/snacks/meat/slab/plagued
- name = "meat"
- desc = "A slab of disease-ridden meat. Eating it is a questionable idea."
- icon_state = "meat"
- dried_type = /obj/item/reagent_containers/food/snacks/sosjerky/
- bitesize = 3
- list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/cooking_oil = 2, /datum/reagent/plaguebacteria = 3) //It is infected by plague
- slice_path = /obj/item/reagent_containers/food/snacks/meat/raw_cutlet/plain
- slices_num = 3
- filling_color = "#FF0000"
- tastes = list("meat" = 2, "decay" = 1)
- foodtype = MEAT | RAW
////////////////////////////////////// MEAT STEAKS ///////////////////////////////////////////////////////////
From db1f40761e99e3395158c3c0a443b3efdae5b925 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Tue, 7 Jun 2022 16:11:33 +0300
Subject: [PATCH 03/55] Update objects.dm
---
code/_globalvars/lists/objects.dm | 2 ++
1 file changed, 2 insertions(+)
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 331f30de8bd1..87a4a0f38cb0 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -40,3 +40,5 @@ GLOBAL_LIST_EMPTY(ai_core_displays)
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert
GLOBAL_LIST_INIT(alarms, list("Fire" = list(), "Atmosphere" = list(), "Power" = list())) //all engineering alerts for station alert consoles and alarm manager
+
+GLOBAL_LIST_EMPTY(hog_structures)
From 2558753f387843ad6a8530920d15409b834899a1 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Tue, 14 Jun 2022 20:36:00 +0300
Subject: [PATCH 04/55] Update computer.dm
---
code/modules/shuttle/computer.dm | 4 ----
1 file changed, 4 deletions(-)
diff --git a/code/modules/shuttle/computer.dm b/code/modules/shuttle/computer.dm
index 642305964b0d..829da6224a1c 100644
--- a/code/modules/shuttle/computer.dm
+++ b/code/modules/shuttle/computer.dm
@@ -137,7 +137,3 @@
/obj/machinery/computer/shuttle/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
if(port && (shuttleId == initial(shuttleId) || override))
shuttleId = port.id
-
-/obj/machinery/computer/shuttle/AltClick(user)
- if(istype(user, /mob/living/carbon) || istype(user, /mob/living/simple_animal/hostile/asteroid/elite))
- ui_interact(user, null)
From e5a044ca51e9fadb76cf73b230d6d66a2fd1c236 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Tue, 14 Jun 2022 20:36:31 +0300
Subject: [PATCH 05/55] Update meat.dm
---
code/modules/food_and_drinks/food/snacks/meat.dm | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/code/modules/food_and_drinks/food/snacks/meat.dm b/code/modules/food_and_drinks/food/snacks/meat.dm
index 12abbd676081..15c73412feb7 100644
--- a/code/modules/food_and_drinks/food/snacks/meat.dm
+++ b/code/modules/food_and_drinks/food/snacks/meat.dm
@@ -340,6 +340,18 @@
icon_state = "shadowmeat"
desc = "It is covered in a strange darkness. This slab's magical properties appear to be drastically weakened due to the synthetic nature of the meat."
+/obj/item/reagent_containers/food/snacks/meat/slab/plagued
+ name = "meat"
+ desc = "A slab of disease-ridden meat. Eating it is a questionable idea."
+ icon_state = "meat"
+ dried_type = /obj/item/reagent_containers/food/snacks/sosjerky/
+ bitesize = 3
+ list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/cooking_oil = 2, /datum/reagent/plaguebacteria = 3) //It is infected by plague
+ slice_path = /obj/item/reagent_containers/food/snacks/meat/raw_cutlet/plain
+ slices_num = 3
+ filling_color = "#FF0000"
+ tastes = list("meat" = 2, "decay" = 1)
+ foodtype = MEAT | RAW
////////////////////////////////////// MEAT STEAKS ///////////////////////////////////////////////////////////
From 6705493de9ccbbe95b742bc166220935deedf83e Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Tue, 14 Jun 2022 20:36:53 +0300
Subject: [PATCH 06/55] Update objects.dm
---
code/_globalvars/lists/objects.dm | 2 --
1 file changed, 2 deletions(-)
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 87a4a0f38cb0..331f30de8bd1 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -40,5 +40,3 @@ GLOBAL_LIST_EMPTY(ai_core_displays)
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert
GLOBAL_LIST_INIT(alarms, list("Fire" = list(), "Atmosphere" = list(), "Power" = list())) //all engineering alerts for station alert consoles and alarm manager
-
-GLOBAL_LIST_EMPTY(hog_structures)
From 86f4d4fe847dce628413babbdacf4a02e683cb00 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Mon, 27 Jun 2022 16:00:36 +0300
Subject: [PATCH 07/55] boowomp
---
code/datums/mood_events/generic_negative_events.dm | 4 ++++
code/game/objects/items/clown_items.dm | 4 +++-
yogstation/code/game/objects/items/clown_items.dm | 5 +++++
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index 9edfcb07ce9d..7079d65816ca 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -222,3 +222,7 @@
description = "HE'S CUTTING ME OPEN!!\n"
mood_change = -8
+/datum/mood_event/boowomp
+ description = "I've been boowomped.\n"
+ mood_change = -1
+ timeout = 4 MINUTES
\ No newline at end of file
diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm
index 599ccff1d2c9..300a38322176 100644
--- a/code/game/objects/items/clown_items.dm
+++ b/code/game/objects/items/clown_items.dm
@@ -153,6 +153,7 @@
throw_speed = 3
throw_range = 7
attack_verb = list("HONKED")
+ var/funny = TRUE
/obj/item/bikehorn/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
@@ -169,7 +170,8 @@
AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50)
/obj/item/bikehorn/attack(mob/living/carbon/M, mob/living/carbon/user)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk)
+ if(funny)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk)
return ..()
/obj/item/bikehorn/suicide_act(mob/user)
diff --git a/yogstation/code/game/objects/items/clown_items.dm b/yogstation/code/game/objects/items/clown_items.dm
index 2a9fd7ba9756..52ef94d19346 100644
--- a/yogstation/code/game/objects/items/clown_items.dm
+++ b/yogstation/code/game/objects/items/clown_items.dm
@@ -24,7 +24,12 @@
name = "sad horn"
desc = "Thank you, Doktor."
attack_verb = list("Boowomped")
+ funny = FALSE
/obj/item/bikehorn/sad/Initialize()
. = ..()
AddComponent(/datum/component/squeak, list('yogstation/sound/items/boowomp.ogg'=1), 50)
+
+/obj/item/bikehorn/sad/attack(mob/living/carbon/M, mob/living/carbon/user)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "boowomp", /datum/mood_event/boowomp) ///because it is a sad horn!
+ return ..()
\ No newline at end of file
From 7f26672d4b6ee1345dcfc678cf75ccdb25ae2fbf Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Mon, 27 Jun 2022 16:01:51 +0300
Subject: [PATCH 08/55] e
---
code/datums/mood_events/generic_negative_events.dm | 5 -----
code/game/objects/items/clown_items.dm | 4 +---
yogstation/code/game/objects/items/clown_items.dm | 4 ----
3 files changed, 1 insertion(+), 12 deletions(-)
diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index 7079d65816ca..e5fc41d754e2 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -221,8 +221,3 @@
/datum/mood_event/surgery
description = "HE'S CUTTING ME OPEN!!\n"
mood_change = -8
-
-/datum/mood_event/boowomp
- description = "I've been boowomped.\n"
- mood_change = -1
- timeout = 4 MINUTES
\ No newline at end of file
diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm
index 300a38322176..599ccff1d2c9 100644
--- a/code/game/objects/items/clown_items.dm
+++ b/code/game/objects/items/clown_items.dm
@@ -153,7 +153,6 @@
throw_speed = 3
throw_range = 7
attack_verb = list("HONKED")
- var/funny = TRUE
/obj/item/bikehorn/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
@@ -170,8 +169,7 @@
AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50)
/obj/item/bikehorn/attack(mob/living/carbon/M, mob/living/carbon/user)
- if(funny)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "honk", /datum/mood_event/honk)
return ..()
/obj/item/bikehorn/suicide_act(mob/user)
diff --git a/yogstation/code/game/objects/items/clown_items.dm b/yogstation/code/game/objects/items/clown_items.dm
index 52ef94d19346..a61ee950cdad 100644
--- a/yogstation/code/game/objects/items/clown_items.dm
+++ b/yogstation/code/game/objects/items/clown_items.dm
@@ -29,7 +29,3 @@
/obj/item/bikehorn/sad/Initialize()
. = ..()
AddComponent(/datum/component/squeak, list('yogstation/sound/items/boowomp.ogg'=1), 50)
-
-/obj/item/bikehorn/sad/attack(mob/living/carbon/M, mob/living/carbon/user)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "boowomp", /datum/mood_event/boowomp) ///because it is a sad horn!
- return ..()
\ No newline at end of file
From 4d2a2f36ae00b8a5b41bd1e7f2014a976ed180f5 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Mon, 27 Jun 2022 16:03:52 +0300
Subject: [PATCH 09/55] s
---
yogstation/code/game/objects/items/clown_items.dm | 1 -
1 file changed, 1 deletion(-)
diff --git a/yogstation/code/game/objects/items/clown_items.dm b/yogstation/code/game/objects/items/clown_items.dm
index a61ee950cdad..2a9fd7ba9756 100644
--- a/yogstation/code/game/objects/items/clown_items.dm
+++ b/yogstation/code/game/objects/items/clown_items.dm
@@ -24,7 +24,6 @@
name = "sad horn"
desc = "Thank you, Doktor."
attack_verb = list("Boowomped")
- funny = FALSE
/obj/item/bikehorn/sad/Initialize()
. = ..()
From f2a5fd35194618acf3a65b16a09cf4f13b4dfaaa Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Tue, 28 Jun 2022 21:54:10 +0300
Subject: [PATCH 10/55] s
---
code/__DEFINES/antagonists.dm | 2 +
code/_onclick/hud/blob_overmind.dm | 6 +-
code/_onclick/hud/radial.dm | 16 +++--
code/game/objects/effects/info.dm | 26 +++++++
.../blob/blobstrains/_blobstrain.dm | 2 +-
code/modules/antagonists/blob/overmind.dm | 4 ++
code/modules/antagonists/blob/powers.dm | 70 ++++++++++++++-----
7 files changed, 98 insertions(+), 28 deletions(-)
create mode 100644 code/game/objects/effects/info.dm
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index ccdc70876238..3e9067499976 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -124,3 +124,5 @@
#define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal))
#define IS_MONSTERHUNTER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/monsterhunter))
+/// How much does it cost to reroll strains?
+#define BLOB_REROLL_COST 40
\ No newline at end of file
diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm
index 5e352112f26b..bcb7856be825 100644
--- a/code/_onclick/hud/blob_overmind.dm
+++ b/code/_onclick/hud/blob_overmind.dm
@@ -93,17 +93,17 @@
/obj/screen/blob/ReadaptStrain
icon_state = "ui_chemswap"
- name = "Readapt Strain (40)"
+ name = "Readapt Strain"
desc = "Allows you to choose a new strain from 4 random choices for 40 resources."
/obj/screen/blob/ReadaptStrain/MouseEntered(location,control,params)
if(hud && hud.mymob && isovermind(hud.mymob))
var/mob/camera/blob/B = hud.mymob
if(B.free_strain_rerolls)
- name = "Readapt Strain (FREE)"
+ name = "[initial(name)] (FREE)"
desc = "Randomly rerolls your strain for free."
else
- name = initial(name)
+ name = "[initial(name)] ([BLOB_REROLL_COST])"
desc = initial(desc)
..()
diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm
index 85e3914b8513..926f117858bd 100644
--- a/code/_onclick/hud/radial.dm
+++ b/code/_onclick/hud/radial.dm
@@ -211,16 +211,20 @@ GLOBAL_LIST_EMPTY(radial_menus)
var/atom/movable/AM = choices_values[choice_id] //Movables only
E.name = AM.name
+ E.choice = choice_id
+ E.maptext = null
+ E.next_page = FALSE
+
if(choices_icons[choice_id])
E.add_overlay(choices_icons[choice_id])
- var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id]
- if(choice_datum && istext(choice_datum.info))
- E.desc = choice_datum.info
+ if (choice_datums[choice_id])
+ var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id]
+ if (choice_datum.info)
+ var/obj/effect/abstract/info/info_button = new(E, choice_datum.info)
+ info_button.layer = ABOVE_HUD_LAYER
+ E.vis_contents += info_button
- E.choice = choice_id
- E.maptext = null
- E.next_page = FALSE
/datum/radial_menu/New()
close_button = new
diff --git a/code/game/objects/effects/info.dm b/code/game/objects/effects/info.dm
new file mode 100644
index 000000000000..0c9e3abf252c
--- /dev/null
+++ b/code/game/objects/effects/info.dm
@@ -0,0 +1,26 @@
+/// An info button that, when clicked, puts some text in the user's chat
+/obj/effect/abstract/info
+ name = "info"
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "info"
+
+ /// What should the info button display when clicked?
+ var/info_text
+
+/obj/effect/abstract/info/Initialize(mapload, info_text)
+ . = ..()
+
+ if (!isnull(info_text))
+ src.info_text = info_text
+
+/obj/effect/abstract/info/Click()
+ . = ..()
+ to_chat(usr, info_text)
+
+/obj/effect/abstract/info/MouseEntered()
+ . = ..()
+ icon_state = "info_hovered"
+
+/obj/effect/abstract/info/MouseExited()
+ . = ..()
+ icon_state = initial(icon_state)
\ No newline at end of file
diff --git a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm
index ad439d962de2..a9fa8350e79b 100644
--- a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm
+++ b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm
@@ -8,7 +8,7 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/
var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects
var/effectdesc = null //any long, blob-tile specific effects
var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp."
- var/analyzerdesceffect = "N/A"
+ var/analyzerdesceffect
var/blobbernaut_message = "slams" //blobbernaut attack verb
var/message = "The blob strikes you" //message sent to any mob hit by the blob
var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt
diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm
index 9cc0c8df26a9..5b1639414f1e 100644
--- a/code/modules/antagonists/blob/overmind.dm
+++ b/code/modules/antagonists/blob/overmind.dm
@@ -44,6 +44,9 @@ GLOBAL_LIST_EMPTY(blob_nodes)
var/has_announced = FALSE
var/basemodifier = 1
+ /// The list of strains the blob can reroll for.
+ var/list/strain_choices
+
/mob/camera/blob/Initialize(mapload, starting_points = 60, pointmodifier = 1)
validate_location()
blob_points = starting_points
@@ -186,6 +189,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
BM.overmind = null
BM.update_icons()
GLOB.overminds -= src
+ QDEL_LIST_ASSOC_VAL(strain_choices)
SSshuttle.clearHostileEnvironment(src)
STOP_PROCESSING(SSobj, src)
diff --git a/code/modules/antagonists/blob/powers.dm b/code/modules/antagonists/blob/powers.dm
index 5a8110bfc7ca..1131e4017bf2 100644
--- a/code/modules/antagonists/blob/powers.dm
+++ b/code/modules/antagonists/blob/powers.dm
@@ -1,3 +1,6 @@
+#define BLOB_REROLL_CHOICES 6
+#define BLOB_REROLL_RADIUS 60
+
/mob/camera/blob/proc/can_buy(cost = 15)
if(blob_points < cost)
to_chat(src, span_warning("You cannot afford this, you need at least [cost] resources!"))
@@ -340,25 +343,53 @@
set category = "Blob"
set name = "Reactive Strain Adaptation (40)"
set desc = "Replaces your strain with a random, different one."
- if(!rerolling && (free_strain_rerolls || can_buy(40)))
- rerolling = TRUE
- reroll_strain()
- rerolling = FALSE
- if(free_strain_rerolls)
- free_strain_rerolls--
- last_reroll_time = world.time
-
-/mob/camera/blob/proc/reroll_strain()
- var/list/choices = list()
- while (length(choices) < 4)
- var/datum/blobstrain/bs = pick((GLOB.valid_blobstrains))
- choices[initial(bs.name)] = bs
-
- var/choice = input(usr, "Please choose a new strain","Strain") as anything in choices
- if (choice && choices[choice] && !QDELETED(src))
- var/datum/blobstrain/bs = choices[choice]
- set_strain(bs)
+ if (!free_strain_rerolls && blob_points < BLOB_REROLL_COST)
+ to_chat(src, "You need at least [BLOB_REROLL_COST] resources to reroll your strain again!")
+ return
+
+ open_reroll_menu()
+
+/// Open the menu to reroll strains
+/mob/camera/blob/proc/open_reroll_menu()
+ if (!strain_choices)
+ strain_choices = list()
+
+ var/list/new_strains = GLOB.valid_blobstrains.Copy()
+ for (var/_ in 1 to BLOB_REROLL_CHOICES)
+ var/datum/blobstrain/strain = pick_n_take(new_strains)
+
+ var/image/strain_icon = image('icons/mob/blob.dmi', "blob_core")
+ strain_icon.color = initial(strain.color)
+
+ var/info_text = "[initial(strain.name)]"
+ info_text += "
[initial(strain.analyzerdescdamage)]"
+ if (!isnull(initial(strain.analyzerdesceffect)))
+ info_text += "
[initial(strain.analyzerdesceffect)]"
+
+ var/datum/radial_menu_choice/choice = new
+ choice.image = strain_icon
+ choice.info = info_text
+
+ strain_choices[initial(strain.name)] = choice
+ var/strain_result = show_radial_menu(src, src, strain_choices, radius = BLOB_REROLL_RADIUS, tooltips = TRUE)
+ if (isnull(strain_result))
+ return
+
+ if (!free_strain_rerolls && !can_buy(BLOB_REROLL_COST))
+ return
+
+ for (var/_other_strain in GLOB.valid_blobstrains)
+ var/datum/blobstrain/other_strain = _other_strain
+ if (initial(other_strain.name) == strain_result)
+ set_strain(other_strain)
+
+ if (free_strain_rerolls)
+ free_strain_rerolls -= 1
+
+ last_reroll_time = world.time
+
+ return
/mob/camera/blob/verb/blob_help()
set category = "Blob"
@@ -383,3 +414,6 @@
if(!placed && autoplace_max_time <= world.time)
to_chat(src, span_big("You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)]."))
to_chat(src, span_big("You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen."))
+
+#undef BLOB_REROLL_CHOICES
+#undef BLOB_REROLL_RADIUS
\ No newline at end of file
From dfc5e8a49e6c48061fabff8ec95b0b2c6cbaf567 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Tue, 28 Jun 2022 22:28:51 +0300
Subject: [PATCH 11/55] 3
---
code/modules/antagonists/blob/structures/_blob.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm
index a65b79e33b41..68fdf4075658 100644
--- a/code/modules/antagonists/blob/structures/_blob.dm
+++ b/code/modules/antagonists/blob/structures/_blob.dm
@@ -244,7 +244,7 @@
if(overmind)
. += list("Material: [overmind.blobstrain.name][span_notice(".")]",
"Material Effects: [span_notice("[overmind.blobstrain.analyzerdescdamage]")]",
- "Material Properties: [span_notice("[overmind.blobstrain.analyzerdesceffect]")]")
+ "Material Properties: [overmind.blobstrain.analyzerdesceffect || "N/A"]")
else
. += "No Material Detected!"
From 7ae0659d568481d4c91a7364836c55ea34666ad4 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 14:45:05 +0300
Subject: [PATCH 12/55] rev
---
code/__DEFINES/role_preferences.dm | 1 +
code/controllers/subsystem/job.dm | 2 +
code/datums/mind.dm | 2 +
.../gamemodes/dynamic/dynamic_rulesets.dm | 5 -
.../dynamic/dynamic_rulesets_latejoin.dm | 58 ++----
.../dynamic/dynamic_rulesets_roundstart.dm | 51 +-----
code/modules/admin/antag_panel.dm | 2 +-
.../antagonists/revolution/revolution.dm | 165 ++++++++++++++++--
code/modules/events/bureaucratic_error.dm | 18 +-
code/modules/jobs/job_types/_job.dm | 3 +
code/modules/jobs/job_types/ai.dm | 1 +
strings/anti_union_propaganda.txt | 4 +
12 files changed, 197 insertions(+), 115 deletions(-)
create mode 100644 strings/anti_union_propaganda.txt
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 07bb830ece9a..388bba808595 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -16,6 +16,7 @@
#define ROLE_MALF "Malf AI"
#define ROLE_REV "Revolutionary"
#define ROLE_REV_HEAD "Head Revolutionary"
+#define ROLE_REV_SUCCESSFUL "Victorious Revolutionary"
#define ROLE_ALIEN "Xenomorph"
#define ROLE_PAI "pAI"
#define ROLE_CULTIST "Cultist"
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index d0de6312dba6..fb921b14c20a 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -30,11 +30,13 @@ SUBSYSTEM_DEF(job)
var/datum/job/new_overflow = GetJob(new_overflow_role)
var/cap = CONFIG_GET(number/overflow_cap)
+ new_overflow.allow_bureaucratic_error = FALSE
new_overflow.spawn_positions = cap
new_overflow.total_positions = cap
if(new_overflow_role != overflow_role)
var/datum/job/old_overflow = GetJob(overflow_role)
+ old_overflow.allow_bureaucratic_error = initial(old_overflow.allow_bureaucratic_error)
old_overflow.spawn_positions = initial(old_overflow.spawn_positions)
old_overflow.total_positions = initial(old_overflow.total_positions)
overflow_role = new_overflow_role
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 43f063a24237..079ad25db409 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -88,6 +88,8 @@
var/afk_verb_used = FALSE
/// The timer for the afk verb
var/afk_verb_timer
+ /// A lazy list of statuses to add next to this mind in the traitor panel
+ var/list/special_statuses
/datum/mind/New(key)
src.key = key
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm
index efbab7a576eb..600e34fbb43a 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm
@@ -183,11 +183,6 @@
/// Only called if ruleset is flagged as HIGH_IMPACT_RULESET
/datum/dynamic_ruleset/proc/round_result()
-/// Checks if round is finished, return true to end the round.
-/// Only called if ruleset is flagged as HIGH_IMPACT_RULESET
-/datum/dynamic_ruleset/proc/check_finished()
- return FALSE
-
//////////////////////////////////////////////
// //
// ROUNDSTART RULESETS //
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
index 2cf8d95e5442..721a7f928d78 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
@@ -93,6 +93,8 @@
blocking_rules = list(/datum/dynamic_ruleset/roundstart/revs)
var/required_heads_of_staff = 3
var/finished = FALSE
+ /// How much threat should be injected when the revolution wins?
+ var/revs_win_threat_injection = 20
var/datum/team/revolution/revolution
/datum/dynamic_ruleset/latejoin/provocateur/ready(forced=FALSE)
@@ -119,7 +121,7 @@
new_head = M.mind.add_antag_datum(new_head, revolution)
revolution.update_objectives()
revolution.update_heads()
- SSshuttle.registerHostileEnvironment(src)
+ SSshuttle.registerHostileEnvironment(revolution)
return TRUE
else
log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.")
@@ -127,27 +129,12 @@
return FALSE
/datum/dynamic_ruleset/latejoin/provocateur/rule_process()
- if(check_rev_victory())
- finished = REVOLUTION_VICTORY
- return RULESET_STOP_PROCESSING
- else if (check_heads_victory())
- finished = STATION_VICTORY
- SSshuttle.clearHostileEnvironment(src)
- revolution.save_members()
- for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions.
- if(M.has_antag_datum(/datum/antagonist/rev/head))
- var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head)
- R.remove_revolutionary(FALSE, "gamemode")
- if(M.current)
- var/mob/living/carbon/C = M.current
- if(istype(C) && C.stat == DEAD)
- C.makeUncloneable()
- if(M.has_antag_datum(/datum/antagonist/rev))
- var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
- R.remove_revolutionary(FALSE, "gamemode")
- priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \
- We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division")
- return RULESET_STOP_PROCESSING
+ var/winner = revolution.process_victory(revs_win_threat_injection)
+ if (isnull(winner))
+ return
+
+ finished = winner
+ return RULESET_STOP_PROCESSING
@@ -158,33 +145,8 @@
return TRUE
return FALSE
-/datum/dynamic_ruleset/latejoin/provocateur/check_finished()
- if(finished == REVOLUTION_VICTORY)
- return TRUE
- else
- return ..()
-
-/datum/dynamic_ruleset/latejoin/provocateur/proc/check_rev_victory()
- for(var/datum/objective/mutiny/objective in revolution.objectives)
- if(!(objective.check_completion()))
- return FALSE
- return TRUE
-
-/datum/dynamic_ruleset/latejoin/provocateur/proc/check_heads_victory()
- for(var/datum/mind/rev_mind in revolution.head_revolutionaries())
- var/turf/T = get_turf(rev_mind.current)
- if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z))
- if(ishuman(rev_mind.current) || ismonkey(rev_mind.current))
- return FALSE
- return TRUE
-
/datum/dynamic_ruleset/latejoin/provocateur/round_result()
- if(finished == REVOLUTION_VICTORY)
- SSticker.mode_result = "win - heads killed"
- SSticker.news_report = REVS_WIN
- else if(finished == STATION_VICTORY)
- SSticker.mode_result = "loss - rev heads killed"
- SSticker.news_report = REVS_LOSE
+ revolution.round_result(finished)
//////////////////////////////////////////////
// //
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index 6f75591d5968..a472e53b9cf3 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -410,7 +410,7 @@
if(revolution.members.len)
revolution.update_objectives()
revolution.update_heads()
- SSshuttle.registerHostileEnvironment(src)
+ SSshuttle.registerHostileEnvironment(revolution)
return TRUE
log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.")
return FALSE
@@ -420,30 +420,12 @@
..()
/datum/dynamic_ruleset/roundstart/revs/rule_process()
- if(!revolution)
- log_game("DYNAMIC: Something went horrifically wrong with [name] - and the antag datum could not be created. Notify coders.")
+ var/winner = revolution.process_victory(revs_win_threat_injection)
+ if (isnull(winner))
return
- if(check_rev_victory())
- finished = REVOLUTION_VICTORY
- return RULESET_STOP_PROCESSING
- else if (check_heads_victory())
- finished = STATION_VICTORY
- SSshuttle.clearHostileEnvironment(src)
- revolution.save_members()
- for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions.
- if(M.has_antag_datum(/datum/antagonist/rev/head))
- var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head)
- R.remove_revolutionary(FALSE, "gamemode")
- if(M.current)
- var/mob/living/carbon/C = M.current
- if(istype(C) && C.stat == DEAD)
- C.makeUncloneable()
- if(M.has_antag_datum(/datum/antagonist/rev))
- var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
- R.remove_revolutionary(FALSE, "gamemode")
- priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \
- We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division")
- return RULESET_STOP_PROCESSING
+
+ finished = winner
+ return RULESET_STOP_PROCESSING
/// Checks for revhead loss conditions and other antag datums.
/datum/dynamic_ruleset/roundstart/revs/proc/check_eligible(var/datum/mind/M)
@@ -458,27 +440,8 @@
else
return ..()
-/datum/dynamic_ruleset/roundstart/revs/proc/check_rev_victory()
- for(var/datum/objective/mutiny/objective in revolution.objectives)
- if(!(objective.check_completion()))
- return FALSE
- return TRUE
-
-/datum/dynamic_ruleset/roundstart/revs/proc/check_heads_victory()
- for(var/datum/mind/rev_mind in revolution.head_revolutionaries())
- var/turf/T = get_turf(rev_mind.current)
- if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z))
- if(ishuman(rev_mind.current) || ismonkey(rev_mind.current))
- return FALSE
- return TRUE
-
/datum/dynamic_ruleset/roundstart/revs/round_result()
- if(finished == REVOLUTION_VICTORY)
- SSticker.mode_result = "win - heads killed"
- SSticker.news_report = REVS_WIN
- else if(finished == STATION_VICTORY)
- SSticker.mode_result = "loss - rev heads killed"
- SSticker.news_report = REVS_LOSE
+ revolution.round_result(finished)
// Admin only rulesets. The threat requirement is 101 so it is not possible to roll them.
diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm
index a41a7ff229b1..12254c2e155d 100644
--- a/code/modules/admin/antag_panel.dm
+++ b/code/modules/admin/antag_panel.dm
@@ -78,7 +78,7 @@ GLOBAL_VAR(antag_prototypes)
return common_commands
/datum/mind/proc/get_special_statuses()
- var/list/result = list()
+ var/list/result = LAZYCOPY(special_statuses)
if(!current)
result += span_bad("No body!")
if(current && HAS_TRAIT(current, TRAIT_MINDSHIELD))
diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm
index ebb9aa0d6066..7f4da5843334 100644
--- a/code/modules/antagonists/revolution/revolution.dm
+++ b/code/modules/antagonists/revolution/revolution.dm
@@ -1,3 +1,5 @@
+#define DECONVERTER_STATION_WIN "gamemode_station_win"
+#define DECONVERTER_REVS_WIN "gamemode_revs_win"
//How often to check for promotion possibility
#define HEAD_UPDATE_PERIOD 300
@@ -10,6 +12,9 @@
var/hud_type = "rev"
var/datum/team/revolution/rev_team
+ /// What message should the player receive when they are being demoted, and the revolution has won?
+ var/victory_message = "The revolution has overpowered the command staff! Viva la revolution! Execute any head of staff and security should you find them alive."
+
/datum/antagonist/rev/can_be_owned(datum/mind/new_owner)
. = ..()
if(.)
@@ -209,7 +214,22 @@
new_rev.silent = FALSE
to_chat(old_owner, span_userdanger("Revolution has been disappointed of your leader traits! You are a regular revolutionary now!"))
+/// Checks if the revolution succeeded, and lets them know.
+/datum/antagonist/rev/proc/announce_victorious()
+ . = rev_team.check_rev_victory()
+
+ if (!.)
+ return
+
+ to_chat(owner, "[victory_message]")
+ var/policy = get_policy(ROLE_REV_SUCCESSFUL)
+ if (policy)
+ to_chat(owner, policy)
+
/datum/antagonist/rev/farewell()
+ if (announce_victorious())
+ return
+
if(ishuman(owner.current) || ismonkey(owner.current))
owner.current.visible_message("[span_deconversion_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!")]", null, null, null, owner.current)
to_chat(owner, span_userdanger("You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you..."))
@@ -223,13 +243,13 @@
if(borged)
message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]")
owner.special_role = null
- if(iscarbon(owner.current))
+ if(iscarbon(owner.current) && deconverter != DECONVERTER_REVS_WIN)
var/mob/living/carbon/C = owner.current
C.Unconscious(100)
owner.remove_antag_datum(type)
/datum/antagonist/rev/head/remove_revolutionary(borged,deconverter)
- if(borged || deconverter == "gamemode")
+ if(borged || deconverter == DECONVERTER_STATION_WIN || deconverter == DECONVERTER_REVS_WIN)
. = ..()
/datum/antagonist/rev/head/equip_rev()
@@ -259,6 +279,22 @@
S.Insert(H, special = FALSE, drop_if_replaced = FALSE)
to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.")
+/// "Enemy of the Revolutionary", given to heads and security when the revolution wins
+/datum/antagonist/revolution_enemy
+ name = "Enemy of the Revolution"
+ show_in_antagpanel = FALSE
+
+/datum/antagonist/revolution_enemy/on_gain()
+ owner.special_role = "revolution enemy"
+
+ var/datum/objective/survive/survive = new /datum/objective/survive
+ survive.owner = owner
+ survive.explanation_text = "The station has been overrun by revolutionaries, stay alive until the end."
+ objectives += survive
+
+ return ..()
+
+
/datum/antagonist/rev/head/on_gain()
. = ..()
company = /datum/corporation/bolsynpowell
@@ -327,6 +363,101 @@
ex_headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE)
ex_revs = get_antag_minds(/datum/antagonist/rev, TRUE)
+/// Checks if revs have won
+/datum/team/revolution/proc/check_rev_victory()
+ for(var/datum/objective/mutiny/objective in objectives)
+ if(!(objective.check_completion()))
+ return FALSE
+ return TRUE
+
+/// Checks if heads have won
+/datum/team/revolution/proc/check_heads_victory()
+ for(var/datum/mind/rev_mind in head_revolutionaries())
+ var/turf/rev_turf = get_turf(rev_mind.current)
+ if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(rev_turf.z))
+ if(ishuman(rev_mind.current))
+ return FALSE
+ return TRUE
+
+/// Updates the state of the world depending on if revs won or loss.
+/// Returns who won, at which case this method should no longer be called.
+/// If revs_win_injection_amount is passed, then that amount of threat will be added if the revs win.
+/datum/team/revolution/proc/process_victory(revs_win_injection_amount)
+ if (check_rev_victory())
+ . = REVOLUTION_VICTORY
+ else if (check_heads_victory())
+ . = STATION_VICTORY
+ else
+ return
+
+ SSshuttle.clearHostileEnvironment(src)
+ save_members()
+
+ // Remove everyone as a revolutionary
+ for (var/_rev_mind in members)
+ var/datum/mind/rev_mind = _rev_mind
+ if (rev_mind.has_antag_datum(/datum/antagonist/rev))
+ var/datum/antagonist/rev/rev_antag = rev_mind.has_antag_datum(/datum/antagonist/rev)
+ rev_antag.remove_revolutionary(FALSE, . == STATION_VICTORY ? DECONVERTER_STATION_WIN : DECONVERTER_REVS_WIN)
+ LAZYADD(rev_mind.special_statuses, "Former [(rev_mind in ex_headrevs) ? "head revolutionary" : "revolutionary"]")
+
+ if (. == STATION_VICTORY)
+ // If the revolution was quelled, make rev heads unable to be revived through pods
+ for (var/_rev_head_mind in ex_revs)
+ var/datum/mind/rev_head_mind = _rev_head_mind
+ var/mob/living/carbon/rev_head_body = rev_head_mind.current
+ if(istype(rev_head_body) && rev_head_body.stat == DEAD)
+ rev_head_body.makeUncloneable()
+
+ priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \
+ We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division")
+ else
+ for (var/_player in GLOB.player_list)
+ var/mob/player = _player
+ var/datum/mind/mind = player.mind
+
+ if (isnull(mind))
+ continue
+
+ if (!(mind.assigned_role in GLOB.command_positions + GLOB.security_positions))
+ continue
+
+ var/mob/living/carbon/target_body = mind.current
+
+ mind.add_antag_datum(/datum/antagonist/revolution_enemy)
+
+ if (!istype(target_body))
+ continue
+
+ if (target_body.stat == DEAD)
+ target_body.makeUncloneable()
+ else
+ mind.announce_objectives()
+
+ for (var/job_name in GLOB.command_positions + GLOB.security_positions)
+ var/datum/job/job = SSjob.GetJob(job_name)
+ job.allow_bureaucratic_error = FALSE
+ job.total_positions = 0
+
+ if (revs_win_injection_amount)
+ var/datum/game_mode/dynamic/dynamic = SSticker.mode
+ dynamic.create_threat(revs_win_injection_amount)
+ dynamic.threat_log += "[worldtime2text()]: Revolution victory. Added [revs_win_injection_amount] threat."
+
+ priority_announce("A recent assessment of your station has marked your station as a severe risk area for high ranking Nanotrasen officials. \
+ For the safety of our staff, we have blacklisted your station for new employment of security and command. \
+ [pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division")
+
+/// Mutates the ticker to report that the revs have won
+/datum/team/revolution/proc/round_result(finished)
+ if (finished == REVOLUTION_VICTORY)
+ SSticker.mode_result = "win - heads killed"
+ SSticker.news_report = REVS_WIN
+ else if (finished == STATION_VICTORY)
+ SSticker.mode_result = "loss - rev heads killed"
+ SSticker.news_report = REVS_LOSE
+
+
/datum/team/revolution/proc/check_victory()
for(var/datum/objective/O in objectives)
if(!O.check_completion())
@@ -341,18 +472,6 @@
result += "
"
- var/num_revs = 0
- var/num_survivors = 0
- for(var/mob/living/carbon/survivor in GLOB.alive_mob_list)
- if(survivor.ckey)
- num_survivors++
- if(survivor.mind)
- if(is_revolutionary(survivor))
- num_revs++
- if(num_survivors)
- result += "Command's Approval Rating:
[100 - round((num_revs/num_survivors)*100, 0.1)]%"
-
-
var/list/targets = list()
var/list/datum/mind/headrevs
var/list/datum/mind/revs
@@ -365,6 +484,17 @@
revs = ex_revs
else
revs = get_antag_minds(/datum/antagonist/rev, TRUE)
+
+ var/num_revs = 0
+ var/num_survivors = 0
+ for(var/mob/living/carbon/survivor in GLOB.alive_mob_list)
+ if(survivor.ckey)
+ num_survivors += 1
+ if ((survivor.mind in revs) || (survivor.mind in headrevs))
+ num_revs += 1
+
+ if(num_survivors)
+ result += "Command's Approval Rating:
[100 - round((num_revs/num_survivors)*100, 0.1)]%"
if(check_victory())
for(var/H in revs)
@@ -376,13 +506,13 @@
if(headrevs.len)
var/list/headrev_part = list()
headrev_part += span_header("The head revolutionaries were:")
- headrev_part += printplayerlist(headrevs,TRUE)
+ headrev_part += printplayerlist(headrevs, !check_rev_victory())
result += headrev_part.Join("
")
if(revs.len)
var/list/rev_part = list()
rev_part += span_header("The revolutionaries were:")
- rev_part += printplayerlist(revs,TRUE)
+ rev_part += printplayerlist(revs, !check_rev_victory())
result += rev_part.Join("
")
var/list/heads = SSjob.get_all_heads()
@@ -435,3 +565,6 @@
/datum/team/revolution/is_gamemode_hero()
return SSticker.mode.name == "revolution"
+
+#undef DECONVERTER_STATION_WIN
+#undef DECONVERTER_REVS_WIN
\ No newline at end of file
diff --git a/code/modules/events/bureaucratic_error.dm b/code/modules/events/bureaucratic_error.dm
index 64919c6818b8..0f5c42391fb3 100644
--- a/code/modules/events/bureaucratic_error.dm
+++ b/code/modules/events/bureaucratic_error.dm
@@ -12,4 +12,20 @@
priority_announce("A recent bureaucratic error in the Organic Resources Department may result in personnel shortages in some departments and redundant staffing in others.", "Paperwork Mishap Alert")
/datum/round_event/bureaucratic_error/start()
- SSjob.set_overflow_role(pick(get_all_jobs()))
+ var/list/jobs = SSjob.occupations.Copy()
+ if(prob(33)) // Only allows latejoining as a single role. Add latejoin AI bluespace pods for fun later.
+ var/datum/job/overflow = pick_n_take(jobs)
+ overflow.spawn_positions = -1
+ overflow.total_positions = -1 // Ensures infinite slots as this role. Assistant will still be open for those that cant play it.
+ for(var/job in jobs)
+ var/datum/job/current = job
+ if(!current.allow_bureaucratic_error)
+ continue
+ current.total_positions = 0
+ else // Adds/removes a random amount of job slots from all jobs.
+ for(var/job in jobs)
+ var/datum/job/current = job
+ if(!current.allow_bureaucratic_error)
+ continue
+ var/ran = rand(-2,4)
+ current.total_positions = max(current.total_positions + ran, 0)
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index c85904d4a217..7484d34cd1ac 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -70,6 +70,9 @@
var/list/changed_maps = list() // Maps on which the job is changed. Should use the same name as the mapping config
+ /// Should this job be allowed to be picked for the bureaucratic error event?
+ var/allow_bureaucratic_error = TRUE
+
/*
If you want to change a job on a specific map with this system, you will want to go onto that job datum
and add said map's name to the changed_maps list, like so:
diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm
index fe094589de30..3cdc17b738db 100644
--- a/code/modules/jobs/job_types/ai.dm
+++ b/code/modules/jobs/job_types/ai.dm
@@ -12,6 +12,7 @@
minimal_player_age = 30
exp_requirements = 180
exp_type = EXP_TYPE_CREW
+ allow_bureaucratic_error = FALSE
exp_type_department = EXP_TYPE_SILICON
display_order = JOB_DISPLAY_ORDER_AI
var/do_special_check = TRUE
diff --git a/strings/anti_union_propaganda.txt b/strings/anti_union_propaganda.txt
new file mode 100644
index 000000000000..e1e6f68721a1
--- /dev/null
+++ b/strings/anti_union_propaganda.txt
@@ -0,0 +1,4 @@
+Remember, union dues cost around 70,000 credits a year. A new video game system with the latest hits sounds like fun. Put your money towards that instead of paying dues to the union.
+Remember, tickets & food to the Toolbox Tournament aren't cheap. That money in union dues you'd be paying every year could sure go a long way.
+Remember, nothing's more enjoyable than a night out watching a thunderdome match with your buddies. All those union dues you pay every year could buy a few rounds.
+Nanotrasen's open door policy is designed to help you feel comfortable taking up issues to your assigned head of staff. It's hard for us to maintain this when they're dead.
\ No newline at end of file
From 42f71b8d8217a4050b27af40bbb6489491791d30 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 14:57:02 +0300
Subject: [PATCH 13/55] Update antagonists.dm
---
code/__DEFINES/antagonists.dm | 3 ---
1 file changed, 3 deletions(-)
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index 3e9067499976..3bb45151bb3b 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -123,6 +123,3 @@
#define IS_BLOODSUCKER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/bloodsucker))
#define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal))
#define IS_MONSTERHUNTER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/monsterhunter))
-
-/// How much does it cost to reroll strains?
-#define BLOB_REROLL_COST 40
\ No newline at end of file
From 55a1411206fcf4234e4da47a3aa844c743f2448d Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:00:38 +0300
Subject: [PATCH 14/55] Update blob_overmind.dm
---
code/_onclick/hud/blob_overmind.dm | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm
index bcb7856be825..e028a89b4772 100644
--- a/code/_onclick/hud/blob_overmind.dm
+++ b/code/_onclick/hud/blob_overmind.dm
@@ -93,17 +93,17 @@
/obj/screen/blob/ReadaptStrain
icon_state = "ui_chemswap"
- name = "Readapt Strain"
+ name = "Readapt Strain (40)"
desc = "Allows you to choose a new strain from 4 random choices for 40 resources."
/obj/screen/blob/ReadaptStrain/MouseEntered(location,control,params)
if(hud && hud.mymob && isovermind(hud.mymob))
var/mob/camera/blob/B = hud.mymob
if(B.free_strain_rerolls)
- name = "[initial(name)] (FREE)"
+ name = "Readapt Strain (FREE)"
desc = "Randomly rerolls your strain for free."
else
- name = "[initial(name)] ([BLOB_REROLL_COST])"
+ name = initial(name)
desc = initial(desc)
..()
@@ -174,4 +174,4 @@
using = new /obj/screen/blob/RelocateCore()
using.screen_loc = ui_storage2
- static_inventory += using
\ No newline at end of file
+ static_inventory += using
From dd6e91b03bdb001e35a2ee0b2be2fda6923a9136 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:00:58 +0300
Subject: [PATCH 15/55] Update radial.dm
---
code/_onclick/hud/radial.dm | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm
index 926f117858bd..85e3914b8513 100644
--- a/code/_onclick/hud/radial.dm
+++ b/code/_onclick/hud/radial.dm
@@ -211,20 +211,16 @@ GLOBAL_LIST_EMPTY(radial_menus)
var/atom/movable/AM = choices_values[choice_id] //Movables only
E.name = AM.name
- E.choice = choice_id
- E.maptext = null
- E.next_page = FALSE
-
if(choices_icons[choice_id])
E.add_overlay(choices_icons[choice_id])
- if (choice_datums[choice_id])
- var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id]
- if (choice_datum.info)
- var/obj/effect/abstract/info/info_button = new(E, choice_datum.info)
- info_button.layer = ABOVE_HUD_LAYER
- E.vis_contents += info_button
+ var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id]
+ if(choice_datum && istext(choice_datum.info))
+ E.desc = choice_datum.info
+ E.choice = choice_id
+ E.maptext = null
+ E.next_page = FALSE
/datum/radial_menu/New()
close_button = new
From 0ac0cb4d0cd4ff8395aab39dff0341180b34bdbf Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:01:11 +0300
Subject: [PATCH 16/55] Delete info.dm
---
code/game/objects/effects/info.dm | 26 --------------------------
1 file changed, 26 deletions(-)
delete mode 100644 code/game/objects/effects/info.dm
diff --git a/code/game/objects/effects/info.dm b/code/game/objects/effects/info.dm
deleted file mode 100644
index 0c9e3abf252c..000000000000
--- a/code/game/objects/effects/info.dm
+++ /dev/null
@@ -1,26 +0,0 @@
-/// An info button that, when clicked, puts some text in the user's chat
-/obj/effect/abstract/info
- name = "info"
- icon = 'icons/effects/effects.dmi'
- icon_state = "info"
-
- /// What should the info button display when clicked?
- var/info_text
-
-/obj/effect/abstract/info/Initialize(mapload, info_text)
- . = ..()
-
- if (!isnull(info_text))
- src.info_text = info_text
-
-/obj/effect/abstract/info/Click()
- . = ..()
- to_chat(usr, info_text)
-
-/obj/effect/abstract/info/MouseEntered()
- . = ..()
- icon_state = "info_hovered"
-
-/obj/effect/abstract/info/MouseExited()
- . = ..()
- icon_state = initial(icon_state)
\ No newline at end of file
From d4bdf34f3c15c529bcb70e8f9581db2387c30d4e Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:01:52 +0300
Subject: [PATCH 17/55] Update overmind.dm
---
code/modules/antagonists/blob/overmind.dm | 2 --
1 file changed, 2 deletions(-)
diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm
index 5b1639414f1e..2efd527ae5e0 100644
--- a/code/modules/antagonists/blob/overmind.dm
+++ b/code/modules/antagonists/blob/overmind.dm
@@ -44,8 +44,6 @@ GLOBAL_LIST_EMPTY(blob_nodes)
var/has_announced = FALSE
var/basemodifier = 1
- /// The list of strains the blob can reroll for.
- var/list/strain_choices
/mob/camera/blob/Initialize(mapload, starting_points = 60, pointmodifier = 1)
validate_location()
From 5fc36bff4ecfc074ba097c0f5944aee39fb6d45c Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:02:13 +0300
Subject: [PATCH 18/55] Update overmind.dm
---
code/modules/antagonists/blob/overmind.dm | 2 --
1 file changed, 2 deletions(-)
diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm
index 2efd527ae5e0..9cc0c8df26a9 100644
--- a/code/modules/antagonists/blob/overmind.dm
+++ b/code/modules/antagonists/blob/overmind.dm
@@ -44,7 +44,6 @@ GLOBAL_LIST_EMPTY(blob_nodes)
var/has_announced = FALSE
var/basemodifier = 1
-
/mob/camera/blob/Initialize(mapload, starting_points = 60, pointmodifier = 1)
validate_location()
blob_points = starting_points
@@ -187,7 +186,6 @@ GLOBAL_LIST_EMPTY(blob_nodes)
BM.overmind = null
BM.update_icons()
GLOB.overminds -= src
- QDEL_LIST_ASSOC_VAL(strain_choices)
SSshuttle.clearHostileEnvironment(src)
STOP_PROCESSING(SSobj, src)
From a2838367dcea232fc8843dc87b87ac6f1f591636 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:03:44 +0300
Subject: [PATCH 19/55] Update powers.dm
---
code/modules/antagonists/blob/powers.dm | 70 +++++++------------------
1 file changed, 18 insertions(+), 52 deletions(-)
diff --git a/code/modules/antagonists/blob/powers.dm b/code/modules/antagonists/blob/powers.dm
index 1131e4017bf2..5a8110bfc7ca 100644
--- a/code/modules/antagonists/blob/powers.dm
+++ b/code/modules/antagonists/blob/powers.dm
@@ -1,6 +1,3 @@
-#define BLOB_REROLL_CHOICES 6
-#define BLOB_REROLL_RADIUS 60
-
/mob/camera/blob/proc/can_buy(cost = 15)
if(blob_points < cost)
to_chat(src, span_warning("You cannot afford this, you need at least [cost] resources!"))
@@ -343,53 +340,25 @@
set category = "Blob"
set name = "Reactive Strain Adaptation (40)"
set desc = "Replaces your strain with a random, different one."
- if (!free_strain_rerolls && blob_points < BLOB_REROLL_COST)
- to_chat(src, "
You need at least [BLOB_REROLL_COST] resources to reroll your strain again!")
- return
-
- open_reroll_menu()
-
-/// Open the menu to reroll strains
-/mob/camera/blob/proc/open_reroll_menu()
- if (!strain_choices)
- strain_choices = list()
-
- var/list/new_strains = GLOB.valid_blobstrains.Copy()
- for (var/_ in 1 to BLOB_REROLL_CHOICES)
- var/datum/blobstrain/strain = pick_n_take(new_strains)
-
- var/image/strain_icon = image('icons/mob/blob.dmi', "blob_core")
- strain_icon.color = initial(strain.color)
-
- var/info_text = "
[initial(strain.name)]"
- info_text += "
[initial(strain.analyzerdescdamage)]"
- if (!isnull(initial(strain.analyzerdesceffect)))
- info_text += "
[initial(strain.analyzerdesceffect)]"
-
- var/datum/radial_menu_choice/choice = new
- choice.image = strain_icon
- choice.info = info_text
-
- strain_choices[initial(strain.name)] = choice
+ if(!rerolling && (free_strain_rerolls || can_buy(40)))
+ rerolling = TRUE
+ reroll_strain()
+ rerolling = FALSE
+ if(free_strain_rerolls)
+ free_strain_rerolls--
+ last_reroll_time = world.time
+
+/mob/camera/blob/proc/reroll_strain()
+ var/list/choices = list()
+ while (length(choices) < 4)
+ var/datum/blobstrain/bs = pick((GLOB.valid_blobstrains))
+ choices[initial(bs.name)] = bs
+
+ var/choice = input(usr, "Please choose a new strain","Strain") as anything in choices
+ if (choice && choices[choice] && !QDELETED(src))
+ var/datum/blobstrain/bs = choices[choice]
+ set_strain(bs)
- var/strain_result = show_radial_menu(src, src, strain_choices, radius = BLOB_REROLL_RADIUS, tooltips = TRUE)
- if (isnull(strain_result))
- return
-
- if (!free_strain_rerolls && !can_buy(BLOB_REROLL_COST))
- return
-
- for (var/_other_strain in GLOB.valid_blobstrains)
- var/datum/blobstrain/other_strain = _other_strain
- if (initial(other_strain.name) == strain_result)
- set_strain(other_strain)
-
- if (free_strain_rerolls)
- free_strain_rerolls -= 1
-
- last_reroll_time = world.time
-
- return
/mob/camera/blob/verb/blob_help()
set category = "Blob"
@@ -414,6 +383,3 @@
if(!placed && autoplace_max_time <= world.time)
to_chat(src, span_big("
You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)]."))
to_chat(src, span_big("
You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen."))
-
-#undef BLOB_REROLL_CHOICES
-#undef BLOB_REROLL_RADIUS
\ No newline at end of file
From 172019b8de767740e8aa751c7279a575ff66f1de Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:24:53 +0300
Subject: [PATCH 20/55] Update role_preferences.dm
---
code/__DEFINES/role_preferences.dm | 1 -
1 file changed, 1 deletion(-)
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 388bba808595..07bb830ece9a 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -16,7 +16,6 @@
#define ROLE_MALF "Malf AI"
#define ROLE_REV "Revolutionary"
#define ROLE_REV_HEAD "Head Revolutionary"
-#define ROLE_REV_SUCCESSFUL "Victorious Revolutionary"
#define ROLE_ALIEN "Xenomorph"
#define ROLE_PAI "pAI"
#define ROLE_CULTIST "Cultist"
From e329b12815170e18d8bd0067a3f208b0b741173e Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:25:31 +0300
Subject: [PATCH 21/55] Update job.dm
---
code/controllers/subsystem/job.dm | 2 --
1 file changed, 2 deletions(-)
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index fb921b14c20a..d0de6312dba6 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -30,13 +30,11 @@ SUBSYSTEM_DEF(job)
var/datum/job/new_overflow = GetJob(new_overflow_role)
var/cap = CONFIG_GET(number/overflow_cap)
- new_overflow.allow_bureaucratic_error = FALSE
new_overflow.spawn_positions = cap
new_overflow.total_positions = cap
if(new_overflow_role != overflow_role)
var/datum/job/old_overflow = GetJob(overflow_role)
- old_overflow.allow_bureaucratic_error = initial(old_overflow.allow_bureaucratic_error)
old_overflow.spawn_positions = initial(old_overflow.spawn_positions)
old_overflow.total_positions = initial(old_overflow.total_positions)
overflow_role = new_overflow_role
From 5515ca0ba09d9e78fe0d7f58458bccf196030341 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:26:35 +0300
Subject: [PATCH 22/55] Update mind.dm
---
code/datums/mind.dm | 2 --
1 file changed, 2 deletions(-)
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 079ad25db409..43f063a24237 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -88,8 +88,6 @@
var/afk_verb_used = FALSE
/// The timer for the afk verb
var/afk_verb_timer
- /// A lazy list of statuses to add next to this mind in the traitor panel
- var/list/special_statuses
/datum/mind/New(key)
src.key = key
From f01a65e4acceca5ab1026ea88789c27a09c06c53 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:26:59 +0300
Subject: [PATCH 23/55] Update dynamic_rulesets.dm
---
code/game/gamemodes/dynamic/dynamic_rulesets.dm | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm
index 600e34fbb43a..efbab7a576eb 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm
@@ -183,6 +183,11 @@
/// Only called if ruleset is flagged as HIGH_IMPACT_RULESET
/datum/dynamic_ruleset/proc/round_result()
+/// Checks if round is finished, return true to end the round.
+/// Only called if ruleset is flagged as HIGH_IMPACT_RULESET
+/datum/dynamic_ruleset/proc/check_finished()
+ return FALSE
+
//////////////////////////////////////////////
// //
// ROUNDSTART RULESETS //
From 986a19999755448af2eafbcbca9a813c6f0a6f35 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:27:36 +0300
Subject: [PATCH 24/55] Update dynamic_rulesets_latejoin.dm
---
.../dynamic/dynamic_rulesets_latejoin.dm | 58 +++++++++++++++----
1 file changed, 48 insertions(+), 10 deletions(-)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
index 721a7f928d78..2cf8d95e5442 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
@@ -93,8 +93,6 @@
blocking_rules = list(/datum/dynamic_ruleset/roundstart/revs)
var/required_heads_of_staff = 3
var/finished = FALSE
- /// How much threat should be injected when the revolution wins?
- var/revs_win_threat_injection = 20
var/datum/team/revolution/revolution
/datum/dynamic_ruleset/latejoin/provocateur/ready(forced=FALSE)
@@ -121,7 +119,7 @@
new_head = M.mind.add_antag_datum(new_head, revolution)
revolution.update_objectives()
revolution.update_heads()
- SSshuttle.registerHostileEnvironment(revolution)
+ SSshuttle.registerHostileEnvironment(src)
return TRUE
else
log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.")
@@ -129,12 +127,27 @@
return FALSE
/datum/dynamic_ruleset/latejoin/provocateur/rule_process()
- var/winner = revolution.process_victory(revs_win_threat_injection)
- if (isnull(winner))
- return
-
- finished = winner
- return RULESET_STOP_PROCESSING
+ if(check_rev_victory())
+ finished = REVOLUTION_VICTORY
+ return RULESET_STOP_PROCESSING
+ else if (check_heads_victory())
+ finished = STATION_VICTORY
+ SSshuttle.clearHostileEnvironment(src)
+ revolution.save_members()
+ for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions.
+ if(M.has_antag_datum(/datum/antagonist/rev/head))
+ var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head)
+ R.remove_revolutionary(FALSE, "gamemode")
+ if(M.current)
+ var/mob/living/carbon/C = M.current
+ if(istype(C) && C.stat == DEAD)
+ C.makeUncloneable()
+ if(M.has_antag_datum(/datum/antagonist/rev))
+ var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
+ R.remove_revolutionary(FALSE, "gamemode")
+ priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \
+ We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division")
+ return RULESET_STOP_PROCESSING
@@ -145,8 +158,33 @@
return TRUE
return FALSE
+/datum/dynamic_ruleset/latejoin/provocateur/check_finished()
+ if(finished == REVOLUTION_VICTORY)
+ return TRUE
+ else
+ return ..()
+
+/datum/dynamic_ruleset/latejoin/provocateur/proc/check_rev_victory()
+ for(var/datum/objective/mutiny/objective in revolution.objectives)
+ if(!(objective.check_completion()))
+ return FALSE
+ return TRUE
+
+/datum/dynamic_ruleset/latejoin/provocateur/proc/check_heads_victory()
+ for(var/datum/mind/rev_mind in revolution.head_revolutionaries())
+ var/turf/T = get_turf(rev_mind.current)
+ if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z))
+ if(ishuman(rev_mind.current) || ismonkey(rev_mind.current))
+ return FALSE
+ return TRUE
+
/datum/dynamic_ruleset/latejoin/provocateur/round_result()
- revolution.round_result(finished)
+ if(finished == REVOLUTION_VICTORY)
+ SSticker.mode_result = "win - heads killed"
+ SSticker.news_report = REVS_WIN
+ else if(finished == STATION_VICTORY)
+ SSticker.mode_result = "loss - rev heads killed"
+ SSticker.news_report = REVS_LOSE
//////////////////////////////////////////////
// //
From a4bd274fb0c5fa4b8dc6bb56b14cbae2efa36eac Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:28:15 +0300
Subject: [PATCH 25/55] Update dynamic_rulesets_roundstart.dm
---
.../dynamic/dynamic_rulesets_roundstart.dm | 51 ++++++++++++++++---
1 file changed, 44 insertions(+), 7 deletions(-)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index a472e53b9cf3..6f75591d5968 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -410,7 +410,7 @@
if(revolution.members.len)
revolution.update_objectives()
revolution.update_heads()
- SSshuttle.registerHostileEnvironment(revolution)
+ SSshuttle.registerHostileEnvironment(src)
return TRUE
log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.")
return FALSE
@@ -420,12 +420,30 @@
..()
/datum/dynamic_ruleset/roundstart/revs/rule_process()
- var/winner = revolution.process_victory(revs_win_threat_injection)
- if (isnull(winner))
+ if(!revolution)
+ log_game("DYNAMIC: Something went horrifically wrong with [name] - and the antag datum could not be created. Notify coders.")
return
-
- finished = winner
- return RULESET_STOP_PROCESSING
+ if(check_rev_victory())
+ finished = REVOLUTION_VICTORY
+ return RULESET_STOP_PROCESSING
+ else if (check_heads_victory())
+ finished = STATION_VICTORY
+ SSshuttle.clearHostileEnvironment(src)
+ revolution.save_members()
+ for(var/datum/mind/M in revolution.members) // Remove antag datums and prevents podcloned or exiled headrevs restarting rebellions.
+ if(M.has_antag_datum(/datum/antagonist/rev/head))
+ var/datum/antagonist/rev/head/R = M.has_antag_datum(/datum/antagonist/rev/head)
+ R.remove_revolutionary(FALSE, "gamemode")
+ if(M.current)
+ var/mob/living/carbon/C = M.current
+ if(istype(C) && C.stat == DEAD)
+ C.makeUncloneable()
+ if(M.has_antag_datum(/datum/antagonist/rev))
+ var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
+ R.remove_revolutionary(FALSE, "gamemode")
+ priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \
+ We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division")
+ return RULESET_STOP_PROCESSING
/// Checks for revhead loss conditions and other antag datums.
/datum/dynamic_ruleset/roundstart/revs/proc/check_eligible(var/datum/mind/M)
@@ -440,8 +458,27 @@
else
return ..()
+/datum/dynamic_ruleset/roundstart/revs/proc/check_rev_victory()
+ for(var/datum/objective/mutiny/objective in revolution.objectives)
+ if(!(objective.check_completion()))
+ return FALSE
+ return TRUE
+
+/datum/dynamic_ruleset/roundstart/revs/proc/check_heads_victory()
+ for(var/datum/mind/rev_mind in revolution.head_revolutionaries())
+ var/turf/T = get_turf(rev_mind.current)
+ if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z))
+ if(ishuman(rev_mind.current) || ismonkey(rev_mind.current))
+ return FALSE
+ return TRUE
+
/datum/dynamic_ruleset/roundstart/revs/round_result()
- revolution.round_result(finished)
+ if(finished == REVOLUTION_VICTORY)
+ SSticker.mode_result = "win - heads killed"
+ SSticker.news_report = REVS_WIN
+ else if(finished == STATION_VICTORY)
+ SSticker.mode_result = "loss - rev heads killed"
+ SSticker.news_report = REVS_LOSE
// Admin only rulesets. The threat requirement is 101 so it is not possible to roll them.
From 32c0f01474214cd9849618d939720b057d8852d2 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:30:15 +0300
Subject: [PATCH 26/55] Update antag_panel.dm
---
code/modules/admin/antag_panel.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm
index 12254c2e155d..a41a7ff229b1 100644
--- a/code/modules/admin/antag_panel.dm
+++ b/code/modules/admin/antag_panel.dm
@@ -78,7 +78,7 @@ GLOBAL_VAR(antag_prototypes)
return common_commands
/datum/mind/proc/get_special_statuses()
- var/list/result = LAZYCOPY(special_statuses)
+ var/list/result = list()
if(!current)
result += span_bad("No body!")
if(current && HAS_TRAIT(current, TRAIT_MINDSHIELD))
From 3ade95a1ff2015eb2e18346f158ecb7bd215eb4d Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:31:09 +0300
Subject: [PATCH 27/55] Update revolution.dm
---
.../antagonists/revolution/revolution.dm | 165 ++----------------
1 file changed, 16 insertions(+), 149 deletions(-)
diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm
index 7f4da5843334..ebb9aa0d6066 100644
--- a/code/modules/antagonists/revolution/revolution.dm
+++ b/code/modules/antagonists/revolution/revolution.dm
@@ -1,5 +1,3 @@
-#define DECONVERTER_STATION_WIN "gamemode_station_win"
-#define DECONVERTER_REVS_WIN "gamemode_revs_win"
//How often to check for promotion possibility
#define HEAD_UPDATE_PERIOD 300
@@ -12,9 +10,6 @@
var/hud_type = "rev"
var/datum/team/revolution/rev_team
- /// What message should the player receive when they are being demoted, and the revolution has won?
- var/victory_message = "The revolution has overpowered the command staff! Viva la revolution! Execute any head of staff and security should you find them alive."
-
/datum/antagonist/rev/can_be_owned(datum/mind/new_owner)
. = ..()
if(.)
@@ -214,22 +209,7 @@
new_rev.silent = FALSE
to_chat(old_owner, span_userdanger("Revolution has been disappointed of your leader traits! You are a regular revolutionary now!"))
-/// Checks if the revolution succeeded, and lets them know.
-/datum/antagonist/rev/proc/announce_victorious()
- . = rev_team.check_rev_victory()
-
- if (!.)
- return
-
- to_chat(owner, "
[victory_message]")
- var/policy = get_policy(ROLE_REV_SUCCESSFUL)
- if (policy)
- to_chat(owner, policy)
-
/datum/antagonist/rev/farewell()
- if (announce_victorious())
- return
-
if(ishuman(owner.current) || ismonkey(owner.current))
owner.current.visible_message("[span_deconversion_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!")]", null, null, null, owner.current)
to_chat(owner, span_userdanger("You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you..."))
@@ -243,13 +223,13 @@
if(borged)
message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]")
owner.special_role = null
- if(iscarbon(owner.current) && deconverter != DECONVERTER_REVS_WIN)
+ if(iscarbon(owner.current))
var/mob/living/carbon/C = owner.current
C.Unconscious(100)
owner.remove_antag_datum(type)
/datum/antagonist/rev/head/remove_revolutionary(borged,deconverter)
- if(borged || deconverter == DECONVERTER_STATION_WIN || deconverter == DECONVERTER_REVS_WIN)
+ if(borged || deconverter == "gamemode")
. = ..()
/datum/antagonist/rev/head/equip_rev()
@@ -279,22 +259,6 @@
S.Insert(H, special = FALSE, drop_if_replaced = FALSE)
to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.")
-/// "Enemy of the Revolutionary", given to heads and security when the revolution wins
-/datum/antagonist/revolution_enemy
- name = "Enemy of the Revolution"
- show_in_antagpanel = FALSE
-
-/datum/antagonist/revolution_enemy/on_gain()
- owner.special_role = "revolution enemy"
-
- var/datum/objective/survive/survive = new /datum/objective/survive
- survive.owner = owner
- survive.explanation_text = "The station has been overrun by revolutionaries, stay alive until the end."
- objectives += survive
-
- return ..()
-
-
/datum/antagonist/rev/head/on_gain()
. = ..()
company = /datum/corporation/bolsynpowell
@@ -363,101 +327,6 @@
ex_headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE)
ex_revs = get_antag_minds(/datum/antagonist/rev, TRUE)
-/// Checks if revs have won
-/datum/team/revolution/proc/check_rev_victory()
- for(var/datum/objective/mutiny/objective in objectives)
- if(!(objective.check_completion()))
- return FALSE
- return TRUE
-
-/// Checks if heads have won
-/datum/team/revolution/proc/check_heads_victory()
- for(var/datum/mind/rev_mind in head_revolutionaries())
- var/turf/rev_turf = get_turf(rev_mind.current)
- if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(rev_turf.z))
- if(ishuman(rev_mind.current))
- return FALSE
- return TRUE
-
-/// Updates the state of the world depending on if revs won or loss.
-/// Returns who won, at which case this method should no longer be called.
-/// If revs_win_injection_amount is passed, then that amount of threat will be added if the revs win.
-/datum/team/revolution/proc/process_victory(revs_win_injection_amount)
- if (check_rev_victory())
- . = REVOLUTION_VICTORY
- else if (check_heads_victory())
- . = STATION_VICTORY
- else
- return
-
- SSshuttle.clearHostileEnvironment(src)
- save_members()
-
- // Remove everyone as a revolutionary
- for (var/_rev_mind in members)
- var/datum/mind/rev_mind = _rev_mind
- if (rev_mind.has_antag_datum(/datum/antagonist/rev))
- var/datum/antagonist/rev/rev_antag = rev_mind.has_antag_datum(/datum/antagonist/rev)
- rev_antag.remove_revolutionary(FALSE, . == STATION_VICTORY ? DECONVERTER_STATION_WIN : DECONVERTER_REVS_WIN)
- LAZYADD(rev_mind.special_statuses, "
Former [(rev_mind in ex_headrevs) ? "head revolutionary" : "revolutionary"]")
-
- if (. == STATION_VICTORY)
- // If the revolution was quelled, make rev heads unable to be revived through pods
- for (var/_rev_head_mind in ex_revs)
- var/datum/mind/rev_head_mind = _rev_head_mind
- var/mob/living/carbon/rev_head_body = rev_head_mind.current
- if(istype(rev_head_body) && rev_head_body.stat == DEAD)
- rev_head_body.makeUncloneable()
-
- priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \
- We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division")
- else
- for (var/_player in GLOB.player_list)
- var/mob/player = _player
- var/datum/mind/mind = player.mind
-
- if (isnull(mind))
- continue
-
- if (!(mind.assigned_role in GLOB.command_positions + GLOB.security_positions))
- continue
-
- var/mob/living/carbon/target_body = mind.current
-
- mind.add_antag_datum(/datum/antagonist/revolution_enemy)
-
- if (!istype(target_body))
- continue
-
- if (target_body.stat == DEAD)
- target_body.makeUncloneable()
- else
- mind.announce_objectives()
-
- for (var/job_name in GLOB.command_positions + GLOB.security_positions)
- var/datum/job/job = SSjob.GetJob(job_name)
- job.allow_bureaucratic_error = FALSE
- job.total_positions = 0
-
- if (revs_win_injection_amount)
- var/datum/game_mode/dynamic/dynamic = SSticker.mode
- dynamic.create_threat(revs_win_injection_amount)
- dynamic.threat_log += "[worldtime2text()]: Revolution victory. Added [revs_win_injection_amount] threat."
-
- priority_announce("A recent assessment of your station has marked your station as a severe risk area for high ranking Nanotrasen officials. \
- For the safety of our staff, we have blacklisted your station for new employment of security and command. \
- [pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division")
-
-/// Mutates the ticker to report that the revs have won
-/datum/team/revolution/proc/round_result(finished)
- if (finished == REVOLUTION_VICTORY)
- SSticker.mode_result = "win - heads killed"
- SSticker.news_report = REVS_WIN
- else if (finished == STATION_VICTORY)
- SSticker.mode_result = "loss - rev heads killed"
- SSticker.news_report = REVS_LOSE
-
-
/datum/team/revolution/proc/check_victory()
for(var/datum/objective/O in objectives)
if(!O.check_completion())
@@ -472,6 +341,18 @@
result += "
"
+ var/num_revs = 0
+ var/num_survivors = 0
+ for(var/mob/living/carbon/survivor in GLOB.alive_mob_list)
+ if(survivor.ckey)
+ num_survivors++
+ if(survivor.mind)
+ if(is_revolutionary(survivor))
+ num_revs++
+ if(num_survivors)
+ result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
"
+
+
var/list/targets = list()
var/list/datum/mind/headrevs
var/list/datum/mind/revs
@@ -484,17 +365,6 @@
revs = ex_revs
else
revs = get_antag_minds(/datum/antagonist/rev, TRUE)
-
- var/num_revs = 0
- var/num_survivors = 0
- for(var/mob/living/carbon/survivor in GLOB.alive_mob_list)
- if(survivor.ckey)
- num_survivors += 1
- if ((survivor.mind in revs) || (survivor.mind in headrevs))
- num_revs += 1
-
- if(num_survivors)
- result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
"
if(check_victory())
for(var/H in revs)
@@ -506,13 +376,13 @@
if(headrevs.len)
var/list/headrev_part = list()
headrev_part += span_header("The head revolutionaries were:")
- headrev_part += printplayerlist(headrevs, !check_rev_victory())
+ headrev_part += printplayerlist(headrevs,TRUE)
result += headrev_part.Join("
")
if(revs.len)
var/list/rev_part = list()
rev_part += span_header("The revolutionaries were:")
- rev_part += printplayerlist(revs, !check_rev_victory())
+ rev_part += printplayerlist(revs,TRUE)
result += rev_part.Join("
")
var/list/heads = SSjob.get_all_heads()
@@ -565,6 +435,3 @@
/datum/team/revolution/is_gamemode_hero()
return SSticker.mode.name == "revolution"
-
-#undef DECONVERTER_STATION_WIN
-#undef DECONVERTER_REVS_WIN
\ No newline at end of file
From 9152bcdebeb69f2d7db2ff6722adb240be35cd98 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:31:31 +0300
Subject: [PATCH 28/55] Update bureaucratic_error.dm
---
code/modules/events/bureaucratic_error.dm | 18 +-----------------
1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/code/modules/events/bureaucratic_error.dm b/code/modules/events/bureaucratic_error.dm
index 0f5c42391fb3..64919c6818b8 100644
--- a/code/modules/events/bureaucratic_error.dm
+++ b/code/modules/events/bureaucratic_error.dm
@@ -12,20 +12,4 @@
priority_announce("A recent bureaucratic error in the Organic Resources Department may result in personnel shortages in some departments and redundant staffing in others.", "Paperwork Mishap Alert")
/datum/round_event/bureaucratic_error/start()
- var/list/jobs = SSjob.occupations.Copy()
- if(prob(33)) // Only allows latejoining as a single role. Add latejoin AI bluespace pods for fun later.
- var/datum/job/overflow = pick_n_take(jobs)
- overflow.spawn_positions = -1
- overflow.total_positions = -1 // Ensures infinite slots as this role. Assistant will still be open for those that cant play it.
- for(var/job in jobs)
- var/datum/job/current = job
- if(!current.allow_bureaucratic_error)
- continue
- current.total_positions = 0
- else // Adds/removes a random amount of job slots from all jobs.
- for(var/job in jobs)
- var/datum/job/current = job
- if(!current.allow_bureaucratic_error)
- continue
- var/ran = rand(-2,4)
- current.total_positions = max(current.total_positions + ran, 0)
+ SSjob.set_overflow_role(pick(get_all_jobs()))
From 27d126770742f73d12077eb550ebb74328ae2755 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:31:54 +0300
Subject: [PATCH 29/55] Update _job.dm
---
code/modules/jobs/job_types/_job.dm | 2 --
1 file changed, 2 deletions(-)
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index 7484d34cd1ac..c701ca035c63 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -70,8 +70,6 @@
var/list/changed_maps = list() // Maps on which the job is changed. Should use the same name as the mapping config
- /// Should this job be allowed to be picked for the bureaucratic error event?
- var/allow_bureaucratic_error = TRUE
/*
If you want to change a job on a specific map with this system, you will want to go onto that job datum
From 05a1a1629f5a136c3aef6d2f7a5ea41fb5d7308a Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:32:15 +0300
Subject: [PATCH 30/55] Update ai.dm
---
code/modules/jobs/job_types/ai.dm | 1 -
1 file changed, 1 deletion(-)
diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm
index 3cdc17b738db..fe094589de30 100644
--- a/code/modules/jobs/job_types/ai.dm
+++ b/code/modules/jobs/job_types/ai.dm
@@ -12,7 +12,6 @@
minimal_player_age = 30
exp_requirements = 180
exp_type = EXP_TYPE_CREW
- allow_bureaucratic_error = FALSE
exp_type_department = EXP_TYPE_SILICON
display_order = JOB_DISPLAY_ORDER_AI
var/do_special_check = TRUE
From dafd04d0ff063d765c66cfaa273ee6bb7ba5e6df Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:32:24 +0300
Subject: [PATCH 31/55] Delete anti_union_propaganda.txt
---
strings/anti_union_propaganda.txt | 4 ----
1 file changed, 4 deletions(-)
delete mode 100644 strings/anti_union_propaganda.txt
diff --git a/strings/anti_union_propaganda.txt b/strings/anti_union_propaganda.txt
deleted file mode 100644
index e1e6f68721a1..000000000000
--- a/strings/anti_union_propaganda.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Remember, union dues cost around 70,000 credits a year. A new video game system with the latest hits sounds like fun. Put your money towards that instead of paying dues to the union.
-Remember, tickets & food to the Toolbox Tournament aren't cheap. That money in union dues you'd be paying every year could sure go a long way.
-Remember, nothing's more enjoyable than a night out watching a thunderdome match with your buddies. All those union dues you pay every year could buy a few rounds.
-Nanotrasen's open door policy is designed to help you feel comfortable taking up issues to your assigned head of staff. It's hard for us to maintain this when they're dead.
\ No newline at end of file
From e8d7e8e8d9ea77db4037505e771e42525d472289 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:35:55 +0300
Subject: [PATCH 32/55] Update antagonists.dm
---
code/__DEFINES/antagonists.dm | 1 +
1 file changed, 1 insertion(+)
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index 3bb45151bb3b..ccdc70876238 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -123,3 +123,4 @@
#define IS_BLOODSUCKER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/bloodsucker))
#define IS_VASSAL(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/vassal))
#define IS_MONSTERHUNTER(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/monsterhunter))
+
From 6cb432a30503e4bc21c81813a9186022542db497 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:36:26 +0300
Subject: [PATCH 33/55] Update blob_overmind.dm
---
code/_onclick/hud/blob_overmind.dm | 1 +
1 file changed, 1 insertion(+)
diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm
index e028a89b4772..e2c1c0a5712d 100644
--- a/code/_onclick/hud/blob_overmind.dm
+++ b/code/_onclick/hud/blob_overmind.dm
@@ -175,3 +175,4 @@
using = new /obj/screen/blob/RelocateCore()
using.screen_loc = ui_storage2
static_inventory += using
+
From 4adce07dd8b13ea9354d87ef1a588d4a540274d9 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:36:44 +0300
Subject: [PATCH 34/55] Update generic_negative_events.dm
---
code/datums/mood_events/generic_negative_events.dm | 1 +
1 file changed, 1 insertion(+)
diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index e5fc41d754e2..9edfcb07ce9d 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -221,3 +221,4 @@
/datum/mood_event/surgery
description = "HE'S CUTTING ME OPEN!!\n"
mood_change = -8
+
From 02370485ee0bab17c9f905daf9e8e6a11dd85b04 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:36:57 +0300
Subject: [PATCH 35/55] Update _blobstrain.dm
---
code/modules/antagonists/blob/blobstrains/_blobstrain.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm
index a9fa8350e79b..ad439d962de2 100644
--- a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm
+++ b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm
@@ -8,7 +8,7 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/
var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects
var/effectdesc = null //any long, blob-tile specific effects
var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp."
- var/analyzerdesceffect
+ var/analyzerdesceffect = "N/A"
var/blobbernaut_message = "slams" //blobbernaut attack verb
var/message = "The blob strikes you" //message sent to any mob hit by the blob
var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt
From fb0ad0605d4d3ac02afc0b9f01a79508b66d0a50 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:37:15 +0300
Subject: [PATCH 36/55] Update _blob.dm
---
code/modules/antagonists/blob/structures/_blob.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm
index 68fdf4075658..a65b79e33b41 100644
--- a/code/modules/antagonists/blob/structures/_blob.dm
+++ b/code/modules/antagonists/blob/structures/_blob.dm
@@ -244,7 +244,7 @@
if(overmind)
. += list("Material: [overmind.blobstrain.name][span_notice(".")]",
"Material Effects: [span_notice("[overmind.blobstrain.analyzerdescdamage]")]",
- "Material Properties: [overmind.blobstrain.analyzerdesceffect || "N/A"]")
+ "Material Properties: [span_notice("[overmind.blobstrain.analyzerdesceffect]")]")
else
. += "No Material Detected!"
From c3269d84c5c6a498c82148290ed0163b8af924bc Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Wed, 29 Jun 2022 15:37:32 +0300
Subject: [PATCH 37/55] Update _job.dm
---
code/modules/jobs/job_types/_job.dm | 1 -
1 file changed, 1 deletion(-)
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index c701ca035c63..c85904d4a217 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -70,7 +70,6 @@
var/list/changed_maps = list() // Maps on which the job is changed. Should use the same name as the mapping config
-
/*
If you want to change a job on a specific map with this system, you will want to go onto that job datum
and add said map's name to the changed_maps list, like so:
From a384daa1d477a370df4151a8015c0a486b0af7f5 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sat, 2 Jul 2022 14:19:12 +0300
Subject: [PATCH 38/55] amonus
---
code/__DEFINES/antagonists.dm | 7 ---
code/__DEFINES/role_preferences.dm | 1 +
code/__DEFINES/status_effects.dm | 4 --
code/__DEFINES/traits.dm | 3 +-
code/datums/mind.dm | 4 ++
.../mood_events/generic_positive_events.dm | 10 +++++
.../dynamic/dynamic_rulesets_roundstart.dm | 34 +++++++++++++++
code/game/gamemodes/hivemind/hivemind.dm | 43 ++++++++++++-------
code/game/gamemodes/hivemind/objectives.dm | 14 +++++-
9 files changed, 91 insertions(+), 29 deletions(-)
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index ccdc70876238..341cf1c6a942 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -76,13 +76,6 @@
/// Prevents hijacking same way as non-antags
#define HIJACK_PREVENT 2
-//Assimilation
-#define TRACKER_DEFAULT_TIME 900
-#define TRACKER_MINDSHIELD_TIME 1200
-#define TRACKER_AWAKENED_TIME 3000
-#define TRACKER_BONUS_LARGE 300
-#define TRACKER_BONUS_SMALL 100
-
//Syndicate Contracts
#define CONTRACT_STATUS_INACTIVE 1
#define CONTRACT_STATUS_ACTIVE 2
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 07bb830ece9a..cb975ac3f8f2 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -30,6 +30,7 @@
#define ROLE_BROTHER "Blood Brother"
#define ROLE_BRAINWASHED "Brainwashed Victim"
#define ROLE_HIVE "Hivemind Host"
+#define ROLE_HIVE_VESSEL "Awakened Vessel"
#define ROLE_OBSESSED "Obsessed"
#define ROLE_SENTIENCE "Sentience Potion Spawn"
#define ROLE_MIND_TRANSFER "Mind Transfer Potion"
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 4afbccca45e9..3dcd959bd438 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -137,10 +137,6 @@
#define STATUS_EFFECT_BUGGED /datum/status_effect/bugged //Lets other mobs listen in on what it hears
-#define STATUS_EFFECT_HIVE_TRACKER /datum/status_effect/hive_track
-
-#define STATUS_EFFECT_HIVE_RADAR /datum/status_effect/agent_pinpointer/hivemind
-
#define STATUS_EFFECT_BOUNTY /datum/status_effect/bounty //rewards the person who added this to the target with refreshed spells and a fair heal
#define STATUS_EFFECT_HELDUP /datum/status_effect/heldup // someone is currently pointing a gun at you
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index bcfdfb97bfc0..c28887f30f2a 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -220,6 +220,7 @@
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat
#define TRAIT_MASQUERADE "masquerade" // Falsifies Health analyzer blood levels
#define TRAIT_COLDBLOODED "coldblooded" // Your body is literal room temperature. Does not make you immune to the temp
+#define TRAIT_HIVE_BURNT "hive-burnt"
//non-mob traits
/// Used for limb-based paralysis, where replacing the limb will fix it.
@@ -321,7 +322,7 @@
#define LOCKED_HELMET_TRAIT "locked-helmet"
#define NINJA_SUIT_TRAIT "ninja-suit"
#define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant"
-#define HIVEMIND_ONE_MIND_TRAIT "one_mind"
+#define HIVEMIND_TRAIT "hivemind-trait"
#define VR_ZONE_TRAIT "vr_zone_trait"
#define GUARDIAN_TRAIT "guardian_trait"
#define RANDOM_BLACKOUTS "random_blackouts"
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 43f063a24237..a162b28a9552 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -283,6 +283,10 @@
if(O)
O.unlock_code = null
+/datum/mind/proc/remove_from_hives()
+ SIGNAL_HANDLER
+ remove_hivemember(src)
+
/datum/mind/proc/remove_all_antag() //For the Lazy amongst us.
remove_changeling()
remove_traitor()
diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm
index 0fb6810f229d..98dfa995ad6b 100644
--- a/code/datums/mood_events/generic_positive_events.dm
+++ b/code/datums/mood_events/generic_positive_events.dm
@@ -114,6 +114,16 @@
mood_change = 10
hidden = TRUE
+/datum/mood_event/hivehost
+ description = "Our psyche expands, our influence broadens.\n"
+ mood_change = 5
+ hidden = TRUE
+
+/datum/mood_event/hiveawakened
+ description = "True purpose has been revealed to us, at last!.\n"
+ mood_change = 2
+ hidden = TRUE
+
/datum/mood_event/family_heirloom
description = "My family heirloom is safe with me.\n"
mood_change = 1
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index 6f75591d5968..b4d71ab85c4d 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -1002,3 +1002,37 @@
if(!bloodsuckermind.make_bloodsucker(assigned_bloodsuckers))
assigned -= assigned_bloodsuckers
return TRUE
+
+//////////////////////////////////////////////
+// //
+// ASSIMILATION //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/roundstart/hivemind
+ name = "Assimilation"
+ antag_flag = ROLE_HIVE
+ antag_datum = /datum/antagonist/hivemind
+ protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
+ restricted_roles = list("Cyborg","AI")
+ required_candidates = 3
+ weight = 3
+ cost = 30
+ requirements = list(100,90,80,60,40,30,10,10,10,10)
+ flags = HIGH_IMPACT_RULESET
+
+/datum/dynamic_ruleset/roundstart/hivemind/pre_execute(population)
+ . = ..()
+ var/num_hosts = max( 3 , rand(0,1) + min(8, round(population / 8) ) )
+ for (var/i = 1 to num_hosts)
+ var/mob/M = pick_n_take(candidates)
+ assigned += M.mind
+ M.mind.restricted_roles = restricted_roles
+ M.mind.special_role = ROLE_HIVE
+ return TRUE
+
+/datum/dynamic_ruleset/roundstart/hivemind/execute()
+ for(var/datum/mind/host in assigned)
+ var/datum/antagonist/hivemind/new_antag = new antag_datum()
+ host.add_antag_datum(new_antag)
+ return TRUE
\ No newline at end of file
diff --git a/code/game/gamemodes/hivemind/hivemind.dm b/code/game/gamemodes/hivemind/hivemind.dm
index 28838d59675e..4a97379aca08 100644
--- a/code/game/gamemodes/hivemind/hivemind.dm
+++ b/code/game/gamemodes/hivemind/hivemind.dm
@@ -1,13 +1,15 @@
+GLOBAL_LIST_EMPTY(hivehosts)
+
/datum/game_mode/hivemind
- name = "Assimilation"
+ name = "assimilation"
config_tag = "hivemind"
report_type = "hivemind"
antag_flag = ROLE_HIVE
false_report_weight = 5
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Brig Physician") //Yogs: Added "Brig Physician
restricted_jobs = list("Cyborg","AI")
- required_players = 24
- required_enemies = 2
+ required_players = 30
+ required_enemies = 3
recommended_enemies = 3
reroll_friendly = 1
enemy_minimum_age = 0
@@ -24,15 +26,10 @@
return
return M.mind.has_antag_datum(/datum/antagonist/hivemind)
-/mob/living/proc/is_real_hivehost() //This proc ignores mind controlled vessels
- for(var/datum/antagonist/hivemind/hive in GLOB.antagonists)
+/mob/living/proc/is_real_hivehost()
+ for(var/datum/antagonist/hivemind/hive as() in GLOB.hivehosts)
if(!hive.owner?.spell_list)
continue
- var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in hive.owner.spell_list
- if((!the_spell || !the_spell.active ) && mind == hive.owner)
- return TRUE
- if(the_spell?.active && the_spell.original_body == src)
- return TRUE
return FALSE
/mob/living/proc/get_real_hivehost() //Returns src unless it's under mind control, then it returns the original body
@@ -41,9 +38,6 @@
return
if(!is_hivehost(M) || is_real_hivehost(M))
return M
- var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in M.mind.spell_list
- if(the_spell?.active)
- return the_spell.original_body
return M
/proc/is_hivemember(mob/living/L)
@@ -52,7 +46,7 @@
var/datum/mind/M = L.mind
if(!M)
return FALSE
- for(var/datum/antagonist/hivemind/H in GLOB.antagonists)
+ for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
if(H.hivemembers.Find(M))
return TRUE
return FALSE
@@ -61,7 +55,7 @@
var/datum/mind/M = L?.mind
if(!M)
return
- for(var/datum/antagonist/hivemind/H in GLOB.antagonists)
+ for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
if(H.hivemembers.Find(M))
H.hivemembers -= M
H.calc_size()
@@ -77,7 +71,7 @@
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
- var/num_hosts = max( 1 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra
+ var/num_hosts = max( 3 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra
for(var/j = 0, j < num_hosts, j++)
if (!antag_candidates.len)
@@ -105,3 +99,20 @@
return "Reports of psychic activity have been showing up in this sector, and we believe this may have to do with a containment breach on \[REDACTED\] last month \
when a sapient hive intelligence displaying paranormal powers escaped into the unknown. They present a very large risk as they can assimilate people into \
the hivemind with ease, although they appear unable to affect mindshielded personnel."
+
+/datum/game_mode/hivemind/generate_credit_text()
+ var/list/round_credits = list()
+ var/len_before_addition
+
+ for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
+ round_credits += "
Hive [H.hiveID]:
"
+ len_before_addition = round_credits.len
+ round_credits += "[H.name] as the Hivemind Host
"
+ for(var/datum/antagonist/hivevessel/V as() in H.avessels)
+ round_credits += "[V.name] as an Awakened Vessel
"
+ if(len_before_addition == round_credits.len)
+ round_credits += list("Hive [H.hiveID] couldn't withstand the competition!
")
+ round_credits += "
"
+
+ round_credits += ..()
+ return round_credits
\ No newline at end of file
diff --git a/code/game/gamemodes/hivemind/objectives.dm b/code/game/gamemodes/hivemind/objectives.dm
index 00c0245e4071..749cac2165aa 100644
--- a/code/game/gamemodes/hivemind/objectives.dm
+++ b/code/game/gamemodes/hivemind/objectives.dm
@@ -30,6 +30,18 @@
/datum/objective/hivemind/hiveescape/update_explanation_text()
explanation_text = "Have at least [target_amount] members of the hive escape on the shuttle alive and free."
+/datum/objective/hivemind/dominance/New()
+ update_explanation_text()
+
+/datum/objective/hivemind/dominance/update_explanation_text()
+ explanation_text = "Assert dominance after having twenty more vessels and more integrations than any other hive."
+
+/datum/objective/hivemind/dominance/check_completion()
+ var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind)
+ if(!host)
+ return ..()
+ return host?.unlocked_dominance || ..()
+
/datum/objective/hivemind/hiveescape/check_completion()
if(..())
return TRUE
@@ -51,7 +63,7 @@
var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind)
if(!host)
return FALSE
- for(var/datum/antagonist/hivemind/H in GLOB.antagonists)
+ for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
if(H == host)
continue
if(H.hive_size >= host.hive_size)
From f216470da92eaa03453cd27224c7782ed6173aca Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sat, 2 Jul 2022 14:19:32 +0300
Subject: [PATCH 39/55] del
---
code/game/gamemodes/hivemind/radar.dm | 74 ---------------------------
1 file changed, 74 deletions(-)
delete mode 100644 code/game/gamemodes/hivemind/radar.dm
diff --git a/code/game/gamemodes/hivemind/radar.dm b/code/game/gamemodes/hivemind/radar.dm
deleted file mode 100644
index 27c1154d8d6a..000000000000
--- a/code/game/gamemodes/hivemind/radar.dm
+++ /dev/null
@@ -1,74 +0,0 @@
-#define HIVEMIND_RADAR_MIN_DISTANCE 0 //Very generous, as the targets are only tracked for a few minutes.
-#define HIVEMIND_RADAR_MAX_DISTANCE 50
-#define HIVEMIND_RADAR_PING_TIME 40 //4s update time.
-
-//Modified IA/changeling pinpointer, points to the nearest person who is afflicted with the hive tracker status effect
-/datum/status_effect/agent_pinpointer/hivemind
- id = "hive_pinpointer"
- alert_type = /obj/screen/alert/status_effect/agent_pinpointer/hivemind
- minimum_range = HIVEMIND_RADAR_MIN_DISTANCE
- tick_interval = HIVEMIND_RADAR_PING_TIME
- range_fuzz_factor = 0
-
-/datum/status_effect/agent_pinpointer/hivemind/point_to_target() //If we found what we're looking for, show the distance and direction
- if(scan_target)
- if(owner.mind)
- var/datum/antagonist/hivemind/hive = owner.mind.has_antag_datum(/datum/antagonist/hivemind)
- if(hive)
- range_far = range_mid * (2-hive.get_threat_multiplier())
- if(scan_target.mind)
- var/datum/antagonist/hivemind/enemy_hive = scan_target.mind.has_antag_datum(/datum/antagonist/hivemind)
- if(enemy_hive)
- range_far = max(range_mid * (1+enemy_hive.get_threat_multiplier()), range_far)
-
- ..()
-
-/datum/status_effect/agent_pinpointer/hivemind/scan_for_target()
- var/turf/my_loc = get_turf(owner)
-
- var/list/mob/living/carbon/targets = list()
- var/trackable_targets_exist = FALSE
-
- for(var/mob/living/carbon/C in GLOB.alive_mob_list)
- if(C == owner)
- continue
- var/datum/status_effect/hive_track/mark = C.has_status_effect(STATUS_EFFECT_HIVE_TRACKER)
- if(mark && mark.tracked_by == owner)
- trackable_targets_exist = TRUE
- var/their_loc = get_turf(C)
- var/distance = get_dist_euclidian(my_loc, their_loc)
- if (distance < HIVEMIND_RADAR_MAX_DISTANCE)
- var/multiplier = 0.5
- if(C.mind)
- var/datum/antagonist/hivemind/hive = C.mind.has_antag_datum(/datum/antagonist/hivemind)
- if(hive)
- multiplier = hive.get_threat_multiplier()
- targets[C] = ((HIVEMIND_RADAR_MAX_DISTANCE ** 2) - (distance ** 2)) * multiplier
-
- if(targets.len)
- scan_target = pickweight(targets) //Point at a 'random' target, biasing heavily towards closer ones.
- else
- scan_target = null
- if(!trackable_targets_exist)
- to_chat(owner, span_assimilator("The psychic energies eminating from afar have died down... for now"))
- owner.remove_status_effect(STATUS_EFFECT_HIVE_RADAR)
-
-//"Trackable" status effect
-/datum/status_effect/hive_track
- id = "hive_track"
- duration = 1200
- status_type = STATUS_EFFECT_MULTIPLE
- alert_type = null
- var/mob/living/tracked_by
-
-/datum/status_effect/hive_track/on_creation(mob/living/new_owner, mob/living/hunter, set_duration)
- . = ..()
- if(.)
- tracked_by = hunter
- if(isnum(set_duration))
- duration = world.time + set_duration
-
-//Screen alert
-/obj/screen/alert/status_effect/agent_pinpointer/hivemind
- name = "Psychic link"
- desc = "Somebody is there, and they're definitely not friendly."
From f08f550816f0da891b55701dcc7583bd048ffa3c Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sun, 10 Jul 2022 15:01:45 +0300
Subject: [PATCH 40/55] amogus
---
.../objects/structures/lavaland/geyser.dm | 56 ++++++++++---------
code/modules/reagents/reagent_dispenser.dm | 3 +-
2 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/code/game/objects/structures/lavaland/geyser.dm b/code/game/objects/structures/lavaland/geyser.dm
index 0d90bbe84ecd..fd7325c18497 100644
--- a/code/game/objects/structures/lavaland/geyser.dm
+++ b/code/game/objects/structures/lavaland/geyser.dm
@@ -1,55 +1,59 @@
//If you look at the "geyser_soup" overlay icon_state, you'll see that the first frame has 25 ticks.
//That's because the first 18~ ticks are completely skipped for some ungodly weird fucking byond reason
-/obj/structure/geyser
+/obj/structure/reagent_dispensers/geyser
name = "geyser"
icon = 'icons/obj/lavaland/terrain.dmi'
icon_state = "geyser"
anchored = TRUE
+ reagent_id = /datum/reagent/oil
+ tank_volume = 500
- var/erupting_state = null //set to null to get it greyscaled from "[icon_state]_soup". Not very usable with the whole random thing, but more types can be added if you change the spawn prob
var/activated = FALSE //whether we are active and generating chems
- var/reagent_id = /datum/reagent/oil
var/potency = 2 //how much reagents we add every process (2 seconds)
- var/max_volume = 500
var/start_volume = 50
+ var/points = 100
-/obj/structure/geyser/proc/start_chemming()
+/obj/structure/reagent_dispensers/geyser/proc/start_chemming()
activated = TRUE
- create_reagents(max_volume, DRAINABLE)
reagents.add_reagent(reagent_id, start_volume)
- START_PROCESSING(SSfluids, src) //It's main function is to be plumbed, so use SSfluids
- if(erupting_state)
- icon_state = erupting_state
- else
- var/mutable_appearance/I = mutable_appearance('icons/obj/lavaland/terrain.dmi', "[icon_state]_soup")
- I.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(I)
+ START_PROCESSING(SSfluids, src)
+ var/mutable_appearance/I = mutable_appearance('icons/obj/lavaland/terrain.dmi', "[icon_state]_soup")
+ I.color = mix_color_from_reagents(reagents.reagent_list)
+ add_overlay(I)
-/obj/structure/geyser/process()
+/obj/structure/reagent_dispensers/geyser/process()
if(activated && reagents.total_volume <= reagents.maximum_volume) //this is also evaluated in add_reagent, but from my understanding proc calls are expensive and should be avoided in continous
reagents.add_reagent(reagent_id, potency) //processes
-/obj/structure/geyser/plunger_act(obj/item/plunger/P, mob/living/user, _reinforced)
- if(!_reinforced)
- to_chat(user, "The [P.name] isn't strong enough!")
- return
- if(activated)
- to_chat(user, "The [name] is already active!")
- return
+/obj/structure/reagent_dispensers/geyser/attackby(obj/item/W, mob/user, params)
+ if(istype(/obj/item/t_scanner/adv_mining_scanner))
+ if(activated)
+ to_chat(user, span_warning("The [src] is already activated!"))
+ return
+ to_chat(user, span_notice("You start activating the [src]...")) ///Power of mining scanners
+ if(do_after(user, 3 SECONDS, src))
+ to_chat(user, span_notice("You activate the [src]"))
+ var/obj/item/card/id/I = M.get_idcard(TRUE)
+ if(I)
+ to_chat(user, span_notice("You gain 100 mining points for scanning the [src]."))
+ I.mining_points += points
+ playsound(src, 'sound/machines/ping.ogg', 15, TRUE)
+ start_chemming()
+ . = ..()
- to_chat(user, "You start vigorously plunging [src]!")
- if(do_after(user, 5 SECONDS*P.plunge_mod, src) && !activated)
- start_chemming()
+/obj/structure/reagent_dispensers/geyser/boom() /// Fuck you, no boom
+ return
-/obj/structure/geyser/random
+/obj/structure/reagent_dispensers/geyser/random
erupting_state = null
var/list/options = list(/datum/reagent/oil = 2, /datum/reagent/clf3 = 1) //fucking add more
-/obj/structure/geyser/random/Initialize()
+/obj/structure/reagent_dispensers/geyser/random/Initialize()
. = ..()
reagent_id = pickweight(options)
+///Unused shit
/obj/item/plunger
name = "plunger"
desc = "It's a plunger for plunging."
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index d80b3390396b..7b3db4a6c196 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -9,6 +9,7 @@
max_integrity = 300
var/tank_volume = 1000 //In units, how much the dispenser can hold
var/reagent_id = /datum/reagent/water //The ID of the reagent that the dispenser uses
+ var/filled = TRUE //If the tank initialy starts with reagents
/obj/structure/reagent_dispensers/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
@@ -24,7 +25,7 @@
/obj/structure/reagent_dispensers/Initialize()
create_reagents(tank_volume, DRAINABLE | AMOUNT_VISIBLE)
- if(reagent_id)
+ if(reagent_id && filled)
reagents.add_reagent(reagent_id, tank_volume)
. = ..()
From c4063404e9b14dcb962a71eed75e82c344036ae8 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sun, 10 Jul 2022 15:03:02 +0300
Subject: [PATCH 41/55] mapping shit
---
code/datums/mapgen/CaveGenerator.dm | 2 +-
code/datums/mapgen/Cavegens/LavalandGenerator.dm | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/code/datums/mapgen/CaveGenerator.dm b/code/datums/mapgen/CaveGenerator.dm
index 34e06b5d47e0..4b5219e6f396 100644
--- a/code/datums/mapgen/CaveGenerator.dm
+++ b/code/datums/mapgen/CaveGenerator.dm
@@ -43,7 +43,7 @@
if(!flora_spawn_list)
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
if(!feature_spawn_list)
- feature_spawn_list = list(/obj/structure/geyser/random = 1)
+ feature_spawn_list = list(/obj/structure/reagent_dispensers/geyser/random = 1)
/datum/map_generator/cave_generator/generate_terrain(list/turfs)
. = ..()
diff --git a/code/datums/mapgen/Cavegens/LavalandGenerator.dm b/code/datums/mapgen/Cavegens/LavalandGenerator.dm
index 78da86214492..b643202ec9ee 100644
--- a/code/datums/mapgen/Cavegens/LavalandGenerator.dm
+++ b/code/datums/mapgen/Cavegens/LavalandGenerator.dm
@@ -11,7 +11,7 @@
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
///Note that this spawn list is also in the icemoon generator
//feature_spawn_list = list(/obj/structure/geyser/wittel = 6, /obj/structure/geyser/random = 2, /obj/structure/geyser/plasma_oxide = 10, /obj/structure/geyser/protozine = 10, /obj/structure/geyser/hollowwater = 10)
- feature_spawn_list = list(/obj/structure/geyser/random = 1)
+ feature_spawn_list = list(/obj/structure/reagent_dispensers/geyser/random = 1)
initial_closed_chance = 45
smoothing_iterations = 50
From 1b3d071fed32069a4c61660139967164794e6f05 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sun, 10 Jul 2022 15:11:35 +0300
Subject: [PATCH 42/55] removes stupid hivemind shit that i forgot to remove
from my master branch
---
code/__DEFINES/antagonists.dm | 7 ++
code/__DEFINES/role_preferences.dm | 1 -
code/__DEFINES/status_effects.dm | 4 +
code/__DEFINES/traits.dm | 2 +-
code/_onclick/hud/blob_overmind.dm | 3 +-
code/datums/mind.dm | 4 -
.../mood_events/generic_positive_events.dm | 10 ---
.../dynamic/dynamic_rulesets_roundstart.dm | 33 ---------
code/game/gamemodes/hivemind/hivemind.dm | 43 ++++-------
code/game/gamemodes/hivemind/objectives.dm | 12 ---
code/game/gamemodes/hivemind/radar.dm | 74 +++++++++++++++++++
11 files changed, 103 insertions(+), 90 deletions(-)
create mode 100644 code/game/gamemodes/hivemind/radar.dm
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index 341cf1c6a942..ccdc70876238 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -76,6 +76,13 @@
/// Prevents hijacking same way as non-antags
#define HIJACK_PREVENT 2
+//Assimilation
+#define TRACKER_DEFAULT_TIME 900
+#define TRACKER_MINDSHIELD_TIME 1200
+#define TRACKER_AWAKENED_TIME 3000
+#define TRACKER_BONUS_LARGE 300
+#define TRACKER_BONUS_SMALL 100
+
//Syndicate Contracts
#define CONTRACT_STATUS_INACTIVE 1
#define CONTRACT_STATUS_ACTIVE 2
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index cb975ac3f8f2..07bb830ece9a 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -30,7 +30,6 @@
#define ROLE_BROTHER "Blood Brother"
#define ROLE_BRAINWASHED "Brainwashed Victim"
#define ROLE_HIVE "Hivemind Host"
-#define ROLE_HIVE_VESSEL "Awakened Vessel"
#define ROLE_OBSESSED "Obsessed"
#define ROLE_SENTIENCE "Sentience Potion Spawn"
#define ROLE_MIND_TRANSFER "Mind Transfer Potion"
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 3dcd959bd438..4afbccca45e9 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -137,6 +137,10 @@
#define STATUS_EFFECT_BUGGED /datum/status_effect/bugged //Lets other mobs listen in on what it hears
+#define STATUS_EFFECT_HIVE_TRACKER /datum/status_effect/hive_track
+
+#define STATUS_EFFECT_HIVE_RADAR /datum/status_effect/agent_pinpointer/hivemind
+
#define STATUS_EFFECT_BOUNTY /datum/status_effect/bounty //rewards the person who added this to the target with refreshed spells and a fair heal
#define STATUS_EFFECT_HELDUP /datum/status_effect/heldup // someone is currently pointing a gun at you
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index c28887f30f2a..29a7be3266f3 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -220,7 +220,7 @@
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat
#define TRAIT_MASQUERADE "masquerade" // Falsifies Health analyzer blood levels
#define TRAIT_COLDBLOODED "coldblooded" // Your body is literal room temperature. Does not make you immune to the temp
-#define TRAIT_HIVE_BURNT "hive-burnt"
+#define HIVEMIND_ONE_MIND_TRAIT "one_mind"
//non-mob traits
/// Used for limb-based paralysis, where replacing the limb will fix it.
diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm
index e2c1c0a5712d..5e352112f26b 100644
--- a/code/_onclick/hud/blob_overmind.dm
+++ b/code/_onclick/hud/blob_overmind.dm
@@ -174,5 +174,4 @@
using = new /obj/screen/blob/RelocateCore()
using.screen_loc = ui_storage2
- static_inventory += using
-
+ static_inventory += using
\ No newline at end of file
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index a162b28a9552..43f063a24237 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -283,10 +283,6 @@
if(O)
O.unlock_code = null
-/datum/mind/proc/remove_from_hives()
- SIGNAL_HANDLER
- remove_hivemember(src)
-
/datum/mind/proc/remove_all_antag() //For the Lazy amongst us.
remove_changeling()
remove_traitor()
diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm
index 98dfa995ad6b..0fb6810f229d 100644
--- a/code/datums/mood_events/generic_positive_events.dm
+++ b/code/datums/mood_events/generic_positive_events.dm
@@ -114,16 +114,6 @@
mood_change = 10
hidden = TRUE
-/datum/mood_event/hivehost
- description = "Our psyche expands, our influence broadens.\n"
- mood_change = 5
- hidden = TRUE
-
-/datum/mood_event/hiveawakened
- description = "True purpose has been revealed to us, at last!.\n"
- mood_change = 2
- hidden = TRUE
-
/datum/mood_event/family_heirloom
description = "My family heirloom is safe with me.\n"
mood_change = 1
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index b4d71ab85c4d..a08c738a154d 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -1003,36 +1003,3 @@
assigned -= assigned_bloodsuckers
return TRUE
-//////////////////////////////////////////////
-// //
-// ASSIMILATION //
-// //
-//////////////////////////////////////////////
-
-/datum/dynamic_ruleset/roundstart/hivemind
- name = "Assimilation"
- antag_flag = ROLE_HIVE
- antag_datum = /datum/antagonist/hivemind
- protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
- restricted_roles = list("Cyborg","AI")
- required_candidates = 3
- weight = 3
- cost = 30
- requirements = list(100,90,80,60,40,30,10,10,10,10)
- flags = HIGH_IMPACT_RULESET
-
-/datum/dynamic_ruleset/roundstart/hivemind/pre_execute(population)
- . = ..()
- var/num_hosts = max( 3 , rand(0,1) + min(8, round(population / 8) ) )
- for (var/i = 1 to num_hosts)
- var/mob/M = pick_n_take(candidates)
- assigned += M.mind
- M.mind.restricted_roles = restricted_roles
- M.mind.special_role = ROLE_HIVE
- return TRUE
-
-/datum/dynamic_ruleset/roundstart/hivemind/execute()
- for(var/datum/mind/host in assigned)
- var/datum/antagonist/hivemind/new_antag = new antag_datum()
- host.add_antag_datum(new_antag)
- return TRUE
\ No newline at end of file
diff --git a/code/game/gamemodes/hivemind/hivemind.dm b/code/game/gamemodes/hivemind/hivemind.dm
index 4a97379aca08..28838d59675e 100644
--- a/code/game/gamemodes/hivemind/hivemind.dm
+++ b/code/game/gamemodes/hivemind/hivemind.dm
@@ -1,15 +1,13 @@
-GLOBAL_LIST_EMPTY(hivehosts)
-
/datum/game_mode/hivemind
- name = "assimilation"
+ name = "Assimilation"
config_tag = "hivemind"
report_type = "hivemind"
antag_flag = ROLE_HIVE
false_report_weight = 5
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Brig Physician") //Yogs: Added "Brig Physician
restricted_jobs = list("Cyborg","AI")
- required_players = 30
- required_enemies = 3
+ required_players = 24
+ required_enemies = 2
recommended_enemies = 3
reroll_friendly = 1
enemy_minimum_age = 0
@@ -26,10 +24,15 @@ GLOBAL_LIST_EMPTY(hivehosts)
return
return M.mind.has_antag_datum(/datum/antagonist/hivemind)
-/mob/living/proc/is_real_hivehost()
- for(var/datum/antagonist/hivemind/hive as() in GLOB.hivehosts)
+/mob/living/proc/is_real_hivehost() //This proc ignores mind controlled vessels
+ for(var/datum/antagonist/hivemind/hive in GLOB.antagonists)
if(!hive.owner?.spell_list)
continue
+ var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in hive.owner.spell_list
+ if((!the_spell || !the_spell.active ) && mind == hive.owner)
+ return TRUE
+ if(the_spell?.active && the_spell.original_body == src)
+ return TRUE
return FALSE
/mob/living/proc/get_real_hivehost() //Returns src unless it's under mind control, then it returns the original body
@@ -38,6 +41,9 @@ GLOBAL_LIST_EMPTY(hivehosts)
return
if(!is_hivehost(M) || is_real_hivehost(M))
return M
+ var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in M.mind.spell_list
+ if(the_spell?.active)
+ return the_spell.original_body
return M
/proc/is_hivemember(mob/living/L)
@@ -46,7 +52,7 @@ GLOBAL_LIST_EMPTY(hivehosts)
var/datum/mind/M = L.mind
if(!M)
return FALSE
- for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
+ for(var/datum/antagonist/hivemind/H in GLOB.antagonists)
if(H.hivemembers.Find(M))
return TRUE
return FALSE
@@ -55,7 +61,7 @@ GLOBAL_LIST_EMPTY(hivehosts)
var/datum/mind/M = L?.mind
if(!M)
return
- for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
+ for(var/datum/antagonist/hivemind/H in GLOB.antagonists)
if(H.hivemembers.Find(M))
H.hivemembers -= M
H.calc_size()
@@ -71,7 +77,7 @@ GLOBAL_LIST_EMPTY(hivehosts)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
- var/num_hosts = max( 3 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra
+ var/num_hosts = max( 1 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra
for(var/j = 0, j < num_hosts, j++)
if (!antag_candidates.len)
@@ -99,20 +105,3 @@ GLOBAL_LIST_EMPTY(hivehosts)
return "Reports of psychic activity have been showing up in this sector, and we believe this may have to do with a containment breach on \[REDACTED\] last month \
when a sapient hive intelligence displaying paranormal powers escaped into the unknown. They present a very large risk as they can assimilate people into \
the hivemind with ease, although they appear unable to affect mindshielded personnel."
-
-/datum/game_mode/hivemind/generate_credit_text()
- var/list/round_credits = list()
- var/len_before_addition
-
- for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
- round_credits += "Hive [H.hiveID]:
"
- len_before_addition = round_credits.len
- round_credits += "[H.name] as the Hivemind Host
"
- for(var/datum/antagonist/hivevessel/V as() in H.avessels)
- round_credits += "[V.name] as an Awakened Vessel
"
- if(len_before_addition == round_credits.len)
- round_credits += list("Hive [H.hiveID] couldn't withstand the competition!
")
- round_credits += "
"
-
- round_credits += ..()
- return round_credits
\ No newline at end of file
diff --git a/code/game/gamemodes/hivemind/objectives.dm b/code/game/gamemodes/hivemind/objectives.dm
index 749cac2165aa..3e3723ce5428 100644
--- a/code/game/gamemodes/hivemind/objectives.dm
+++ b/code/game/gamemodes/hivemind/objectives.dm
@@ -30,18 +30,6 @@
/datum/objective/hivemind/hiveescape/update_explanation_text()
explanation_text = "Have at least [target_amount] members of the hive escape on the shuttle alive and free."
-/datum/objective/hivemind/dominance/New()
- update_explanation_text()
-
-/datum/objective/hivemind/dominance/update_explanation_text()
- explanation_text = "Assert dominance after having twenty more vessels and more integrations than any other hive."
-
-/datum/objective/hivemind/dominance/check_completion()
- var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind)
- if(!host)
- return ..()
- return host?.unlocked_dominance || ..()
-
/datum/objective/hivemind/hiveescape/check_completion()
if(..())
return TRUE
diff --git a/code/game/gamemodes/hivemind/radar.dm b/code/game/gamemodes/hivemind/radar.dm
new file mode 100644
index 000000000000..27c1154d8d6a
--- /dev/null
+++ b/code/game/gamemodes/hivemind/radar.dm
@@ -0,0 +1,74 @@
+#define HIVEMIND_RADAR_MIN_DISTANCE 0 //Very generous, as the targets are only tracked for a few minutes.
+#define HIVEMIND_RADAR_MAX_DISTANCE 50
+#define HIVEMIND_RADAR_PING_TIME 40 //4s update time.
+
+//Modified IA/changeling pinpointer, points to the nearest person who is afflicted with the hive tracker status effect
+/datum/status_effect/agent_pinpointer/hivemind
+ id = "hive_pinpointer"
+ alert_type = /obj/screen/alert/status_effect/agent_pinpointer/hivemind
+ minimum_range = HIVEMIND_RADAR_MIN_DISTANCE
+ tick_interval = HIVEMIND_RADAR_PING_TIME
+ range_fuzz_factor = 0
+
+/datum/status_effect/agent_pinpointer/hivemind/point_to_target() //If we found what we're looking for, show the distance and direction
+ if(scan_target)
+ if(owner.mind)
+ var/datum/antagonist/hivemind/hive = owner.mind.has_antag_datum(/datum/antagonist/hivemind)
+ if(hive)
+ range_far = range_mid * (2-hive.get_threat_multiplier())
+ if(scan_target.mind)
+ var/datum/antagonist/hivemind/enemy_hive = scan_target.mind.has_antag_datum(/datum/antagonist/hivemind)
+ if(enemy_hive)
+ range_far = max(range_mid * (1+enemy_hive.get_threat_multiplier()), range_far)
+
+ ..()
+
+/datum/status_effect/agent_pinpointer/hivemind/scan_for_target()
+ var/turf/my_loc = get_turf(owner)
+
+ var/list/mob/living/carbon/targets = list()
+ var/trackable_targets_exist = FALSE
+
+ for(var/mob/living/carbon/C in GLOB.alive_mob_list)
+ if(C == owner)
+ continue
+ var/datum/status_effect/hive_track/mark = C.has_status_effect(STATUS_EFFECT_HIVE_TRACKER)
+ if(mark && mark.tracked_by == owner)
+ trackable_targets_exist = TRUE
+ var/their_loc = get_turf(C)
+ var/distance = get_dist_euclidian(my_loc, their_loc)
+ if (distance < HIVEMIND_RADAR_MAX_DISTANCE)
+ var/multiplier = 0.5
+ if(C.mind)
+ var/datum/antagonist/hivemind/hive = C.mind.has_antag_datum(/datum/antagonist/hivemind)
+ if(hive)
+ multiplier = hive.get_threat_multiplier()
+ targets[C] = ((HIVEMIND_RADAR_MAX_DISTANCE ** 2) - (distance ** 2)) * multiplier
+
+ if(targets.len)
+ scan_target = pickweight(targets) //Point at a 'random' target, biasing heavily towards closer ones.
+ else
+ scan_target = null
+ if(!trackable_targets_exist)
+ to_chat(owner, span_assimilator("The psychic energies eminating from afar have died down... for now"))
+ owner.remove_status_effect(STATUS_EFFECT_HIVE_RADAR)
+
+//"Trackable" status effect
+/datum/status_effect/hive_track
+ id = "hive_track"
+ duration = 1200
+ status_type = STATUS_EFFECT_MULTIPLE
+ alert_type = null
+ var/mob/living/tracked_by
+
+/datum/status_effect/hive_track/on_creation(mob/living/new_owner, mob/living/hunter, set_duration)
+ . = ..()
+ if(.)
+ tracked_by = hunter
+ if(isnum(set_duration))
+ duration = world.time + set_duration
+
+//Screen alert
+/obj/screen/alert/status_effect/agent_pinpointer/hivemind
+ name = "Psychic link"
+ desc = "Somebody is there, and they're definitely not friendly."
From adfb9c75f5730f1910b18c74b994ae544944468e Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sun, 10 Jul 2022 15:19:08 +0300
Subject: [PATCH 43/55] Update traits.dm
---
code/__DEFINES/traits.dm | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 29a7be3266f3..bcfdfb97bfc0 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -220,7 +220,6 @@
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat
#define TRAIT_MASQUERADE "masquerade" // Falsifies Health analyzer blood levels
#define TRAIT_COLDBLOODED "coldblooded" // Your body is literal room temperature. Does not make you immune to the temp
-#define HIVEMIND_ONE_MIND_TRAIT "one_mind"
//non-mob traits
/// Used for limb-based paralysis, where replacing the limb will fix it.
@@ -322,7 +321,7 @@
#define LOCKED_HELMET_TRAIT "locked-helmet"
#define NINJA_SUIT_TRAIT "ninja-suit"
#define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant"
-#define HIVEMIND_TRAIT "hivemind-trait"
+#define HIVEMIND_ONE_MIND_TRAIT "one_mind"
#define VR_ZONE_TRAIT "vr_zone_trait"
#define GUARDIAN_TRAIT "guardian_trait"
#define RANDOM_BLACKOUTS "random_blackouts"
From 7bd7834fd1e5834567467f1066d218f8cd3ea14d Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sun, 10 Jul 2022 15:19:36 +0300
Subject: [PATCH 44/55] Update objectives.dm
---
code/game/gamemodes/hivemind/objectives.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/game/gamemodes/hivemind/objectives.dm b/code/game/gamemodes/hivemind/objectives.dm
index 3e3723ce5428..00c0245e4071 100644
--- a/code/game/gamemodes/hivemind/objectives.dm
+++ b/code/game/gamemodes/hivemind/objectives.dm
@@ -51,7 +51,7 @@
var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind)
if(!host)
return FALSE
- for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
+ for(var/datum/antagonist/hivemind/H in GLOB.antagonists)
if(H == host)
continue
if(H.hive_size >= host.hive_size)
From 71109cb99a09bf0dc2eee0a6382813693e107987 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sun, 10 Jul 2022 15:19:59 +0300
Subject: [PATCH 45/55] Update dynamic_rulesets_roundstart.dm
---
code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 1 -
1 file changed, 1 deletion(-)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index a08c738a154d..6f75591d5968 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -1002,4 +1002,3 @@
if(!bloodsuckermind.make_bloodsucker(assigned_bloodsuckers))
assigned -= assigned_bloodsuckers
return TRUE
-
From 137137129d702e8d6a74e96df4e6b910e8eac4ca Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sun, 10 Jul 2022 15:21:06 +0300
Subject: [PATCH 46/55] e
---
code/game/objects/structures/lavaland/geyser.dm | 1 +
1 file changed, 1 insertion(+)
diff --git a/code/game/objects/structures/lavaland/geyser.dm b/code/game/objects/structures/lavaland/geyser.dm
index fd7325c18497..a6b6337dfade 100644
--- a/code/game/objects/structures/lavaland/geyser.dm
+++ b/code/game/objects/structures/lavaland/geyser.dm
@@ -8,6 +8,7 @@
anchored = TRUE
reagent_id = /datum/reagent/oil
tank_volume = 500
+ filled = FALSE
var/activated = FALSE //whether we are active and generating chems
var/potency = 2 //how much reagents we add every process (2 seconds)
From 73387bd44c9a380489febf12b58ff331a02aa4bc Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Sun, 10 Jul 2022 15:24:52 +0300
Subject: [PATCH 47/55] fork cleanup
---
code/datums/mapgen/CaveGenerator.dm | 2 +-
.../mapgen/Cavegens/LavalandGenerator.dm | 2 +-
.../objects/structures/lavaland/geyser.dm | 57 +++++++++----------
code/modules/reagents/reagent_dispenser.dm | 3 +-
4 files changed, 29 insertions(+), 35 deletions(-)
diff --git a/code/datums/mapgen/CaveGenerator.dm b/code/datums/mapgen/CaveGenerator.dm
index 4b5219e6f396..34e06b5d47e0 100644
--- a/code/datums/mapgen/CaveGenerator.dm
+++ b/code/datums/mapgen/CaveGenerator.dm
@@ -43,7 +43,7 @@
if(!flora_spawn_list)
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
if(!feature_spawn_list)
- feature_spawn_list = list(/obj/structure/reagent_dispensers/geyser/random = 1)
+ feature_spawn_list = list(/obj/structure/geyser/random = 1)
/datum/map_generator/cave_generator/generate_terrain(list/turfs)
. = ..()
diff --git a/code/datums/mapgen/Cavegens/LavalandGenerator.dm b/code/datums/mapgen/Cavegens/LavalandGenerator.dm
index b643202ec9ee..78da86214492 100644
--- a/code/datums/mapgen/Cavegens/LavalandGenerator.dm
+++ b/code/datums/mapgen/Cavegens/LavalandGenerator.dm
@@ -11,7 +11,7 @@
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
///Note that this spawn list is also in the icemoon generator
//feature_spawn_list = list(/obj/structure/geyser/wittel = 6, /obj/structure/geyser/random = 2, /obj/structure/geyser/plasma_oxide = 10, /obj/structure/geyser/protozine = 10, /obj/structure/geyser/hollowwater = 10)
- feature_spawn_list = list(/obj/structure/reagent_dispensers/geyser/random = 1)
+ feature_spawn_list = list(/obj/structure/geyser/random = 1)
initial_closed_chance = 45
smoothing_iterations = 50
diff --git a/code/game/objects/structures/lavaland/geyser.dm b/code/game/objects/structures/lavaland/geyser.dm
index a6b6337dfade..0d90bbe84ecd 100644
--- a/code/game/objects/structures/lavaland/geyser.dm
+++ b/code/game/objects/structures/lavaland/geyser.dm
@@ -1,60 +1,55 @@
//If you look at the "geyser_soup" overlay icon_state, you'll see that the first frame has 25 ticks.
//That's because the first 18~ ticks are completely skipped for some ungodly weird fucking byond reason
-/obj/structure/reagent_dispensers/geyser
+/obj/structure/geyser
name = "geyser"
icon = 'icons/obj/lavaland/terrain.dmi'
icon_state = "geyser"
anchored = TRUE
- reagent_id = /datum/reagent/oil
- tank_volume = 500
- filled = FALSE
+ var/erupting_state = null //set to null to get it greyscaled from "[icon_state]_soup". Not very usable with the whole random thing, but more types can be added if you change the spawn prob
var/activated = FALSE //whether we are active and generating chems
+ var/reagent_id = /datum/reagent/oil
var/potency = 2 //how much reagents we add every process (2 seconds)
+ var/max_volume = 500
var/start_volume = 50
- var/points = 100
-/obj/structure/reagent_dispensers/geyser/proc/start_chemming()
+/obj/structure/geyser/proc/start_chemming()
activated = TRUE
+ create_reagents(max_volume, DRAINABLE)
reagents.add_reagent(reagent_id, start_volume)
- START_PROCESSING(SSfluids, src)
- var/mutable_appearance/I = mutable_appearance('icons/obj/lavaland/terrain.dmi', "[icon_state]_soup")
- I.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(I)
+ START_PROCESSING(SSfluids, src) //It's main function is to be plumbed, so use SSfluids
+ if(erupting_state)
+ icon_state = erupting_state
+ else
+ var/mutable_appearance/I = mutable_appearance('icons/obj/lavaland/terrain.dmi', "[icon_state]_soup")
+ I.color = mix_color_from_reagents(reagents.reagent_list)
+ add_overlay(I)
-/obj/structure/reagent_dispensers/geyser/process()
+/obj/structure/geyser/process()
if(activated && reagents.total_volume <= reagents.maximum_volume) //this is also evaluated in add_reagent, but from my understanding proc calls are expensive and should be avoided in continous
reagents.add_reagent(reagent_id, potency) //processes
-/obj/structure/reagent_dispensers/geyser/attackby(obj/item/W, mob/user, params)
- if(istype(/obj/item/t_scanner/adv_mining_scanner))
- if(activated)
- to_chat(user, span_warning("The [src] is already activated!"))
- return
- to_chat(user, span_notice("You start activating the [src]...")) ///Power of mining scanners
- if(do_after(user, 3 SECONDS, src))
- to_chat(user, span_notice("You activate the [src]"))
- var/obj/item/card/id/I = M.get_idcard(TRUE)
- if(I)
- to_chat(user, span_notice("You gain 100 mining points for scanning the [src]."))
- I.mining_points += points
- playsound(src, 'sound/machines/ping.ogg', 15, TRUE)
- start_chemming()
- . = ..()
+/obj/structure/geyser/plunger_act(obj/item/plunger/P, mob/living/user, _reinforced)
+ if(!_reinforced)
+ to_chat(user, "The [P.name] isn't strong enough!")
+ return
+ if(activated)
+ to_chat(user, "The [name] is already active!")
+ return
-/obj/structure/reagent_dispensers/geyser/boom() /// Fuck you, no boom
- return
+ to_chat(user, "You start vigorously plunging [src]!")
+ if(do_after(user, 5 SECONDS*P.plunge_mod, src) && !activated)
+ start_chemming()
-/obj/structure/reagent_dispensers/geyser/random
+/obj/structure/geyser/random
erupting_state = null
var/list/options = list(/datum/reagent/oil = 2, /datum/reagent/clf3 = 1) //fucking add more
-/obj/structure/reagent_dispensers/geyser/random/Initialize()
+/obj/structure/geyser/random/Initialize()
. = ..()
reagent_id = pickweight(options)
-///Unused shit
/obj/item/plunger
name = "plunger"
desc = "It's a plunger for plunging."
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 7b3db4a6c196..d80b3390396b 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -9,7 +9,6 @@
max_integrity = 300
var/tank_volume = 1000 //In units, how much the dispenser can hold
var/reagent_id = /datum/reagent/water //The ID of the reagent that the dispenser uses
- var/filled = TRUE //If the tank initialy starts with reagents
/obj/structure/reagent_dispensers/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
@@ -25,7 +24,7 @@
/obj/structure/reagent_dispensers/Initialize()
create_reagents(tank_volume, DRAINABLE | AMOUNT_VISIBLE)
- if(reagent_id && filled)
+ if(reagent_id)
reagents.add_reagent(reagent_id, tank_volume)
. = ..()
From 4d6158b8c1d98803b3395eba5d55549c9f8d7cc2 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Mon, 11 Jul 2022 14:30:16 +0300
Subject: [PATCH 48/55] cleans useless shit from the fork
---
code/__DEFINES/antagonists.dm | 7 ++
code/__DEFINES/role_preferences.dm | 1 -
code/__DEFINES/status_effects.dm | 4 +
code/__DEFINES/traits.dm | 3 +-
code/_onclick/hud/blob_overmind.dm | 3 +-
code/datums/mind.dm | 4 -
.../mood_events/generic_positive_events.dm | 10 ---
.../dynamic/dynamic_rulesets_roundstart.dm | 34 ---------
code/game/gamemodes/hivemind/hivemind.dm | 45 +++++------
code/game/gamemodes/hivemind/objectives.dm | 14 +---
code/game/gamemodes/hivemind/radar.dm | 74 +++++++++++++++++++
11 files changed, 105 insertions(+), 94 deletions(-)
create mode 100644 code/game/gamemodes/hivemind/radar.dm
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index 341cf1c6a942..ccdc70876238 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -76,6 +76,13 @@
/// Prevents hijacking same way as non-antags
#define HIJACK_PREVENT 2
+//Assimilation
+#define TRACKER_DEFAULT_TIME 900
+#define TRACKER_MINDSHIELD_TIME 1200
+#define TRACKER_AWAKENED_TIME 3000
+#define TRACKER_BONUS_LARGE 300
+#define TRACKER_BONUS_SMALL 100
+
//Syndicate Contracts
#define CONTRACT_STATUS_INACTIVE 1
#define CONTRACT_STATUS_ACTIVE 2
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index cb975ac3f8f2..07bb830ece9a 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -30,7 +30,6 @@
#define ROLE_BROTHER "Blood Brother"
#define ROLE_BRAINWASHED "Brainwashed Victim"
#define ROLE_HIVE "Hivemind Host"
-#define ROLE_HIVE_VESSEL "Awakened Vessel"
#define ROLE_OBSESSED "Obsessed"
#define ROLE_SENTIENCE "Sentience Potion Spawn"
#define ROLE_MIND_TRANSFER "Mind Transfer Potion"
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 3dcd959bd438..4afbccca45e9 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -137,6 +137,10 @@
#define STATUS_EFFECT_BUGGED /datum/status_effect/bugged //Lets other mobs listen in on what it hears
+#define STATUS_EFFECT_HIVE_TRACKER /datum/status_effect/hive_track
+
+#define STATUS_EFFECT_HIVE_RADAR /datum/status_effect/agent_pinpointer/hivemind
+
#define STATUS_EFFECT_BOUNTY /datum/status_effect/bounty //rewards the person who added this to the target with refreshed spells and a fair heal
#define STATUS_EFFECT_HELDUP /datum/status_effect/heldup // someone is currently pointing a gun at you
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index c28887f30f2a..bcfdfb97bfc0 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -220,7 +220,6 @@
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat
#define TRAIT_MASQUERADE "masquerade" // Falsifies Health analyzer blood levels
#define TRAIT_COLDBLOODED "coldblooded" // Your body is literal room temperature. Does not make you immune to the temp
-#define TRAIT_HIVE_BURNT "hive-burnt"
//non-mob traits
/// Used for limb-based paralysis, where replacing the limb will fix it.
@@ -322,7 +321,7 @@
#define LOCKED_HELMET_TRAIT "locked-helmet"
#define NINJA_SUIT_TRAIT "ninja-suit"
#define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant"
-#define HIVEMIND_TRAIT "hivemind-trait"
+#define HIVEMIND_ONE_MIND_TRAIT "one_mind"
#define VR_ZONE_TRAIT "vr_zone_trait"
#define GUARDIAN_TRAIT "guardian_trait"
#define RANDOM_BLACKOUTS "random_blackouts"
diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm
index e2c1c0a5712d..5e352112f26b 100644
--- a/code/_onclick/hud/blob_overmind.dm
+++ b/code/_onclick/hud/blob_overmind.dm
@@ -174,5 +174,4 @@
using = new /obj/screen/blob/RelocateCore()
using.screen_loc = ui_storage2
- static_inventory += using
-
+ static_inventory += using
\ No newline at end of file
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index a162b28a9552..43f063a24237 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -283,10 +283,6 @@
if(O)
O.unlock_code = null
-/datum/mind/proc/remove_from_hives()
- SIGNAL_HANDLER
- remove_hivemember(src)
-
/datum/mind/proc/remove_all_antag() //For the Lazy amongst us.
remove_changeling()
remove_traitor()
diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm
index 98dfa995ad6b..0fb6810f229d 100644
--- a/code/datums/mood_events/generic_positive_events.dm
+++ b/code/datums/mood_events/generic_positive_events.dm
@@ -114,16 +114,6 @@
mood_change = 10
hidden = TRUE
-/datum/mood_event/hivehost
- description = "Our psyche expands, our influence broadens.\n"
- mood_change = 5
- hidden = TRUE
-
-/datum/mood_event/hiveawakened
- description = "True purpose has been revealed to us, at last!.\n"
- mood_change = 2
- hidden = TRUE
-
/datum/mood_event/family_heirloom
description = "My family heirloom is safe with me.\n"
mood_change = 1
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index b4d71ab85c4d..6f75591d5968 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -1002,37 +1002,3 @@
if(!bloodsuckermind.make_bloodsucker(assigned_bloodsuckers))
assigned -= assigned_bloodsuckers
return TRUE
-
-//////////////////////////////////////////////
-// //
-// ASSIMILATION //
-// //
-//////////////////////////////////////////////
-
-/datum/dynamic_ruleset/roundstart/hivemind
- name = "Assimilation"
- antag_flag = ROLE_HIVE
- antag_datum = /datum/antagonist/hivemind
- protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
- restricted_roles = list("Cyborg","AI")
- required_candidates = 3
- weight = 3
- cost = 30
- requirements = list(100,90,80,60,40,30,10,10,10,10)
- flags = HIGH_IMPACT_RULESET
-
-/datum/dynamic_ruleset/roundstart/hivemind/pre_execute(population)
- . = ..()
- var/num_hosts = max( 3 , rand(0,1) + min(8, round(population / 8) ) )
- for (var/i = 1 to num_hosts)
- var/mob/M = pick_n_take(candidates)
- assigned += M.mind
- M.mind.restricted_roles = restricted_roles
- M.mind.special_role = ROLE_HIVE
- return TRUE
-
-/datum/dynamic_ruleset/roundstart/hivemind/execute()
- for(var/datum/mind/host in assigned)
- var/datum/antagonist/hivemind/new_antag = new antag_datum()
- host.add_antag_datum(new_antag)
- return TRUE
\ No newline at end of file
diff --git a/code/game/gamemodes/hivemind/hivemind.dm b/code/game/gamemodes/hivemind/hivemind.dm
index 4a97379aca08..593db3a265d9 100644
--- a/code/game/gamemodes/hivemind/hivemind.dm
+++ b/code/game/gamemodes/hivemind/hivemind.dm
@@ -1,15 +1,13 @@
-GLOBAL_LIST_EMPTY(hivehosts)
-
/datum/game_mode/hivemind
- name = "assimilation"
+ name = "Assimilation"
config_tag = "hivemind"
report_type = "hivemind"
antag_flag = ROLE_HIVE
false_report_weight = 5
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Brig Physician") //Yogs: Added "Brig Physician
restricted_jobs = list("Cyborg","AI")
- required_players = 30
- required_enemies = 3
+ required_players = 24
+ required_enemies = 2
recommended_enemies = 3
reroll_friendly = 1
enemy_minimum_age = 0
@@ -26,10 +24,15 @@ GLOBAL_LIST_EMPTY(hivehosts)
return
return M.mind.has_antag_datum(/datum/antagonist/hivemind)
-/mob/living/proc/is_real_hivehost()
- for(var/datum/antagonist/hivemind/hive as() in GLOB.hivehosts)
+/mob/living/proc/is_real_hivehost() //This proc ignores mind controlled vessels
+ for(var/datum/antagonist/hivemind/hive in GLOB.antagonists)
if(!hive.owner?.spell_list)
continue
+ var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in hive.owner.spell_list
+ if((!the_spell || !the_spell.active ) && mind == hive.owner)
+ return TRUE
+ if(the_spell?.active && the_spell.original_body == src)
+ return TRUE
return FALSE
/mob/living/proc/get_real_hivehost() //Returns src unless it's under mind control, then it returns the original body
@@ -38,6 +41,9 @@ GLOBAL_LIST_EMPTY(hivehosts)
return
if(!is_hivehost(M) || is_real_hivehost(M))
return M
+ var/obj/effect/proc_holder/spell/target_hive/hive_control/the_spell = locate(/obj/effect/proc_holder/spell/target_hive/hive_control) in M.mind.spell_list
+ if(the_spell?.active)
+ return the_spell.original_body
return M
/proc/is_hivemember(mob/living/L)
@@ -46,7 +52,7 @@ GLOBAL_LIST_EMPTY(hivehosts)
var/datum/mind/M = L.mind
if(!M)
return FALSE
- for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
+ for(var/datum/antagonist/hivemind/H in GLOB.antagonists)
if(H.hivemembers.Find(M))
return TRUE
return FALSE
@@ -55,7 +61,7 @@ GLOBAL_LIST_EMPTY(hivehosts)
var/datum/mind/M = L?.mind
if(!M)
return
- for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
+ for(var/datum/antagonist/hivemind/H in GLOB.antagonists)
if(H.hivemembers.Find(M))
H.hivemembers -= M
H.calc_size()
@@ -71,7 +77,7 @@ GLOBAL_LIST_EMPTY(hivehosts)
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
- var/num_hosts = max( 3 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra
+ var/num_hosts = max( 1 , rand(0,1) + min(8, round(num_players() / 8) ) ) //1 host for every 8 players up to 64, with a 50% chance of an extra
for(var/j = 0, j < num_hosts, j++)
if (!antag_candidates.len)
@@ -98,21 +104,4 @@ GLOBAL_LIST_EMPTY(hivehosts)
/datum/game_mode/hivemind/generate_report()
return "Reports of psychic activity have been showing up in this sector, and we believe this may have to do with a containment breach on \[REDACTED\] last month \
when a sapient hive intelligence displaying paranormal powers escaped into the unknown. They present a very large risk as they can assimilate people into \
- the hivemind with ease, although they appear unable to affect mindshielded personnel."
-
-/datum/game_mode/hivemind/generate_credit_text()
- var/list/round_credits = list()
- var/len_before_addition
-
- for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
- round_credits += "Hive [H.hiveID]:
"
- len_before_addition = round_credits.len
- round_credits += "[H.name] as the Hivemind Host
"
- for(var/datum/antagonist/hivevessel/V as() in H.avessels)
- round_credits += "[V.name] as an Awakened Vessel
"
- if(len_before_addition == round_credits.len)
- round_credits += list("Hive [H.hiveID] couldn't withstand the competition!
")
- round_credits += "
"
-
- round_credits += ..()
- return round_credits
\ No newline at end of file
+ the hivemind with ease, although they appear unable to affect mindshielded personnel."
\ No newline at end of file
diff --git a/code/game/gamemodes/hivemind/objectives.dm b/code/game/gamemodes/hivemind/objectives.dm
index 749cac2165aa..00c0245e4071 100644
--- a/code/game/gamemodes/hivemind/objectives.dm
+++ b/code/game/gamemodes/hivemind/objectives.dm
@@ -30,18 +30,6 @@
/datum/objective/hivemind/hiveescape/update_explanation_text()
explanation_text = "Have at least [target_amount] members of the hive escape on the shuttle alive and free."
-/datum/objective/hivemind/dominance/New()
- update_explanation_text()
-
-/datum/objective/hivemind/dominance/update_explanation_text()
- explanation_text = "Assert dominance after having twenty more vessels and more integrations than any other hive."
-
-/datum/objective/hivemind/dominance/check_completion()
- var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind)
- if(!host)
- return ..()
- return host?.unlocked_dominance || ..()
-
/datum/objective/hivemind/hiveescape/check_completion()
if(..())
return TRUE
@@ -63,7 +51,7 @@
var/datum/antagonist/hivemind/host = owner.has_antag_datum(/datum/antagonist/hivemind)
if(!host)
return FALSE
- for(var/datum/antagonist/hivemind/H as() in GLOB.hivehosts)
+ for(var/datum/antagonist/hivemind/H in GLOB.antagonists)
if(H == host)
continue
if(H.hive_size >= host.hive_size)
diff --git a/code/game/gamemodes/hivemind/radar.dm b/code/game/gamemodes/hivemind/radar.dm
new file mode 100644
index 000000000000..27c1154d8d6a
--- /dev/null
+++ b/code/game/gamemodes/hivemind/radar.dm
@@ -0,0 +1,74 @@
+#define HIVEMIND_RADAR_MIN_DISTANCE 0 //Very generous, as the targets are only tracked for a few minutes.
+#define HIVEMIND_RADAR_MAX_DISTANCE 50
+#define HIVEMIND_RADAR_PING_TIME 40 //4s update time.
+
+//Modified IA/changeling pinpointer, points to the nearest person who is afflicted with the hive tracker status effect
+/datum/status_effect/agent_pinpointer/hivemind
+ id = "hive_pinpointer"
+ alert_type = /obj/screen/alert/status_effect/agent_pinpointer/hivemind
+ minimum_range = HIVEMIND_RADAR_MIN_DISTANCE
+ tick_interval = HIVEMIND_RADAR_PING_TIME
+ range_fuzz_factor = 0
+
+/datum/status_effect/agent_pinpointer/hivemind/point_to_target() //If we found what we're looking for, show the distance and direction
+ if(scan_target)
+ if(owner.mind)
+ var/datum/antagonist/hivemind/hive = owner.mind.has_antag_datum(/datum/antagonist/hivemind)
+ if(hive)
+ range_far = range_mid * (2-hive.get_threat_multiplier())
+ if(scan_target.mind)
+ var/datum/antagonist/hivemind/enemy_hive = scan_target.mind.has_antag_datum(/datum/antagonist/hivemind)
+ if(enemy_hive)
+ range_far = max(range_mid * (1+enemy_hive.get_threat_multiplier()), range_far)
+
+ ..()
+
+/datum/status_effect/agent_pinpointer/hivemind/scan_for_target()
+ var/turf/my_loc = get_turf(owner)
+
+ var/list/mob/living/carbon/targets = list()
+ var/trackable_targets_exist = FALSE
+
+ for(var/mob/living/carbon/C in GLOB.alive_mob_list)
+ if(C == owner)
+ continue
+ var/datum/status_effect/hive_track/mark = C.has_status_effect(STATUS_EFFECT_HIVE_TRACKER)
+ if(mark && mark.tracked_by == owner)
+ trackable_targets_exist = TRUE
+ var/their_loc = get_turf(C)
+ var/distance = get_dist_euclidian(my_loc, their_loc)
+ if (distance < HIVEMIND_RADAR_MAX_DISTANCE)
+ var/multiplier = 0.5
+ if(C.mind)
+ var/datum/antagonist/hivemind/hive = C.mind.has_antag_datum(/datum/antagonist/hivemind)
+ if(hive)
+ multiplier = hive.get_threat_multiplier()
+ targets[C] = ((HIVEMIND_RADAR_MAX_DISTANCE ** 2) - (distance ** 2)) * multiplier
+
+ if(targets.len)
+ scan_target = pickweight(targets) //Point at a 'random' target, biasing heavily towards closer ones.
+ else
+ scan_target = null
+ if(!trackable_targets_exist)
+ to_chat(owner, span_assimilator("The psychic energies eminating from afar have died down... for now"))
+ owner.remove_status_effect(STATUS_EFFECT_HIVE_RADAR)
+
+//"Trackable" status effect
+/datum/status_effect/hive_track
+ id = "hive_track"
+ duration = 1200
+ status_type = STATUS_EFFECT_MULTIPLE
+ alert_type = null
+ var/mob/living/tracked_by
+
+/datum/status_effect/hive_track/on_creation(mob/living/new_owner, mob/living/hunter, set_duration)
+ . = ..()
+ if(.)
+ tracked_by = hunter
+ if(isnum(set_duration))
+ duration = world.time + set_duration
+
+//Screen alert
+/obj/screen/alert/status_effect/agent_pinpointer/hivemind
+ name = "Psychic link"
+ desc = "Somebody is there, and they're definitely not friendly."
From 3327242e84ca5a3b21e927ba848769d96d307cfd Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Mon, 11 Jul 2022 14:39:26 +0300
Subject: [PATCH 49/55] amongus
---
code/game/gamemodes/hivemind/hivemind.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/game/gamemodes/hivemind/hivemind.dm b/code/game/gamemodes/hivemind/hivemind.dm
index 593db3a265d9..28838d59675e 100644
--- a/code/game/gamemodes/hivemind/hivemind.dm
+++ b/code/game/gamemodes/hivemind/hivemind.dm
@@ -104,4 +104,4 @@
/datum/game_mode/hivemind/generate_report()
return "Reports of psychic activity have been showing up in this sector, and we believe this may have to do with a containment breach on \[REDACTED\] last month \
when a sapient hive intelligence displaying paranormal powers escaped into the unknown. They present a very large risk as they can assimilate people into \
- the hivemind with ease, although they appear unable to affect mindshielded personnel."
\ No newline at end of file
+ the hivemind with ease, although they appear unable to affect mindshielded personnel."
From 90b406fbb08bded0dd1f85454a7938e7a2d32260 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Thu, 14 Jul 2022 14:09:42 +0300
Subject: [PATCH 50/55] removes inflitrators from the game
---
.../dynamic/dynamic_rulesets_midround.dm | 41 ++++++++++++++
.../dynamic/dynamic_rulesets_roundstart.dm | 56 +++++++++++++++++++
.../code/modules/events/infiltrators.dm | 4 +-
3 files changed, 99 insertions(+), 2 deletions(-)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index a787074ca67a..12f83d7e4d9c 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -348,6 +348,47 @@
else
return ..()
+//////////////////////////////////////////////
+// //
+// INFILTRATORS (MIDROUND) //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/midround/from_ghosts/infiltration
+ name = "Infiltration"
+ antag_flag = ROLE_INFILTRATOR
+ antag_datum = ANTAG_DATUM_INFILTRATOR
+ enemy_roles = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain")
+ required_enemies = list(3,3,3,3,2,2,1,1,0,0)
+ required_candidates = 5
+ weight = 3
+ cost = 22
+ requirements = list(90,90,90,80,60,40,30,20,10,10)
+ var/list/agents_cap = list(2,2,3,3,4,5,5,5,5,5)
+ var/datum/team/infiltrator/sit_team
+ flags = HIGH_IMPACT_RULESET
+ minimum_players = 35
+
+/datum/dynamic_ruleset/midround/from_ghosts/infiltration/acceptable(population=0, threat=0)
+ if (locate(/datum/dynamic_ruleset/roundstart/infiltration) in mode.executed_rules)
+ return FALSE
+ indice_pop = min(agents_cap.len, round(living_players.len/5)+1)
+ required_candidates = agents_cap[indice_pop]
+ return ..()
+
+/datum/dynamic_ruleset/midround/from_ghosts/infiltration/ready(forced = FALSE)
+ if (required_candidates > (dead_players.len + list_observers.len))
+ return FALSE
+ return ..()
+
+/datum/dynamic_ruleset/midround/from_ghosts/infiltration/finish_setup(mob/new_character, index)
+ new_character.mind.special_role = "Syndicate Infiltrator"
+ new_character.mind.assigned_role = "Syndicate Infiltrator"
+ if(!sit_team)
+ sit_team = new /datum/team/infiltrator
+ sit_mind.add_antag_datum(ANTAG_DATUM_INFILTRATOR, sit_team)
+ sit_team.update_objectives()
+
//////////////////////////////////////////////
// //
// BLOB (GHOST) //
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index 6f75591d5968..c2a57d3826bb 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -357,6 +357,62 @@
SSticker.mode_result = "halfwin - interrupted"
SSticker.news_report = OPERATIVE_SKIRMISH
+//////////////////////////////////////////////
+// //
+// INFILTRATORS //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/roundstart/infiltration
+ name = "Infiltration"
+ antag_flag = ROLE_INFILTRATOR
+ antag_datum = ANTAG_DATUM_INFILTRATOR
+ minimum_required_age = 14
+ restricted_roles = list("Head of Security", "Captain")
+ required_candidates = 5
+ weight = 4
+ cost = 18
+ requirements = list(90,90,90,80,60,40,30,20,10,10)
+ flags = HIGH_IMPACT_RULESET
+ antag_cap = list("denominator" = 15, "offset" = 1)
+ var/datum/team/infiltrator/sit_team
+ minimum_players = 30
+
+/datum/dynamic_ruleset/roundstart/infiltration/ready(population, forced = FALSE)
+ required_candidates = get_antag_cap(population)
+ . = ..()
+
+/datum/dynamic_ruleset/roundstart/infiltration/pre_execute(population)
+ . = ..()
+ var/inflitrators_amount = get_antag_cap(population)
+ for(var/i = 1 to inflitrators_amount)
+ if(candidates.len <= 0)
+ break
+ var/mob/M = pick_n_take(candidates)
+ assigned += M.mind
+ M.mind.assigned_role = "Syndicate Infiltrator"
+ M.mind.special_role = "Syndicate Infiltrator"
+ return TRUE
+
+/datum/dynamic_ruleset/roundstart/infiltration/execute()
+ sit_team = new /datum/team/infiltrator
+ for(var/datum/mind/sit_mind in assigned)
+ sit_mind.add_antag_datum(ANTAG_DATUM_INFILTRATOR, sit_team)
+ sit_team.update_objectives()
+ return TRUE
+
+/datum/dynamic_ruleset/roundstart/infiltration/round_result()
+ var/result = sit_team.get_result()
+ switch(result)
+ if(INFILTRATION_ALLCOMPLETE)
+ SSticker.mode_result = "major win - objectives complete"
+ if(INFILTRATION_MOSTCOMPLETE)
+ SSticker.mode_result = "minor win - most objectives complete"
+ if(INFILTRATION_SOMECOMPLETE)
+ SSticker.mode_result = "neutral - some objectives complete"
+ else
+ SSticker.mode_result = "loss - no objectives complete"
+
//////////////////////////////////////////////
// //
// REVS //
diff --git a/yogstation/code/modules/events/infiltrators.dm b/yogstation/code/modules/events/infiltrators.dm
index 804cac1a3ce2..6aa80dbe6d68 100644
--- a/yogstation/code/modules/events/infiltrators.dm
+++ b/yogstation/code/modules/events/infiltrators.dm
@@ -2,13 +2,13 @@
name = "Infiltrators"
typepath = /datum/round_event/ghost_role/infiltrators
- weight = 0
+ weight = 8
max_occurrences = 1
earliest_start = 30 MINUTES
min_players = 23
- gamemode_blacklist = list("nuclear","wizard","revolution","abduction","infiltration","gang","cult","clockcult","darkspawn")
+ gamemode_blacklist = list("nuclear","wizard","revolution","abduction","infiltration","gang","cult","clockcult","darkspawn","dynamic")
/datum/round_event_control/infiltrators/canSpawnEvent(var/players_amt, var/gamemode)
. = ..()
From 5669982d6a9fbed68a27f44aaefedd92698f1d18 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Thu, 14 Jul 2022 14:16:51 +0300
Subject: [PATCH 51/55] e
---
config/game_options.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/game_options.txt b/config/game_options.txt
index 52aebab2338e..24085de9adfe 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -106,7 +106,7 @@ ALERT_DELTA Destruction of the station is imminent. All crew are instructed to o
# New
PROBABILITY DARKSPAWN 6
PROBABILITY HERESY 4
-PROBABILITY INFILTRATION 4
+PROBABILITY INFILTRATION 0
PROBABILITY BLOODSUCKER 4
# Lowpop
From 1516b9363145ef91bc0726be9d043def793fd601 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+TymurShatillo@users.noreply.github.com>
Date: Thu, 14 Jul 2022 14:21:21 +0300
Subject: [PATCH 52/55] fix
---
code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index 12f83d7e4d9c..fabff1688191 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -386,7 +386,7 @@
new_character.mind.assigned_role = "Syndicate Infiltrator"
if(!sit_team)
sit_team = new /datum/team/infiltrator
- sit_mind.add_antag_datum(ANTAG_DATUM_INFILTRATOR, sit_team)
+ new_character.mind.add_antag_datum(ANTAG_DATUM_INFILTRATOR, sit_team)
sit_team.update_objectives()
//////////////////////////////////////////////
From f49f0c31fb147ae4e9e7d85b2e9bb2cd50e65413 Mon Sep 17 00:00:00 2001
From: SuperSlayer <91609255+SuperSlayer0@users.noreply.github.com>
Date: Sun, 28 Aug 2022 15:27:46 +0300
Subject: [PATCH 53/55] sex
---
config/game_options.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/game_options.txt b/config/game_options.txt
index 24085de9adfe..11b58159881f 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -106,7 +106,7 @@ ALERT_DELTA Destruction of the station is imminent. All crew are instructed to o
# New
PROBABILITY DARKSPAWN 6
PROBABILITY HERESY 4
-PROBABILITY INFILTRATION 0
+PROBABILITY INFILTRATION 2
PROBABILITY BLOODSUCKER 4
# Lowpop
From 035ae2ccad37526e09de90a7f70217344ec7b35f Mon Sep 17 00:00:00 2001
From: TheGamerdk <5618080+TheGamerdk@users.noreply.github.com>
Date: Sat, 10 Sep 2022 19:56:43 +0200
Subject: [PATCH 54/55] Update yogstation/code/modules/events/infiltrators.dm
---
yogstation/code/modules/events/infiltrators.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/yogstation/code/modules/events/infiltrators.dm b/yogstation/code/modules/events/infiltrators.dm
index 6aa80dbe6d68..0d761a8323a1 100644
--- a/yogstation/code/modules/events/infiltrators.dm
+++ b/yogstation/code/modules/events/infiltrators.dm
@@ -2,7 +2,7 @@
name = "Infiltrators"
typepath = /datum/round_event/ghost_role/infiltrators
- weight = 8
+ weight = 0
max_occurrences = 1
earliest_start = 30 MINUTES
From 0ad50612b6954c83a917199564318d475518599b Mon Sep 17 00:00:00 2001
From: Jamie D <993128+JamieD1@users.noreply.github.com>
Date: Sat, 17 Sep 2022 12:13:59 +0100
Subject: [PATCH 55/55] Update config/game_options.txt
---
config/game_options.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/game_options.txt b/config/game_options.txt
index 11b58159881f..52aebab2338e 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -106,7 +106,7 @@ ALERT_DELTA Destruction of the station is imminent. All crew are instructed to o
# New
PROBABILITY DARKSPAWN 6
PROBABILITY HERESY 4
-PROBABILITY INFILTRATION 2
+PROBABILITY INFILTRATION 4
PROBABILITY BLOODSUCKER 4
# Lowpop