mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Ports some funni midround rulesets from TG (#13971)
* Sussy baka * Update blob.dm * Update blob.dm
This commit is contained in:
@@ -32,10 +32,17 @@
|
||||
/// blob gets a free reroll every X time
|
||||
#define BLOB_REROLL_TIME 2400
|
||||
#define BLOB_SPREAD_COST 4
|
||||
#define OVERMIND_STARTING_AUTO_PLACE_TIME 6 MINUTES
|
||||
/// blob refunds this much if it attacks and doesn't spread
|
||||
#define BLOB_ATTACK_REFUND 2
|
||||
#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
|
||||
#define ERT_BLUE "Blue"
|
||||
|
||||
@@ -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
|
||||
#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
|
||||
the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example)
|
||||
|
||||
@@ -48,7 +48,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()
|
||||
|
||||
/obj/screen/blob/Blobbernaut
|
||||
|
||||
@@ -361,7 +361,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(100,100,100,80,60,50,45,30,20,20)
|
||||
repeatable = TRUE
|
||||
@@ -370,6 +370,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) //
|
||||
@@ -653,3 +688,109 @@
|
||||
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.")
|
||||
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 ..()
|
||||
|
||||
@@ -22,13 +22,25 @@
|
||||
return basic_report
|
||||
|
||||
/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))
|
||||
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()
|
||||
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()
|
||||
var/datum/objective/blob_takeover/main = new
|
||||
main.owner = owner
|
||||
@@ -49,21 +61,49 @@
|
||||
desc = "Unleash the blob"
|
||||
icon_icon = 'icons/mob/blob.dmi'
|
||||
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
|
||||
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, "<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()
|
||||
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()
|
||||
. = ..()
|
||||
if(owner && 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])"
|
||||
|
||||
BIN
sound/ambience/antag/blobalert.ogg
Normal file
BIN
sound/ambience/antag/blobalert.ogg
Normal file
Binary file not shown.
Reference in New Issue
Block a user