From bea8d72e716661a509c80d7cd2e47e483f339928 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sat, 3 Jul 2021 02:17:50 +0200 Subject: [PATCH] [MIRROR] Adds blob as a midround antag like midround traitors, where it does not require a ghost role (#6661) * Adds blob as a midround antag like midround traitors, where it does not require a ghost role * Update dynamic.json Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com> Co-authored-by: Gandalf --- code/__DEFINES/antagonists.dm | 7 + code/_onclick/hud/blob_overmind.dm | 2 +- .../dynamic/dynamic_rulesets_midround.dm | 37 +- code/modules/antagonists/blob/blob.dm | 61 ++- code/modules/antagonists/blob/overmind.dm | 2 +- code/modules/antagonists/blob/powers.dm | 8 +- config/dynamic.json | 390 +++++++----------- sound/ambience/antag/blobalert.ogg | Bin 0 -> 13598 bytes 8 files changed, 241 insertions(+), 266 deletions(-) create mode 100644 sound/ambience/antag/blobalert.ogg diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index cff68506b42..b9f554fd78e 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -71,6 +71,13 @@ GLOBAL_LIST_INIT(heretic_start_knowledge,list(/datum/eldritch_knowledge/spell/ba #define PATH_FLESH "Flesh" #define PATH_VOID "Void" +/// Forces the blob to place the core where they currently are, ignoring any checks. +#define BLOB_FORCE_PLACEMENT -1 +/// Normal blob placement, does the regular checks to make sure the blob isn't placing itself in an invalid location +#define BLOB_NORMAL_PLACEMENT 0 +/// Selects a random location for the blob to be placed. +#define BLOB_RANDOM_PLACEMENT 1 + #define CONSTRUCT_JUGGERNAUT "Juggernaut" #define CONSTRUCT_WRAITH "Wraith" #define CONSTRUCT_ARTIFICER "Artificer" diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index 5af4f278788..dd3224c5500 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -49,7 +49,7 @@ if(isovermind(usr)) var/mob/camera/blob/B = usr if(!B.placed) - B.place_blob_core(0) + B.place_blob_core(BLOB_NORMAL_PLACEMENT) B.transport_core() /atom/movable/screen/blob/blobbernaut diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 68012c8afa3..dd77eb35ec9 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -444,7 +444,7 @@ enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_candidates = 1 - weight = 4 + weight = 2 cost = 10 requirements = list(101,101,101,80,60,50,30,20,10,10) repeatable = TRUE @@ -453,6 +453,41 @@ var/body = applicant.become_overmind() return body +/// Infects a random player, making them explode into a blob. +/datum/dynamic_ruleset/midround/blob_infection + name = "Blob Infection" + antag_datum = /datum/antagonist/blob + antag_flag = ROLE_BLOB + protected_roles = list("Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain") + restricted_roles = list("Cyborg", "AI", "Positronic Brain") + enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") + required_enemies = list(2,2,1,1,1,1,1,0,0,0) + required_candidates = 1 + weight = 2 + cost = 10 + requirements = list(101,101,101,80,60,50,30,20,10,10) + repeatable = TRUE + +/datum/dynamic_ruleset/midround/blob_infection/trim_candidates() + ..() + candidates = living_players + for(var/mob/living/player as anything in candidates) + var/turf/player_turf = get_turf(player) + if(!player_turf || !is_station_level(player_turf.z)) + candidates -= player + continue + + if(player.mind && (player.mind.special_role || length(player.mind.antag_datums) > 0)) + candidates -= player + +/datum/dynamic_ruleset/midround/blob_infection/execute() + if(!candidates || !candidates.len) + return FALSE + var/mob/living/carbon/human/blob_antag = pick_n_take(candidates) + assigned += blob_antag.mind + blob_antag.mind.special_role = antag_flag + return ..() + ////////////////////////////////////////////// // // // XENOMORPH (GHOST) // diff --git a/code/modules/antagonists/blob/blob.dm b/code/modules/antagonists/blob/blob.dm index 216352809f8..a8c54453f68 100644 --- a/code/modules/antagonists/blob/blob.dm +++ b/code/modules/antagonists/blob/blob.dm @@ -19,13 +19,25 @@ return basic_report /datum/antagonist/blob/greet() + to_chat(owner.current, span_notice("You are the Blob!")) + owner.announce_objectives() if(!isovermind(owner.current)) - to_chat(owner,span_userdanger("You feel bloated.")) + to_chat(owner.current, span_notice("Use the pop ability to place your blob core! It is recommended you do this away from anyone else, as you'll be taking on the entire crew!")) + + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/blobalert.ogg', 100, FALSE, pressure_affected = FALSE, use_reverb = FALSE) /datum/antagonist/blob/on_gain() create_objectives() . = ..() +/datum/antagonist/blob/remove_innate_effects() + QDEL_NULL(pop_action) + return ..() + +/datum/antagonist/blob/farewell() + to_chat(owner.current, "You are no longer the Blob!") + return ..() + /datum/antagonist/blob/proc/create_objectives() var/datum/objective/blob_takeover/main = new main.owner = owner @@ -47,20 +59,51 @@ icon_icon = 'icons/mob/blob.dmi' button_icon_state = "blob" -/datum/action/innate/blobpop/Activate() + /// The time taken before this ability is automatically activated. + var/autoplace_time = OVERMIND_STARTING_AUTO_PLACE_TIME + +/datum/action/innate/blobpop/Grant(Target) + . = ..() + if(owner) + addtimer(CALLBACK(src, .proc/Activate, TRUE), autoplace_time, TIMER_UNIQUE|TIMER_OVERRIDE) + to_chat(owner, "You will automatically pop and place your blob core in [DisplayTimeText(autoplace_time)].") + +/datum/action/innate/blobpop/Activate(timer_activated = FALSE) var/mob/living/old_body = owner + if(!owner) + return + var/datum/antagonist/blob/blobtag = owner.mind.has_antag_datum(/datum/antagonist/blob) if(!blobtag) - Remove() + Remove(owner) return - var/mob/camera/blob/B = new /mob/camera/blob(get_turf(old_body), blobtag.starting_points_human_blob) - owner.mind.transfer_to(B) + + . = TRUE + var/turf/target_turf = get_turf(owner) + if(target_turf.density) + to_chat(owner, "This spot is too dense to place a blob core on!") + . = FALSE + var/area/target_area = get_area(target_turf) + if(isspaceturf(target_turf) || !(target_area?.area_flags & BLOBS_ALLOWED) || !is_station_level(target_turf.z)) + to_chat(owner, "You cannot place your core here!") + . = FALSE + + var/placement_override = BLOB_FORCE_PLACEMENT + if(!.) + if(!timer_activated) + return + placement_override = BLOB_RANDOM_PLACEMENT + to_chat(owner, "Because your current location is an invalid starting spot and you need to pop, you've been moved to a random location!") + + var/mob/camera/blob/blob_cam = new /mob/camera/blob(get_turf(old_body), blobtag.starting_points_human_blob) + owner.mind.transfer_to(blob_cam) old_body.gib() - B.place_blob_core(placement_override = TRUE, pop_override = TRUE) + blob_cam.place_blob_core(placement_override, pop_override = TRUE) + playsound(get_turf(blob_cam), 'sound/ambience/antag/blobalert.ogg', 50, FALSE) /datum/antagonist/blob/antag_listing_status() . = ..() if(owner?.current) - var/mob/camera/blob/B = owner.current - if(istype(B)) - . += "(Progress: [B.blobs_legit.len]/[B.blobwincount])" + var/mob/camera/blob/blob_cam = owner.current + if(istype(blob_cam)) + . += "(Progress: [length(blob_cam.blobs_legit)]/[blob_cam.blobwincount])" diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index 5e7c5c59ef3..b843c7d9d89 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -114,7 +114,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) to_chat(src, span_big("You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)].")) manualplace_min_time = 0 if(autoplace_max_time && world.time >= autoplace_max_time) - place_blob_core(1) + place_blob_core(BLOB_RANDOM_PLACEMENT) else qdel(src) else if(!victory_in_progress && (blobs_legit.len >= blobwincount)) diff --git a/code/modules/antagonists/blob/powers.dm b/code/modules/antagonists/blob/powers.dm index 7412cd5f687..46349c8e6bb 100644 --- a/code/modules/antagonists/blob/powers.dm +++ b/code/modules/antagonists/blob/powers.dm @@ -7,10 +7,10 @@ add_points(-cost) return TRUE -/mob/camera/blob/proc/place_blob_core(placement_override, pop_override = FALSE) - if(placed && placement_override != -1) +/mob/camera/blob/proc/place_blob_core(placement_override = BLOB_NORMAL_PLACEMENT, pop_override = FALSE) + if(placed && placement_override != BLOB_FORCE_PLACEMENT) return TRUE - if(!placement_override) + if(placement_override == BLOB_NORMAL_PLACEMENT) if(!pop_override) for(var/mob/living/M in range(7, src)) if(ROLE_BLOB in M.faction) @@ -45,7 +45,7 @@ if(!pop_override && world.time <= manualplace_min_time && world.time <= autoplace_max_time) to_chat(src, span_warning("It is too early to place your blob core!")) return FALSE - else if(placement_override == 1) + else if(placement_override == BLOB_RANDOM_PLACEMENT) var/turf/T = pick(GLOB.blobstart) forceMove(T) //got overrided? you're somewhere random, motherfucker if(placed && blob_core) diff --git a/config/dynamic.json b/config/dynamic.json index 519796b79f1..c503697963f 100644 --- a/config/dynamic.json +++ b/config/dynamic.json @@ -1,252 +1,142 @@ { - "Dynamic": { - "threat_curve_centre": -3, - "threat_curve_width": 1.4, - "roundstart_split_curve_centre": 3, - "roundstart_split_curve_width": 1.2, - "midround_delay_min": 18000, - "midround_delay_max": 30000, - "latejoin_delay_min": 6000, - "latejoin_delay_max": 15000 - }, - "Roundstart": { - "Traitors": { - "antag_cap": { - "denominator": 40 - }, - "protected_roles": [ - "Prisoner", - "Vanguard Operative", - "Civil Disputes Officer", - "Security Medic", - "Security Sergeant", - "Security Officer", - "Corrections Officer", - "Warden", - "Detective", - "Head of Security", - "Blueshield", - "Head of Personnel", - "Quartermaster", - "Chief Engineer", - "Chief Medical Officer", - "Research Director", - "Captain" - ], - "restricted_roles": [ - "Cyborg" - ] - }, - "Blood Brothers": { - "weight": 0 - }, - "Changelings": { - "protected_roles": [ - "Prisoner", - "Vanguard Operative", - "Civil Disputes Officer", - "Security Medic", - "Security Sergeant", - "Security Officer", - "Corrections Officer", - "Warden", - "Detective", - "Head of Security", - "Blueshield", - "Head of Personnel", - "Quartermaster", - "Chief Engineer", - "Chief Medical Officer", - "Research Director", - "Captain" - ], - "restricted_roles": [ - "Cyborg" - ] - }, - "Heretics": { - "weight": 2, - "scaling_cost": 12, - "protected_roles": [ - "Prisoner", - "Vanguard Operative", - "Civil Disputes Officer", - "Security Medic", - "Security Sergeant", - "Security Officer", - "Corrections Officer", - "Warden", - "Detective", - "Head of Security", - "Blueshield", - "Head of Personnel", - "Quartermaster", - "Chief Engineer", - "Chief Medical Officer", - "Research Director", - "Captain" - ], - "restricted_roles": [ - "Cyborg" - ] - }, - "Wizard": { - "weight": 1, - "protected_roles": [ - "Prisoner", - "Vanguard Operative", - "Civil Disputes Officer", - "Security Medic", - "Security Sergeant", - "Security Officer", - "Corrections Officer", - "Warden", - "Detective", - "Head of Security", - "Blueshield", - "Head of Personnel", - "Quartermaster", - "Chief Engineer", - "Chief Medical Officer", - "Research Director", - "Captain" - ], - "restricted_roles": [ - "Cyborg" - ] - }, - "Blood Cult": { - "weight": 0 - }, - "Clockwork Cult": { - "weight": 0 - }, - "Nuclear Emergency": { - "weight": 0 - }, - "Revolution": { - "weight": 0 - }, - "Families": { - "weight": 0 - } - }, - "Midround": { - "Syndicate Sleeper Agent": { - "protected_roles": [ - "Prisoner", - "Vanguard Operative", - "Civil Disputes Officer", - "Security Medic", - "Security Sergeant", - "Security Officer", - "Corrections Officer", - "Warden", - "Detective", - "Head of Security", - "Blueshield", - "Head of Personnel", - "Quartermaster", - "Chief Engineer", - "Chief Medical Officer", - "Research Director", - "Captain" - ], - "restricted_roles": [ - "Cyborg" - ] - }, - "Family Head Aspirants": { - "weight": 0 - }, - "Nuclear Assault": { - "weight": 0 - }, - "Space Dragon": { - "weight": 1 - }, - "Blob": { - "weight": 1 - }, - "Spiders": { - "weight": 1 - }, - "Alien Infestation": { - "weight": 1 - } - }, - "Latejoin": { - "Syndicate Infiltrator": { - "protected_roles": [ - "Prisoner", - "Vanguard Operative", - "Civil Disputes Officer", - "Security Medic", - "Security Sergeant", - "Security Officer", - "Corrections Officer", - "Warden", - "Detective", - "Head of Security", - "Blueshield", - "Head of Personnel", - "Quartermaster", - "Chief Engineer", - "Chief Medical Officer", - "Research Director", - "Captain" - ], - "restricted_roles": [ - "Cyborg" - ] - }, - "Provocateur": { - "protected_roles": [ - "Prisoner", - "Vanguard Operative", - "Civil Disputes Officer", - "Security Medic", - "Security Sergeant", - "Security Officer", - "Corrections Officer", - "Warden", - "Detective", - "Head of Security", - "Blueshield", - "Head of Personnel", - "Quartermaster", - "Chief Engineer", - "Chief Medical Officer", - "Research Director", - "Captain" - ], - "restricted_roles": [ - "Cyborg" - ] - }, - "Heretic Smuggler": { - "protected_roles": [ - "Prisoner", - "Vanguard Operative", - "Civil Disputes Officer", - "Security Medic", - "Security Sergeant", - "Security Officer", - "Corrections Officer", - "Warden", - "Detective", - "Head of Security", - "Blueshield", - "Head of Personnel", - "Quartermaster", - "Chief Engineer", - "Chief Medical Officer", - "Research Director", - "Captain" - ], - "restricted_roles": [ - "Cyborg" - ] - } - } + "Dynamic": {}, + "Roundstart": { + "Traitors": { + "cost": 8, + "scaling_cost": 9, + "weight": 0, + "required_candidates": 1, + "minimum_required_age": 0, + "requirements": [ + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "antag_cap": { + "denominator": 24 + }, + "protected_roles": [ + "Prisoner", + "Security Officer", + "Warden", + "Detective", + "Head of Security", + "Captain" + ], + "restricted_roles": [ + "Cyborg" + ] + }, + + "Blood Brothers": { + "weight": 0 + }, + + "Changelings": { + "weight": 0 + }, + + "Heretics": { + "weight": 0 + }, + + "Wizard": { + "weight": 0 + }, + + "Blood Cult": { + "weight": 0 + }, + + "Nuclear Emergency": { + "weight": 0 + }, + + "Revolution": { + "weight": 0 + }, + + "Families": { + "weight": 0 + } + }, + + "Midround": { + "Syndicate Sleeper Agent": { + "weight": 0 + }, + + "Family Head Aspirants": { + "weight": 0 + }, + + "Malfunctioning AI": { + "weight": 0 + }, + + "Wizard": { + "weight": 0 + }, + + "Nuclear Assault": { + "weight": 0 + }, + + "Blob": { + "weight": 0 + }, + + "Blob Infection": { + "weight": 0 + }, + + "Alien Infestation": { + "weight": 0 + }, + + "Nightmare": { + "weight": 0 + }, + + "Space Dragon": { + "weight": 0 + }, + + "Abductors": { + "weight": 0 + }, + + "Swarmers": { + "weight": 0 + }, + + "Space Ninja": { + "weight": 0 + }, + + "Spiders": { + "weight": 0 + } + }, + + "Latejoin": { + "Syndicate Infiltrator": { + "weight": 0 + }, + + "Provocateur": { + "weight": 0 + }, + + "Heretic Smuggler": { + "weight": 0 + } + } } diff --git a/sound/ambience/antag/blobalert.ogg b/sound/ambience/antag/blobalert.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c9fcfbee4489f64d46f149942fc45c70c7b0826a GIT binary patch literal 13598 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 XKS@Gry7@zx==e?|zp+{agC6)lGke}8 literal 0 HcmV?d00001