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