Ports some funni midround rulesets from TG (#13971)

* Sussy baka

* Update blob.dm

* Update blob.dm
This commit is contained in:
SuperSlayer
2022-05-21 14:58:24 +03:00
committed by GitHub
parent 2b7c9e4a56
commit 1686764c32
6 changed files with 201 additions and 11 deletions

View File

@@ -32,10 +32,17 @@
/// blob gets a free reroll every X time /// blob gets a free reroll every X time
#define BLOB_REROLL_TIME 2400 #define BLOB_REROLL_TIME 2400
#define BLOB_SPREAD_COST 4 #define BLOB_SPREAD_COST 4
#define OVERMIND_STARTING_AUTO_PLACE_TIME 6 MINUTES
/// blob refunds this much if it attacks and doesn't spread /// blob refunds this much if it attacks and doesn't spread
#define BLOB_ATTACK_REFUND 2 #define BLOB_ATTACK_REFUND 2
#define BLOB_REFLECTOR_COST 15 #define BLOB_REFLECTOR_COST 15
/// 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
//ERT Types //ERT Types
#define ERT_BLUE "Blue" #define ERT_BLUE "Blue"

View File

@@ -60,6 +60,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
/// Blocks ruins spawning on the turf /// Blocks ruins spawning on the turf
#define NO_RUINS_1 (1<<10) #define NO_RUINS_1 (1<<10)
/// If blobs can spawn there and if it counts towards their score.
#define BLOBS_ALLOWED (1<<1)
/* /*
These defines are used specifically with the atom/pass_flags bitmask These defines are used specifically with the atom/pass_flags bitmask
the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example) the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example)

View File

@@ -48,7 +48,7 @@
if(isovermind(usr)) if(isovermind(usr))
var/mob/camera/blob/B = usr var/mob/camera/blob/B = usr
if(!B.placed) if(!B.placed)
B.place_blob_core(0) B.place_blob_core(BLOB_NORMAL_PLACEMENT)
B.transport_core() B.transport_core()
/obj/screen/blob/Blobbernaut /obj/screen/blob/Blobbernaut

View File

@@ -361,7 +361,7 @@
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain") enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0) required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_candidates = 1 required_candidates = 1
weight = 4 weight = 2
cost = 10 cost = 10
requirements = list(100,100,100,80,60,50,45,30,20,20) requirements = list(100,100,100,80,60,50,45,30,20,20)
repeatable = TRUE repeatable = TRUE
@@ -370,6 +370,41 @@
var/body = applicant.become_overmind() var/body = applicant.become_overmind()
return body 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) // // XENOMORPH (GHOST) //
@@ -653,3 +688,109 @@
message_admins("[ADMIN_LOOKUPFLW(selected_mobs)] was selected by the [name] ruleset and has been made into a midround Bloodsucker.") message_admins("[ADMIN_LOOKUPFLW(selected_mobs)] was selected by the [name] ruleset and has been made into a midround Bloodsucker.")
log_game("DYNAMIC: [key_name(selected_mobs)] was selected by the [name] ruleset and has been made into a midround Bloodsucker.") log_game("DYNAMIC: [key_name(selected_mobs)] was selected by the [name] ruleset and has been made into a midround Bloodsucker.")
return TRUE return TRUE
/// Revenant ruleset
/datum/dynamic_ruleset/midround/from_ghosts/revenant
name = "Revenant"
antag_datum = /datum/antagonist/revenant
antag_flag = "Revenant"
antag_flag_override = ROLE_REVENANT
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
cost = 10
requirements = list(101,101,101,70,50,40,20,15,10,10)
repeatable = TRUE
var/dead_mobs_required = 20
var/need_extra_spawns_value = 15
var/list/spawn_locs = list()
/datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population=0, threat=0)
if(GLOB.dead_mob_list.len < dead_mobs_required)
return FALSE
return ..()
/datum/dynamic_ruleset/midround/from_ghosts/revenant/execute()
for(var/mob/living/corpse in GLOB.dead_mob_list) //look for any dead bodies
var/turf/corpse_turf = get_turf(corpse)
if(corpse_turf && is_station_level(corpse_turf.z))
spawn_locs += corpse_turf
if(!spawn_locs.len || spawn_locs.len < need_extra_spawns_value) //look for any morgue trays, crematoriums, ect if there weren't alot of dead bodies on the station to pick from
for(var/obj/structure/bodycontainer/corpse_container in GLOB.bodycontainers)
var/turf/container_turf = get_turf(corpse_container)
if(container_turf && is_station_level(container_turf.z))
spawn_locs += container_turf
if(!spawn_locs.len) //If we can't find any valid spawnpoints, try the carp spawns
for(var/obj/effect/landmark/carpspawn/carp_spawnpoint in GLOB.landmarks_list)
if(isturf(carp_spawnpoint.loc))
spawn_locs += carp_spawnpoint.loc
if(!spawn_locs.len) //If we can't find THAT, then just give up and cry
return FALSE
. = ..()
/datum/dynamic_ruleset/midround/from_ghosts/revenant/generate_ruleset_body(mob/applicant)
var/mob/living/simple_animal/revenant/revenant = new(pick(spawn_locs))
revenant.key = applicant.key
message_admins("[ADMIN_LOOKUPFLW(revenant)] has been made into a revenant by the midround ruleset.")
log_game("[key_name(revenant)] was spawned as a revenant by the midround ruleset.")
return revenant
/// Sentient Disease ruleset
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease
name = "Sentient Disease"
antag_datum = /datum/antagonist/disease
antag_flag = "Sentient Disease"
antag_flag_override = ROLE_ALIEN
required_candidates = 1
weight = 4
cost = 10
requirements = list(101,101,101,80,60,50,30,20,10,10)
repeatable = TRUE
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant)
var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center())
virus.key = applicant.key
INVOKE_ASYNC(virus, /mob/camera/disease/proc/pick_name)
message_admins("[ADMIN_LOOKUPFLW(virus)] has been made into a sentient disease by the midround ruleset.")
log_game("[key_name(virus)] was spawned as a sentient disease by the midround ruleset.")
return virus
/// Obsessed ruleset
/datum/dynamic_ruleset/midround/obsessed
name = "Obsessed"
antag_datum = /datum/antagonist/obsessed
antag_flag = ROLE_OBSESSED
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 = 4
cost = 10
requirements = list(101,101,101,80,60,50,30,20,10,10)
repeatable = TRUE
/datum/dynamic_ruleset/midround/obsessed/trim_candidates()
..()
candidates = living_players
for(var/mob/living/carbon/human/candidate in candidates)
if( \
!candidate.getorgan(/obj/item/organ/brain) \
|| candidate.mind.has_antag_datum(/datum/antagonist/obsessed) \
|| candidate.stat == DEAD \
|| !(ROLE_OBSESSED in candidate.client?.prefs?.be_special) \
|| !SSjob.GetJob(candidate.mind.assigned_role) \
|| (candidate.mind.assigned_role in GLOB.nonhuman_positions) \
)
candidates -= candidate
/datum/dynamic_ruleset/midround/obsessed/execute()
if(!candidates || !candidates.len)
return FALSE
var/mob/living/carbon/human/obsessed = pick_n_take(candidates)
obsessed.gain_trauma(/datum/brain_trauma/special/obsessed)
message_admins("[ADMIN_LOOKUPFLW(obsessed)] has been made Obsessed by the midround ruleset.")
log_game("[key_name(obsessed)] was made Obsessed by the midround ruleset.")
return ..()

View File

@@ -22,13 +22,25 @@
return basic_report return basic_report
/datum/antagonist/blob/greet() /datum/antagonist/blob/greet()
to_chat(owner.current, span_notice("<font color=\"#EE4000\">You are the Blob!</font>"))
owner.announce_objectives()
if(!isovermind(owner.current)) 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)
/datum/antagonist/blob/on_gain() /datum/antagonist/blob/on_gain()
create_objectives() create_objectives()
. = ..() . = ..()
/datum/antagonist/blob/remove_innate_effects()
QDEL_NULL(pop_action)
return ..()
/datum/antagonist/blob/farewell()
to_chat(owner.current, "<span class='alertsyndie'><font color=\"#EE4000\">You are no longer the Blob!</font></span>")
return ..()
/datum/antagonist/blob/proc/create_objectives() /datum/antagonist/blob/proc/create_objectives()
var/datum/objective/blob_takeover/main = new var/datum/objective/blob_takeover/main = new
main.owner = owner main.owner = owner
@@ -49,21 +61,49 @@
desc = "Unleash the blob" desc = "Unleash the blob"
icon_icon = 'icons/mob/blob.dmi' icon_icon = 'icons/mob/blob.dmi'
button_icon_state = "blob" button_icon_state = "blob"
var/autoplace_time = OVERMIND_STARTING_AUTO_PLACE_TIME
/datum/action/innate/blobpop/Activate()
/datum/action/innate/blobpop/Grant(Target)
. = ..()
if(owner)
addtimer(CALLBACK(src, .proc/Activate, TRUE), autoplace_time, TIMER_UNIQUE|TIMER_OVERRIDE)
to_chat(owner, "<span class='big'><font color=\"#EE4000\">You will automatically pop and place your blob core in [DisplayTimeText(autoplace_time)].</font></span>")
/datum/action/innate/blobpop/Activate(timer_activated = FALSE)
var/mob/old_body = owner var/mob/old_body = owner
if(!owner)
return
var/datum/antagonist/blob/blobtag = owner.mind.has_antag_datum(/datum/antagonist/blob) var/datum/antagonist/blob/blobtag = owner.mind.has_antag_datum(/datum/antagonist/blob)
if(!blobtag) if(!blobtag)
Remove() Remove(owner)
return 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, "<span class='warning'>This spot is too dense to place a blob core on!</span>")
. = FALSE
if(isspaceturf(target_turf) || !is_station_level(target_turf.z))
to_chat(owner, "<span class='warning'>You cannot place your core here!</span>")
. = FALSE
var/placement_override = BLOB_FORCE_PLACEMENT
if(!.)
if(!timer_activated)
return
placement_override = BLOB_RANDOM_PLACEMENT
to_chat(owner, "<span class='boldwarning'>Because your current location is an invalid starting spot and you need to pop, you've been moved to a random location!</span>")
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() old_body.gib()
B.place_blob_core(blobtag.point_rate_human_blob, 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() /datum/antagonist/blob/antag_listing_status()
. = ..() . = ..()
if(owner && owner.current) if(owner && owner.current)
var/mob/camera/blob/B = owner.current var/mob/camera/blob/blob_cam = owner.current
if(istype(B)) if(istype(blob_cam))
. += "(Progress: [B.blobs_legit.len]/[B.blobwincount])" . += "(Progress: [length(blob_cam.blobs_legit)]/[blob_cam.blobwincount])"

Binary file not shown.