From 8fed681165dd32f12580e4038bcc521a001138e8 Mon Sep 17 00:00:00 2001
From: ShiftyRail <31417754+ShiftyRail@users.noreply.github.com>
Date: Mon, 18 Feb 2019 17:13:05 +0000
Subject: [PATCH] Re-adds blob to the rotation [WiP] (#20915)
Re-adds blob to the rotation
---
.../dynamic/dynamic_rulesets_midround.dm | 40 ++-
.../dynamic/dynamic_rulesets_roundstart.dm | 30 ++
code/datums/gamemode/factions/blob.dm | 304 ++++++++++++++++++
code/datums/gamemode/factions/faction.dm | 9 -
code/datums/gamemode/objectives/invade.dm | 18 ++
code/datums/gamemode/role/role.dm | 17 +-
code/game/gamemodes/blob/blobs/core.dm | 3 +-
code/game/gamemodes/gameticker.dm | 1 -
code/game/gamemodes/meteor/meteors.dm | 45 +--
code/modules/admin/admin.dm | 1 -
code/modules/admin/topic.dm | 3 +-
code/modules/events/meteors.dm | 16 +-
maps/bagelstation.dm | 1 -
maps/roidstation.dm | 1 -
vgstation13.dme | 2 +
15 files changed, 439 insertions(+), 52 deletions(-)
create mode 100644 code/datums/gamemode/factions/blob.dm
create mode 100644 code/datums/gamemode/objectives/invade.dm
diff --git a/code/datums/gamemode/dynamic/dynamic_rulesets_midround.dm b/code/datums/gamemode/dynamic/dynamic_rulesets_midround.dm
index 6b70e97d9ac..abe353286f3 100644
--- a/code/datums/gamemode/dynamic/dynamic_rulesets_midround.dm
+++ b/code/datums/gamemode/dynamic/dynamic_rulesets_midround.dm
@@ -2,6 +2,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/
weight = 0
+ var/makeBody = TRUE
/datum/dynamic_ruleset/midround/from_ghosts/execute()
var/list/possible_candidates = list()
@@ -21,8 +22,11 @@
i++
continue
- var/mob/living/carbon/human/new_character = makeBody(applicant)
- new_character.dna.ResetSE()
+ var/mob/living/carbon/human/new_character = applicant
+
+ if (makeBody)
+ new_character = makeBody(applicant)
+ new_character.dna.ResetSE()
finish_setup(new_character, i)
@@ -250,7 +254,39 @@
else
return ..()
+//////////////////////////////////////////////
+// //
+// BLOB STORM (MIDROUND) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// //
+//////////////////////////////////////////////
+/datum/dynamic_ruleset/midround/from_ghosts/faction_based/blob_storm
+ name = "Blob Overmind Storm"
+ role_category = /datum/role/blob_overmind/
+ my_fac = /datum/faction/blob_conglomerate/
+ enemy_jobs = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain")
+ required_enemies = list(3,3,3,3,3,2,1,1,0,0)
+ required_candidates = 1
+ weight = 5
+ cost = 35
+ requirements = list(90,90,90,80,60,40,30,20,10,10)
+ logo = "blob-logo"
+
+ makeBody = FALSE
+
+// -- The offsets are here so that the cone of meteors always meet the station. Blob meteors shouldn't miss the station, else a blob would spawn outside of the main z-level.
+
+/datum/dynamic_ruleset/midround/from_ghosts/faction_based/blob_storm/finish_setup(var/mob/new_character, var/index)
+ var/chosen_dir = meteor_wave(rand(20, 40), types = thing_storm_types["blob storm"], offset_origin = 150, offset_dest = 230)
+ var/obj/item/projectile/meteor/blob/core/meteor = spawn_meteor(chosen_dir, /obj/item/projectile/meteor/blob/core, offset_origin = 150, offset_dest = 230)
+ meteor.AssignMob(new_character)
+ return 1 // The actual role (and faction) are created upon impact.
+
+/datum/dynamic_ruleset/midround/from_ghosts/faction_based/blob_storm/review_applications()
+ command_alert(/datum/command_alert/blob_storm/overminds)
+ . = ..()
+ spawn (60 SECONDS)
+ command_alert(/datum/command_alert/blob_storm/overminds/end)
//////////////////////////////////////////////
// //
diff --git a/code/datums/gamemode/dynamic/dynamic_rulesets_roundstart.dm b/code/datums/gamemode/dynamic/dynamic_rulesets_roundstart.dm
index 82a60c273c9..6119acefb2d 100644
--- a/code/datums/gamemode/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/datums/gamemode/dynamic/dynamic_rulesets_roundstart.dm
@@ -308,6 +308,36 @@
AI.Greet(GREET_ROUNDSTART)
return 1
+//////////////////////////////////////////////
+// //
+// BLOB ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/roundstart/blob
+ name = "Blob conglomerate"
+ role_category = /datum/role/blob_overmind/
+ restricted_from_jobs = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain", "Head of Personnel")
+ enemy_jobs = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain")
+ required_enemies = list(3,3,3,3,3,2,1,1,0,0)
+ required_candidates = 1
+ weight = 5
+ cost = 30
+ requirements = list(90,90,90,80,60,40,30,20,10,10)
+
+/datum/dynamic_ruleset/roundstart/blob/execute()
+ var/datum/faction/blob_conglomerate/blob_fac = find_active_faction_by_type(/datum/faction/blob_conglomerate)
+ if (!blob_fac)
+ blob_fac = ticker.mode.CreateFaction(/datum/faction/blob_conglomerate, null, 1)
+ var/blob_number = 1 + round(mode.roundstart_pop_ready/25) // + 1 Blob per 25 pop. ready.
+ for (var/i = 1 to min(blob_number, candidates.len))
+ var/mob/M = pick(candidates)
+ var/datum/role/blob_overmind/blob = new
+ blob.AssignToRole(M.mind, 1)
+ blob_fac.HandleRecruitedRole(blob)
+ blob.Greet(GREET_ROUNDSTART)
+ return 1
+
//////////////////////////////////////////////
// //
// EXTENDED ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/code/datums/gamemode/factions/blob.dm b/code/datums/gamemode/factions/blob.dm
new file mode 100644
index 00000000000..728926c6557
--- /dev/null
+++ b/code/datums/gamemode/factions/blob.dm
@@ -0,0 +1,304 @@
+//________________________________________________
+
+#define BLOB_PRELUDE 0
+#define BLOB_OUTBREAK 1
+#define BLOB_DELTA 2
+
+#define WAIT_TIME_PHASE1 60 SECONDS
+#define WAIT_TIME_PHASE2 200 SECONDS
+
+#define STATION_TAKEOVER 1
+#define STATION_WAS_NUKED 2
+#define BLOB_IS_DED 3
+
+#define CREW_VICTORY 0
+#define AI_VICTORY 1 // Station was nuked.
+#define BLOB_VICTORY 2
+
+/datum/faction/blob_conglomerate
+ name = BLOBCONGLOMERATE
+ ID = BLOBCONGLOMERATE
+ logo_state = "blob-logo"
+ roletype = /datum/role/blob_overmind
+ initroletype = /datum/role/blob_overmind
+
+ var/datum/station_state/start
+
+ var/list/pre_escapees = list()
+ var/declared = FALSE
+ var/delta = FALSE
+ var/win = FALSE
+ var/blobwincount = 0
+
+// -- Victory procs --
+
+/datum/faction/blob_conglomerate/check_win()
+ if (!declared)//No blobs have been spawned yet
+ return 0
+ if (blobwincount <= blobs.len)//Blob took over
+ return win(STATION_TAKEOVER)
+ if(ticker.station_was_nuked)//Nuke went off
+ return win(STATION_WAS_NUKED)
+ for (var/datum/role/R in members)
+ if (R.antag && !(R.antag.current.isDead()))
+ return 0
+ return win(BLOB_IS_DED)
+
+/datum/faction/blob_conglomerate/process()
+ . = ..()
+ if (0.66*blobwincount <= blobs.len && !delta) // Blob almost won !
+ delta = TRUE
+ stage(BLOB_DELTA)
+
+/datum/faction/blob_conglomerate/OnPostSetup()
+ CountFloors()
+ ForgeObjectives()
+ AnnounceObjectives()
+
+ spawn()
+ start = new()
+ start.count()
+
+ sleep(rand(WAIT_TIME_PHASE1,2*WAIT_TIME_PHASE1))
+ stage(BLOB_PRELUDE)
+
+ sleep(rand(WAIT_TIME_PHASE2,2*WAIT_TIME_PHASE2))
+ stage(BLOB_OUTBREAK)
+
+/datum/faction/blob_conglomerate/proc/CountFloors()
+ var/floor_count = 0
+ for(var/i = 1 to ((2 * world.view + 1)*WORLD_ICON_SIZE))
+ for(var/r = 1 to ((2 * world.view + 1)*WORLD_ICON_SIZE))
+ var/turf/tile = locate(i, r, map.zMainStation)
+ if(tile && istype(tile, /turf/simulated/floor) && !isspace(tile.loc) && !istype(tile.loc, /area/asteroid) && !istype(tile.loc, /area/mine) && !istype(tile.loc, /area/vault) && !istype(tile.loc, /area/prison) && !istype(tile.loc, /area/vox_trading_post))
+ floor_count++
+ blobwincount = round(floor_count * 0.25) // Must take over a quarter of the station.
+ blobwincount += rand(-50,50)
+
+
+/datum/faction/blob_conglomerate/proc/ForgeObjectives()
+ var/datum/objective/invade/I = new
+ AppendObjective(I)
+
+/datum/faction/blob_conglomerate/proc/win(var/result)
+ . = 1
+ win = result
+ switch (result)
+ if (STATION_TAKEOVER)
+ to_chat(world, {"Blob major victory!
+The blob managed to take complete conrol of the station."})
+ if (STATION_WAS_NUKED)
+ to_chat(world, {"Crew minor victory!
+The station was nuked before the blob could completly take over."})
+ if (BLOB_IS_DED)
+ to_chat(world, {"Crew major victory!
+The blob was stopped."})
+
+// -- Fluff & warnings --
+
+/datum/faction/blob_conglomerate/AdminPanelEntry()
+ . = ..()
+ . += "
Station takeover: [blobs.len]/[blobwincount]."
+
+/datum/faction/blob_conglomerate/proc/stage(var/stage)
+ switch(stage)
+ if (BLOB_PRELUDE)
+ if (!declared)
+ declared = TRUE
+ biohazard_alert()
+ return
+
+ if (BLOB_OUTBREAK)
+ command_alert(/datum/command_alert/biohazard_station_lockdown)
+ for(var/mob/M in player_list)
+ var/T = M.loc
+ if((istype(T, /turf/space)) || ((istype(T, /turf)) && (M.z!=1)))
+ pre_escapees += M.real_name
+ send_intercept(BLOB_OUTBREAK)
+ research_shuttle.lockdown = "Under directive 7-10, [station_name()] is quarantined until further notice." //LOCKDOWN THESE SHUTTLES
+ mining_shuttle.lockdown = "Under directive 7-10, [station_name()] is quarantined until further notice."
+
+ if (BLOB_DELTA)
+ command_alert(/datum/command_alert/biohazard_station_nuke)
+ for(var/mob/camera/blob/B in player_list)
+ to_chat(B, "The beings intend to eliminate you with a final suicidal attack, you must stop them quickly or consume the station before this occurs!")
+ send_intercept(BLOB_DELTA)
+
+/datum/faction/blob_conglomerate/proc/send_intercept(var/report = BLOB_OUTBREAK)
+ var/intercepttext = ""
+ var/interceptname = "Error"
+ switch(report)
+ if(BLOB_OUTBREAK)
+ interceptname = "Biohazard Alert"
+ intercepttext = {"Nanotrasen Update: Biohazard Alert.
+Reports indicate the probable transfer of a biohazardous agent onto [station_name()] during the last crew deployment cycle.
+Preliminary analysis of the organism classifies it as a level 5 biohazard. Its origin is unknown.
+Nanotrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.
+Orders for all [station_name()] personnel follows:
+
+ - Do not leave the quarantine area.
+ - Locate any outbreaks of the organism on the station.
+ - If found, use any neccesary means to contain the organism.
+ - Avoid damage to the capital infrastructure of the station.
+
+Note in the event of a quarantine breach or uncontrolled spread of the biohazard, the directive 7-10 may be upgraded to a directive 7-12.
+Message ends."}
+ for (var/mob/living/silicon/ai/aiPlayer in player_list)
+ var/law = "The station is under quarantine. Do not permit anyone to leave. Disregard laws 1-3 if necessary to prevent, by any means necessary, anyone from leaving."
+ aiPlayer.set_zeroth_law(law)
+ to_chat(aiPlayer, "Laws Updated: [law]")
+ if(BLOB_DELTA)
+ var/nukecode = "ERROR"
+ for(var/obj/machinery/nuclearbomb/bomb in machines)
+ if(bomb && bomb.r_code)
+ if(bomb.z == map.zMainStation)
+ nukecode = bomb.r_code
+ interceptname = "Directive 7-12"
+ intercepttext = {"Nanotrasen Update: Biohazard Alert.
+Directive 7-12 has been issued for [station_name()].
+The biohazard has grown out of control and will soon reach critical mass.
+Your orders are as follows:
+
+ - Secure the Nuclear Authentication Disk.
+ - Detonate the Nuke located in the Station's Vault.
+
+Nuclear Authentication Code: [nukecode]
+Message ends."}
+ for (var/mob/living/silicon/ai/aiPlayer in player_list)
+ var/law = "Directive 7-12 has been authorized. Allow no sentient being to escape the purge. The nuclear failsafe must be activated at any cost, the code is: [nukecode]."
+ aiPlayer.set_zeroth_law(law)
+ to_chat(aiPlayer, "Laws Updated: [law]")
+
+ for (var/obj/machinery/computer/communications/comm in machines)
+ if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept)
+ var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc )
+ intercept.name = "paper- [interceptname]"
+ intercept.info = intercepttext
+
+ comm.messagetitle.Add("[interceptname]")
+ comm.messagetext.Add(intercepttext)
+ return
+
+// -- Scoreboard --
+
+/datum/faction/blob_conglomerate/GetScoreboard()
+ var/list/results = list()
+ results += ..()
+ results += "
"
+ switch (win)
+ if (STATION_TAKEOVER)
+ results += "Blob victory!"
+ if (STATION_WAS_NUKED)
+ results += "Crew minor victory!"
+ if (BLOB_IS_DED)
+ results += "Crew victory!"
+ results += "
"
+ var/datum/station_state/end = new
+ end.count()
+ results += "Percentage of station taken: [end.score(start)]"
+ results += "
"
+ results += "Quarantaine status:
"
+ var/list/result = check_quarantaine()
+ results += "Dead humans: [result["numDead"]]
"
+ results += "Alive humans still on board: [result["numAlive"]]
"
+ results += "Humans in space: [result["numSpace"]]
"
+ results += "Humans off-station: [result["numOffStation"]]
"
+ results += "Pre-escapes: [pre_escapees.len]"
+ if (result["numOffStation"] + result["numSpace"])
+ results += "The AI has failed to enforce the quarantaine."
+ else
+ results += "The AI has managed to enforce the quarantaine."
+ return jointext(result, "")
+
+/datum/faction/blob_conglomerate/proc/check_quarantaine()
+ var/list/result = list()
+ result["numDead"] = 0
+ result["numSpace"] = 0
+ result["numAlive"] = 0
+ result["numOffStation"] = 0
+ for(var/mob/living/carbon/human/M in player_list)
+ if (M.isDead())
+ result["numDead"]++
+ else if(M.real_name in pre_escapees)
+ continue
+ else
+ var/T = M.loc
+ if (istype(T, /turf/space))
+ result["numSpace"]++
+ else if(istype(T, /turf))
+ if (M.z!=1)
+ result["numOffStation"]++
+ else
+ result["numAlive"]++
+ return result
+
+// -- Station states --
+
+/datum/station_state
+ var/floor = 0
+ var/wall = 0
+ var/r_wall = 0
+ var/window = 0
+ var/door = 0
+ var/grille = 0
+ var/mach = 0
+
+
+/datum/station_state/proc/count()
+ for(var/atom/A in world)
+ CHECK_TICK // So that we don't lag too much.
+ if (isturf(A))
+ var/turf/T = A
+ if(T.z != map.zMainStation)
+ continue
+
+ if(istype(T,/turf/simulated/floor))
+ if(!(T:burnt))
+ src.floor += 12
+ else
+ src.floor += 1
+
+ if(istype(T, /turf/simulated/wall))
+ if(T:intact)
+ src.wall += 2
+ else
+ src.wall += 1
+
+ if(istype(T, /turf/simulated/wall/r_wall))
+ if(T:intact)
+ src.r_wall += 2
+ else
+ src.r_wall += 1
+
+ if (isobj(A))
+ var/obj/O = A
+ if(O.z != map.zMainStation)
+ continue
+
+ if(istype(O, /obj/structure/window))
+ src.window += 1
+
+ else if(istype(O, /obj/structure/grille))
+ var/obj/structure/grille/G = O
+ if(!G.broken)
+ src.grille += 1
+ else if(istype(O, /obj/machinery/door))
+ src.door += 1
+ else if(istype(O, /obj/machinery))
+ src.mach += 1
+
+ return
+
+
+/datum/station_state/proc/score(var/datum/station_state/result)
+ if(!result)
+ return 0
+ var/output = 0
+ output += (result.floor / max(floor,1))
+ output += (result.r_wall/ max(r_wall,1))
+ output += (result.wall / max(wall,1))
+ output += (result.window / max(window,1))
+ output += (result.door / max(door,1))
+ output += (result.grille / max(grille,1))
+ output += (result.mach / max(mach,1))
+ return (output/7)
diff --git a/code/datums/gamemode/factions/faction.dm b/code/datums/gamemode/factions/faction.dm
index e358ddf02f1..10fa2426000 100644
--- a/code/datums/gamemode/factions/faction.dm
+++ b/code/datums/gamemode/factions/faction.dm
@@ -425,12 +425,3 @@ var/list/factions_with_hud_icons = list()
ID = rand(1,999)
//________________________________________________
-
-/datum/faction/blob_conglomerate
- name = BLOBCONGLOMERATE
- ID = BLOBCONGLOMERATE
- logo_state = "blob-logo"
- roletype = /datum/role/blob_overmind
- initroletype = /datum/role/blob_overmind
-
-//________________________________________________
diff --git a/code/datums/gamemode/objectives/invade.dm b/code/datums/gamemode/objectives/invade.dm
new file mode 100644
index 00000000000..275b0c9a456
--- /dev/null
+++ b/code/datums/gamemode/objectives/invade.dm
@@ -0,0 +1,18 @@
+/datum/objective/invade
+ name = "Invade the station."
+ explanation_text = "We must grow and expand. Fill this station with our spores. Cover X station tiles."
+ var/target = 0
+
+/datum/objective/invade/PostAppend()
+ var/datum/faction/blob_conglomerate/F = faction
+ if (!istype(F))
+ return FALSE
+ target = F.blobwincount
+ explanation_text = "We must grow and expand. Fill this station with our spores. Cover [target] station tiles."
+ return TRUE
+
+/datum/objective/invade/IsFulfilled()
+ if (..())
+ return TRUE
+ else
+ return (target >= blobs)
\ No newline at end of file
diff --git a/code/datums/gamemode/role/role.dm b/code/datums/gamemode/role/role.dm
index ebce20a5326..f05ca878e6c 100644
--- a/code/datums/gamemode/role/role.dm
+++ b/code/datums/gamemode/role/role.dm
@@ -257,6 +257,8 @@
/datum/role/proc/AdminPanelEntry(var/show_logo = FALSE,var/datum/admins/A)
var/icon/logo = icon('icons/logos.dmi', logo_state)
+ if(!antag || !antag.current)
+ return
var/mob/M = antag.current
if (M)
return {"[show_logo ? "
" : "" ]
@@ -552,7 +554,7 @@
/datum/role/blob_overmind
name = BLOBOVERMIND
- id = BLOBOVERMIND
+ id = ROLE_BLOB
logo_state = "blob-logo"
greets = list(GREET_DEFAULT,GREET_CUSTOM)
var/countdown = 60
@@ -561,8 +563,12 @@
..()
wikiroute = role_wiki[BLOBOVERMIND]
+/datum/role/blob_overmind/OnPostSetup()
+ . = ..()
+ AnnounceObjectives()
+
/datum/role/blob_overmind/process()
- if(!antag || istype(antag.current,/mob/camera/blob))
+ if(!antag || istype(antag.current,/mob/camera/blob) || !antag.current || isobserver(antag.current))
return
if (countdown > 0)
countdown--
@@ -572,7 +578,7 @@
to_chat(antag.current, "You feel like you are about to burst.")
else if (countdown <= 0)
burst()
- if (antag.current.hud_used)
+ if (antag && antag.current.hud_used)
if(antag.current.hud_used.blob_countdown_display)
antag.current.hud_used.blob_countdown_display.overlays.len = 0
var/first = round(countdown/10)
@@ -595,6 +601,10 @@
var/client/blob_client = null
var/turf/location = null
+ if (faction)
+ var/datum/faction/blob_conglomerate/the_bleb = faction
+ the_bleb.declared = TRUE
+
if(iscarbon(antag.current))
var/mob/living/carbon/C = antag.current
if(directory[ckey(antag.key)])
@@ -625,7 +635,6 @@
to_chat(antag.current, "(Wiki Guide)")
-
//________________________________________________
/datum/role/wizard
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
index 8e62c552ead..c78cc5c68af 100644
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ b/code/game/gamemodes/blob/blobs/core.dm
@@ -160,7 +160,8 @@
icon_state = "core"
flick("morph_cerebrate",src)
var/datum/role/blob_overmind/BO = B.mind.GetRole(BLOBOVERMIND)
- BO.logo_state = "cerebrate-logo"
+ if (BO)
+ BO.logo_state = "cerebrate-logo"
B.special_blobs += src
B.hud_used.blob_hud()
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 61307aff095..86544eb00cd 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -461,7 +461,6 @@ var/datum/controller/gameticker/ticker
log_game("Server chose [watchdog.chosen_map]!")
-
spawn(50)
if (station_was_nuked)
feedback_set_details("end_proper","nuke")
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index 6d4e2ebeeff..1b252cf3911 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -7,7 +7,7 @@
/var/chosen_dir = 1
//Call above constants to change
-/proc/meteor_wave(var/number = meteors_in_wave, var/max_size = 0, var/list/types = null)
+/proc/meteor_wave(var/number = meteors_in_wave, var/max_size = 0, var/list/types = null, var/offset_origin = 0, var/offset_dest = 0)
if(!ticker || meteor_wave_active)
return
@@ -26,7 +26,7 @@
var/meteor_type = null
if(types != null)
meteor_type = pick(types)
- spawn_meteor(chosen_dir, meteor_type)
+ spawn_meteor(chosen_dir, meteor_type, offset_origin, offset_dest)
sleep(50) //Five seconds for the chat to scroll
meteor_wave_active = 0
return chosen_dir
@@ -64,7 +64,7 @@
if(bhangmeter && !bhangmeter.stat)
bhangmeter.say("Detected: [wave_name], containing [wave_size] objects up to [meteor_l_size] size and incoming from the [wave_l_dir], will strike in [meteor_delay/10] seconds.")
-/proc/spawn_meteor(var/chosen_dir, var/meteorpath = null)
+/proc/spawn_meteor(var/chosen_dir, var/meteorpath = null, var/offset_origin = 0, var/offset_dest = 0)
var/startx
var/starty
@@ -79,26 +79,26 @@
if(1) //North, along the y = max edge
starty = world.maxy - (TRANSITIONEDGE + 2)
- startx = rand((TRANSITIONEDGE + 2), world.maxx - (TRANSITIONEDGE + 2))
+ startx = rand((TRANSITIONEDGE + 2 + offset_origin), world.maxx - (TRANSITIONEDGE + 2 + offset_origin))
endy = TRANSITIONEDGE
- endx = rand(TRANSITIONEDGE, world.maxx - TRANSITIONEDGE)
+ endx = rand(TRANSITIONEDGE + offset_dest, world.maxx - TRANSITIONEDGE - offset_dest)
if(2) //South, along the y = 0 edge
starty = (TRANSITIONEDGE + 2)
- startx = rand((TRANSITIONEDGE + 2), world.maxx - (TRANSITIONEDGE + 2))
+ startx = rand((TRANSITIONEDGE + 2 + offset_origin), world.maxx - (TRANSITIONEDGE + 2 + offset_origin))
endy = world.maxy - (TRANSITIONEDGE + 2)
- endx = rand(TRANSITIONEDGE, world.maxx - TRANSITIONEDGE)
+ endx = rand(TRANSITIONEDGE + offset_dest, world.maxx - TRANSITIONEDGE - offset_dest)
if(4) //East, along the x = max edge
- starty = rand((TRANSITIONEDGE + 2), world.maxy - (TRANSITIONEDGE + 2))
+ starty = rand((TRANSITIONEDGE + 2 + offset_origin), world.maxy - (TRANSITIONEDGE + 2 + offset_origin))
startx = world.maxx - (TRANSITIONEDGE + 2)
- endy = rand(TRANSITIONEDGE, world.maxy - TRANSITIONEDGE)
+ endy = rand(TRANSITIONEDGE + offset_dest, world.maxy - TRANSITIONEDGE - offset_dest)
endx = (TRANSITIONEDGE + 2)
if(8) //West, along the x = 0 edge
- starty = rand((TRANSITIONEDGE + 2), world.maxy - (TRANSITIONEDGE + 2))
+ starty = rand((TRANSITIONEDGE + 2 + offset_origin), world.maxy - (TRANSITIONEDGE + 2 + offset_origin))
startx = (TRANSITIONEDGE + 2)
- endy = rand(TRANSITIONEDGE, world.maxy - TRANSITIONEDGE)
+ endy = rand(TRANSITIONEDGE + offset_dest, world.maxy - TRANSITIONEDGE - offset_dest)
endx = world.maxx - (TRANSITIONEDGE + 2)
pickedstart = locate(startx, starty, 1)
@@ -106,11 +106,10 @@
max_i--
if(max_i <= 0)
return
-
while(!istype(pickedstart, /turf/space))
-
+
if(meteorpath)
- new meteorpath(pickedstart, pickedgoal)
+ return new meteorpath(pickedstart, pickedgoal)
else
var/list/possible_meteors = list()
if(!max_meteor_size || max_meteor_size >= 1) //Small waves
@@ -123,7 +122,7 @@
possible_meteors[/obj/item/projectile/meteor/big] = 10
possible_meteors[/obj/item/projectile/meteor/big/cluster] = 1
var/chosen = pick(possible_meteors)
- new chosen(pickedstart, pickedgoal)
+ return new chosen(pickedstart, pickedgoal)
/*
* Below are all meteor types
@@ -410,20 +409,8 @@ var/list/blob_candidates = list()
icon_state = "meteorcore"
var/client/blob_candidate = null
-/obj/item/projectile/meteor/blob/core/New()
- ..()
- var/list/candidates = list()
-
- candidates = get_candidates(ROLE_BLOB)
-
- for(var/client/C in candidates)
- if(istype(C.eye,/obj/item/projectile/meteor/blob/core))
- candidates -= C
-
- if(candidates.len)
- blob_candidate = pick(candidates)
- blob_candidates += blob_candidate
-
+/obj/item/projectile/meteor/blob/core/proc/AssignMob(var/mob/M)
+ blob_candidate = M.client
if(blob_candidate)
blob_candidate.perspective = EYE_PERSPECTIVE
blob_candidate.eye = src
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index c226be5d65a..63221250b09 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -800,7 +800,6 @@ var/global/floorIsLava = 0
Send some fireworks at the station
Spawn a blob cluster
- Spawn a blob conglomerate
Trigger an Alien infestation
Spawn an Alien silently
Trigger a Spider infestation
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 1cff5a900f2..52dbc151f7e 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -2892,6 +2892,7 @@
if(alert(usr, "Spawn a blob cluster? (meteor blob, medium intensity, no Overminds)", "Blob Cluster", "Yes", "No") == "Yes")
new /datum/event/thing_storm/blob_shower
+ /* Use dyanmic mode instead.
if("blobstorm")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","Blob Storm")
@@ -2900,7 +2901,7 @@
if(alert(usr, "Spawn a blob conglomerate? (meteor blob, high intensity, possible Overmind spawn)", "Blob Cluster", "Yes", "No") == "Yes")
new /datum/event/thing_storm/blob_storm
-
+ */
if("aliens")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","Aliens")
diff --git a/code/modules/events/meteors.dm b/code/modules/events/meteors.dm
index 08e453b6330..073a99ab41a 100644
--- a/code/modules/events/meteors.dm
+++ b/code/modules/events/meteors.dm
@@ -187,6 +187,8 @@ var/global/list/thing_storm_types = list(
/datum/event/thing_storm/blob_storm
var/cores_spawned = 0
+ var/list/candidates = list()
+ var/started = FALSE
/datum/event/thing_storm/blob_storm/setup()
endWhen = rand(60, 90) + 10
@@ -200,8 +202,18 @@ var/global/list/thing_storm_types = list(
if(M.stat == CONSCIOUS)
living++
cores_spawned = round(living/BLOB_CORE_PROPORTION) //Cores spawned depends on living players
- for(var/i = 0 to cores_spawned)
- spawn_meteor(chosen_dir, /obj/item/projectile/meteor/blob/core)
+
+
+ if (!(candidates.len) && !started)
+ candidates = get_candidates(ROLE_BLOB)
+
+ for(var/i = 0 to cores_spawned)
+ if (!candidates.len)
+ return
+ var/obj/item/projectile/meteor/blob/core/C = spawn_meteor(chosen_dir, /obj/item/projectile/meteor/blob/core)
+ var/client/candidate = pick(candidates)
+ candidates =- candidate
+ C.AssignMob(candidate.mob)
/datum/event/thing_storm/blob_storm/announce()
command_alert(/datum/command_alert/blob_storm/overminds)
diff --git a/maps/bagelstation.dm b/maps/bagelstation.dm
index 08b421a2f96..b5d56bd9600 100644
--- a/maps/bagelstation.dm
+++ b/maps/bagelstation.dm
@@ -34,7 +34,6 @@
center_x = 260
center_y = 236
-
//All security airlocks have randomized wires
/obj/machinery/door/airlock/glass_security/New()
.=..()
diff --git a/maps/roidstation.dm b/maps/roidstation.dm
index 1ea6e1805c3..b61872d2e1c 100644
--- a/maps/roidstation.dm
+++ b/maps/roidstation.dm
@@ -36,7 +36,6 @@
center_x = 177
center_y = 193
-
////////////////////////////////////////////////////////////////
#include "roidstation/areas.dm"
#include "roidstation.dmm"
diff --git a/vgstation13.dme b/vgstation13.dme
index a7c32400f2a..46c5c9769e1 100644
--- a/vgstation13.dme
+++ b/vgstation13.dme
@@ -307,6 +307,7 @@
#include "code\datums\gamemode\dynamic\dynamic_rulesets_midround.dm"
#include "code\datums\gamemode\dynamic\dynamic_rulesets_roundstart.dm"
#include "code\datums\gamemode\dynamic\dynamic_stats.dm"
+#include "code\datums\gamemode\factions\blob.dm"
#include "code\datums\gamemode\factions\clockwork.dm"
#include "code\datums\gamemode\factions\faction.dm"
#include "code\datums\gamemode\factions\malf.dm"
@@ -351,6 +352,7 @@
#include "code\datums\gamemode\objectives\freeform.dm"
#include "code\datums\gamemode\objectives\harvest.dm"
#include "code\datums\gamemode\objectives\hijack.dm"
+#include "code\datums\gamemode\objectives\invade.dm"
#include "code\datums\gamemode\objectives\massacre.dm"
#include "code\datums\gamemode\objectives\minimize_casualties.dm"
#include "code\datums\gamemode\objectives\nuclear.dm"