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: +
    +
  1. Do not leave the quarantine area.
  2. +
  3. Locate any outbreaks of the organism on the station.
  4. +
  5. If found, use any neccesary means to contain the organism.
  6. +
  7. Avoid damage to the capital infrastructure of the station.
  8. +
+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: +
    +
  1. Secure the Nuclear Authentication Disk.
  2. +
  3. Detonate the Nuke located in the Station's Vault.
  4. +
+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"