From 1ead1acbfc27a7f839b03691bd2195aca0483b15 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Wed, 9 Mar 2016 20:21:19 -0500 Subject: [PATCH 1/5] Goon-style blob placement --- code/_onclick/hud/blob_overmind.dm | 2 + code/game/gamemodes/blob/blob.dm | 120 ++++-------------------- code/game/gamemodes/blob/blob_finish.dm | 10 +- code/game/gamemodes/blob/blobs/core.dm | 8 +- code/game/gamemodes/blob/overmind.dm | 45 +++++++-- code/game/gamemodes/blob/powers.dm | 54 +++++------ code/modules/admin/player_panel.dm | 2 +- code/modules/admin/verbs/debug.dm | 3 +- code/modules/events/blob.dm | 2 +- code/modules/mob/transform_procs.dm | 14 +-- 10 files changed, 103 insertions(+), 157 deletions(-) diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index 0ad95519fa7..5fc19b69531 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -30,6 +30,8 @@ /obj/screen/blob/JumpToCore/Click() if(isovermind(usr)) var/mob/camera/blob/B = usr + if(!B.placed) + B.place_blob_core() B.transport_core() /obj/screen/blob/Blobbernaut diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 00565133e40..48788f242f1 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -7,18 +7,18 @@ var/list/overminds = list() var/list/blob_nodes = list() var/list/blobs_legit = list() //used for win-score calculations, contains only blobs counted for win condition +#define BLOB_NO_PLACE_TIME 1800 //time, in deciseconds, blobs are prevented from bursting in the gamemode /datum/game_mode/blob name = "blob" config_tag = "blob" antag_flag = ROLE_BLOB - required_players = 25 + required_players = 0//25 required_enemies = 1 recommended_enemies = 1 round_ends_with_antag_death = 1 - restricted_jobs = list("Cyborg", "AI") var/burst = 0 @@ -28,10 +28,10 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b var/blobwincount = 350 - var/burstdelay_low = 1200 //in deciseconds - var/burstdelay_high = 1800 //blobs will burst after a random value between these * 2.5(minimum 5 minutes, maximum 7 and a half minutes) + var/messagedelay_low = 2400 //in deciseconds + var/messagedelay_high = 3600 //blob report will be sent after a random value between these (minimum 4 minutes, maximum 6 minutes) - var/list/infected_crew = list() + var/list/blob_overminds = list() /datum/game_mode/blob/pre_setup() cores_to_spawn = max(round(num_players()/players_per_core, 1), 1) @@ -42,18 +42,17 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b if (!antag_candidates.len) break var/datum/mind/blob = pick(antag_candidates) - infected_crew += blob + blob_overminds += blob + blob.assigned_role = "Blob" blob.special_role = "Blob" - blob.restricted_roles = restricted_jobs log_game("[blob.key] (ckey) has been selected as a Blob") antag_candidates -= blob - if(!infected_crew.len) + if(!blob_overminds.len) return 0 return 1 - /datum/game_mode/blob/proc/get_blob_candidates() var/list/candidates = list() for(var/mob/living/carbon/human/player in player_list) @@ -62,96 +61,23 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b candidates += player return candidates - -/datum/game_mode/blob/proc/blobize(mob/living/carbon/human/blob) - var/datum/mind/blobmind = blob.mind - if(!istype(blobmind)) - return 0 - infected_crew += blobmind - blobmind.special_role = "Blob" - log_game("[blob.key] (ckey) has been selected as a Blob") - greet_blob(blobmind) - blob << "You feel very tired and bloated! You don't have long before you burst!" - spawn(600) - burst_blob(blobmind) - return 1 - -/datum/game_mode/blob/proc/make_blobs(count) - var/list/candidates = get_blob_candidates() - var/mob/living/carbon/human/blob = null - count=min(count, candidates.len) - for(var/i = 0, i < count, i++) - blob = pick(candidates) - candidates -= blob - blobize(blob) - return count - - - /datum/game_mode/blob/announce() world << "The current game mode is - Blob!" world << "A dangerous alien organism is rapidly spreading throughout the station!" world << "You must kill it all while minimizing the damage to the station." - -/datum/game_mode/blob/proc/greet_blob(datum/mind/blob) - blob.current << "You are infected by the Blob!" - blob.current << "Your body is ready to give spawn to a new blob core which will eat this station." - blob.current << "Find a good location to spawn the core and then take control and overwhelm the station!" - blob.current << "When you have found a location, wait until you spawn; this will happen automatically and you cannot speed up the process." - blob.current << "If you go outside of the station level, or in space, then you will die; make sure your location has lots of ground to cover." - return - /datum/game_mode/blob/proc/show_message(message) - for(var/datum/mind/blob in infected_crew) + for(var/datum/mind/blob in blob_overminds) blob.current << message -/datum/game_mode/blob/proc/burst_blobs() - for(var/datum/mind/blob in infected_crew) - if(blob.special_role != "Blob Overmind") - burst_blob(blob) - -/datum/game_mode/blob/proc/burst_blob(datum/mind/blob, warned=0) - var/client/blob_client = null - var/turf/location = null - - if(iscarbon(blob.current)) - var/mob/living/carbon/C = blob.current - if(directory[ckey(blob.key)]) - blob_client = directory[ckey(blob.key)] - location = get_turf(C) - if(location.z != ZLEVEL_STATION || istype(location, /turf/space)) - if(!warned) - C << "You feel ready to burst, but this isn't an appropriate place! You must return to the station!" - message_admins("[key_name(C)] was in space when the blobs burst, and will die if he doesn't return to the station.") - spawn(300) - burst_blob(blob, 1) - else - burst ++ - log_admin("[key_name(C)] was in space when attempting to burst as a blob.") - message_admins("[key_name(C)] was in space when attempting to burst as a blob.") - C.gib() - make_blobs(1) - check_finished() //Still needed in case we can't make any blobs - - else if(blob_client && location) - burst ++ - C.gib() - var/obj/effect/blob/core/core = new(location, 200, blob_client, blob_point_rate) - if(core.overmind && core.overmind.mind) - core.overmind.mind.name = blob.name - infected_crew -= blob - infected_crew += core.overmind.mind - core.overmind.mind.special_role = "Blob Overmind" - /datum/game_mode/blob/post_setup() - for(var/datum/mind/blob in infected_crew) - greet_blob(blob) - var/datum/action/innate/blob/earlyhelp/B = new - B.Grant(blob.current) - var/datum/action/innate/blob/earlycomm/C = new - C.Grant(blob.current) + for(var/datum/mind/blob in blob_overminds) + var/mob/camera/blob/B = blob.current.become_overmind(1) + var/turf/T = pick(blobstart) + B.loc = T + B.base_point_rate = blob_point_rate + SSshuttle.emergencyNoEscape = 1 // Disable the blob event for this round. @@ -160,21 +86,9 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b B.max_occurrences = 0 // disable the event spawn(0) - var/burst_delay = rand(burstdelay_low, burstdelay_high) //between 5 and 7 and a half minutes with 1200 low and 1800 high. + var/message_delay = rand(messagedelay_low, messagedelay_high) //between 4 and 6 minutes with 2400 low and 3600 high. - sleep(burst_delay) - - show_message("You feel tired and bloated.") - - sleep(burst_delay) - - show_message("You feel like you are about to burst.") - - sleep(burst_delay * 0.5) - - burst_blobs() - - sleep(burst_delay * 0.5) + sleep(message_delay) send_intercept(1) diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm index 78e557c16cf..8bfc8e6f98f 100644 --- a/code/game/gamemodes/blob/blob_finish.dm +++ b/code/game/gamemodes/blob/blob_finish.dm @@ -1,9 +1,9 @@ /datum/game_mode/blob/check_finished() - if(infected_crew.len > burst)//Some blobs have yet to burst + if(blob_overminds.len > cores_to_spawn && cores_to_spawn > blob_cores.len)//Some blobs have yet to burst return 0 if(blobwincount <= blobs_legit.len)//Blob took over return 1 - if(!blob_cores.len && !overminds.len) //blob is dead + if(!overminds.len && !blob_cores.len) //blob is dead if(config.continuous["blob"]) continuous_sanity_checked = 1 //Nonstandard definition of "alive" gets past the check otherwise SSshuttle.emergencyNoEscape = 0 @@ -43,9 +43,9 @@ /datum/game_mode/proc/auto_declare_completion_blob() if(istype(ticker.mode,/datum/game_mode/blob) ) var/datum/game_mode/blob/blob_mode = src - if(blob_mode.infected_crew.len) - var/text = "The blob[(blob_mode.infected_crew.len > 1 ? "s were" : " was")]:" - for(var/datum/mind/blob in blob_mode.infected_crew) + if(blob_mode.blob_overminds.len) + var/text = "The blob[(blob_mode.blob_overminds.len > 1 ? "s were" : " was")]:" + for(var/datum/mind/blob in blob_mode.blob_overminds) text += printplayer(blob) world << text return 1 \ No newline at end of file diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index 42514f7194c..f38cc74d236 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -15,16 +15,16 @@ var/point_rate = 2 -/obj/effect/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2) +/obj/effect/blob/core/New(loc, var/client/new_overmind = null, var/new_rate = 2, var/placed = 0) blob_cores += src SSobj.processing |= src update_icon() //so it atleast appears - if(!overmind) + if(!placed && !overmind) create_overmind(new_overmind) if(overmind) update_icon() point_rate = new_rate - ..(loc, h) + ..() /obj/effect/blob/core/update_icon() overlays.Cut() @@ -95,7 +95,7 @@ C = new_overmind if(C) - var/mob/camera/blob/B = new(src.loc) + var/mob/camera/blob/B = new(src.loc, 1) B.key = C.key B.blob_core = src src.overmind = B diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index b4b3f881929..b45b147a3fd 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -18,8 +18,22 @@ var/datum/reagent/blob/blob_reagent_datum = new/datum/reagent/blob() var/list/blob_mobs = list() var/ghostimage = null + var/placed = 0 + var/base_point_rate = 2 //for blob core placement + var/manualplace_min_time = 600 //in deciseconds //a minute, to get bearings + var/autoplace_max_time = 3600 //six minutes, as long as should be needed -/mob/camera/blob/New() +/mob/camera/blob/New(loc, placed = 0, mode_made = 0) + if(placed) //we already have a core! + manualplace_min_time = 0 + autoplace_max_time = 0 + placed = 1 + else + if(mode_made) + manualplace_min_time = world.time + BLOB_NO_PLACE_TIME + else + manualplace_min_time += world.time + autoplace_max_time += world.time overminds += src var/new_name = "[initial(name)] ([rand(1, 999)])" name = new_name @@ -39,7 +53,15 @@ /mob/camera/blob/Life() if(!blob_core) - qdel(src) + if(!placed) + if(manualplace_min_time && world.time >= manualplace_min_time) + src << "You may now place your blob core." + src << "You will automatically place your blob core in [round((autoplace_max_time - world.time)/600, 0.5)] minutes." + manualplace_min_time = 0 + if(autoplace_max_time && world.time >= autoplace_max_time) + place_blob_core(base_point_rate, 1) + else + qdel(src) ..() /mob/camera/blob/Destroy() @@ -115,13 +137,24 @@ if(blob_core) stat(null, "Core Health: [blob_core.health]") stat(null, "Power Stored: [blob_points]/[max_blob_points]") + if(!placed) + stat(null, "Time Before Automatic Placement: [max(round((autoplace_max_time - world.time)*0.1, 0.1), 0)]") + if(manualplace_min_time) + stat(null, "Time Before Manual Placement: [max(round((manualplace_min_time - world.time)*0.1, 0.1), 0)]") /mob/camera/blob/Move(NewLoc, Dir = 0) - var/obj/effect/blob/B = locate() in range("3x3", NewLoc) - if(B) - loc = NewLoc + if(placed) + var/obj/effect/blob/B = locate() in range("3x3", NewLoc) + if(B) + loc = NewLoc + else + return 0 else - return 0 + var/area/A = get_area(NewLoc) + if(istype(NewLoc, /turf/space) || istype(A, /area/shuttle)) //if unplaced, can't go on shuttles or space tiles + return 0 + loc = NewLoc + return 1 /mob/camera/blob/proc/can_attack() return (world.time > (last_attack + CLICK_CD_RANGE)) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 4c647a30145..55fd500f9b8 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -7,6 +7,28 @@ // Power verbs +/mob/camera/blob/proc/place_blob_core(var/point_rate = base_point_rate, var/override = 0) + if(world.time <= manualplace_min_time && world.time <= autoplace_max_time) + src << "It is too early to place your blob core!" + return 0 + if(placed) + return 1 + if(!override) + for(var/mob/living/M in range(7, src)) + if(M.client) + src << "There is someone too close to place your blob core!" + return 0 + else if(override == 1) + var/turf/T = pick(blobstart) + loc = T //got overrided? you're somewhere random, motherfucker + var/obj/effect/blob/core/core = new(get_turf(src), null, point_rate, 1) + core.overmind = src + blob_core = core + core.update_icon() + update_health_hud() + placed = 1 + return 1 + /mob/camera/blob/verb/transport_core() set category = "Blob" set name = "Jump to Core" @@ -263,32 +285,6 @@ src << "In addition to the buttons on your HUD, there are a few click shortcuts to speed up expansion and defense." src << "Shortcuts: Click = Expand Blob | Middle Mouse Click = Rally Spores | Ctrl Click = Create Shield Blob | Alt Click = Remove Blob" src << "Attempting to talk will send a message to all other overminds, allowing you to coordinate with them." - -/datum/action/innate/blob - background_icon_state = "bg_alien" - -/datum/action/innate/blob/earlyhelp - name = "Blob Help" - button_icon_state = "blob" - -/datum/action/innate/blob_earlyhelp/Activate() - owner << "You are a blob!" - owner << "You will shortly burst, and should find a quiet place to do so, out of sight of the station." - owner << "Alternatively, you could burst near a place that would hinder the station, such as telecomms or science." - owner << "Once you burst, you can get additional information by pressing this button again." - -/datum/action/innate/blob/earlycomm - name = "Blob Communication" - button_icon_state = "blob_comm" - -/datum/action/innate/blob/earlycomm/Activate() - var/msg = stripped_input(owner, "What do you wish to tell your fellow blobs?", null, "") - if(msg && owner) - var/mob/living/carbon/human/O = owner - var/spanned_message = O.say_quote(msg, O.get_spans()) - var/rendered = "\[Blob Telepathy\] [O.real_name] [spanned_message]" - var/datum/game_mode/blob/B = ticker.mode - B.show_message("[rendered]") - for(var/mob/M in mob_list) - if(isobserver(M)) - M << "(F) [rendered]" \ No newline at end of file + if(!placed) + src << "You will automatically place your blob core in [round((autoplace_max_time - world.time)/600, 0.5)] minutes." + src << "You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the button in the bottom right corner of the screen." diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 124b9bd9250..d0aae03c7b1 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -588,7 +588,7 @@ dat += "
" if(istype(ticker.mode,/datum/game_mode/blob)) var/datum/game_mode/blob/mode = ticker.mode - blob_minds |= mode.infected_crew + blob_minds |= mode.blob_overminds dat += "" for(var/datum/mind/blob in blob_minds) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 90a14e8d47c..90b385a3376 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -261,7 +261,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that log_admin("[key_name(src)] has blobized [M.key].") var/mob/living/carbon/human/H = M spawn(0) - H.Blobize() + var/mob/camera/blob/B = H.become_overmind() + B.place_blob_core(B.base_point_rate, -1) //place them wherever they are else alert("Invalid mob") diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index ed2c22ce622..343c4bd5758 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -26,4 +26,4 @@ var/turf/T = pick(blobstart) if(!T) return kill() - new/obj/effect/blob/core(T, 200, null, new_rate) + new/obj/effect/blob/core(T, null, new_rate) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index bac5319ef2a..9a5aae78ea7 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -418,14 +418,14 @@ . = new_slime qdel(src) -/mob/living/carbon/human/proc/Blobize() - if (notransform) - return - if(!client) //TOO BAD - new /obj/effect/blob/core (loc) +/mob/proc/become_overmind(mode_made = 0) + var/mob/camera/blob/B = new /mob/camera/blob(loc, 0, mode_made) + if(mind) + mind.transfer_to(B) else - new /obj/effect/blob/core (loc,new_overmind = src.client) - gib(src) + B.key = key + . = B + qdel(src) /mob/proc/become_god(var/side_colour) From cb5672879211c463d4787ecbfe99e0cf7102afee Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Wed, 9 Mar 2016 20:28:29 -0500 Subject: [PATCH 2/5] ah,,,,, --- code/game/gamemodes/blob/blob.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 48788f242f1..768f23fe646 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -14,7 +14,7 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b config_tag = "blob" antag_flag = ROLE_BLOB - required_players = 0//25 + required_players = 25 required_enemies = 1 recommended_enemies = 1 From b9128fe1b107304ef25828b6868c74c2d17c0b7c Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Wed, 9 Mar 2016 20:58:36 -0500 Subject: [PATCH 3/5] Thoroughness in placement checking; can't place on dense turfs can place on dense objects can't place if there's someone in a large view() --- code/game/gamemodes/blob/powers.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 55fd500f9b8..41d3fa14386 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -18,6 +18,14 @@ if(M.client) src << "There is someone too close to place your blob core!" return 0 + for(var/mob/living/M in view(15, src)) + if(M.client) + src << "Someone could see your blob core from here!" + return 0 + var/turf/T = get_turf(src) + if(T.density) + src << "This spot is too dense to place a blob core on!" + return 0 else if(override == 1) var/turf/T = pick(blobstart) loc = T //got overrided? you're somewhere random, motherfucker From a1077721663a24f8b793ec2dcf8d365958fd51e7 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Thu, 10 Mar 2016 10:20:46 -0500 Subject: [PATCH 4/5] fixes --- code/game/gamemodes/blob/overmind.dm | 4 ++-- code/game/gamemodes/blob/powers.dm | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index b45b147a3fd..8603e6096a6 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -23,8 +23,8 @@ var/manualplace_min_time = 600 //in deciseconds //a minute, to get bearings var/autoplace_max_time = 3600 //six minutes, as long as should be needed -/mob/camera/blob/New(loc, placed = 0, mode_made = 0) - if(placed) //we already have a core! +/mob/camera/blob/New(loc, pre_placed = 0, mode_made = 0) + if(pre_placed) //we already have a core! manualplace_min_time = 0 autoplace_max_time = 0 placed = 1 diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 41d3fa14386..7efa0387a5b 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -8,17 +8,21 @@ // Power verbs /mob/camera/blob/proc/place_blob_core(var/point_rate = base_point_rate, var/override = 0) - if(world.time <= manualplace_min_time && world.time <= autoplace_max_time) + if(!override && world.time <= manualplace_min_time && world.time <= autoplace_max_time) src << "It is too early to place your blob core!" return 0 if(placed) return 1 if(!override) for(var/mob/living/M in range(7, src)) + if("blob" in M.faction) + continue if(M.client) src << "There is someone too close to place your blob core!" return 0 - for(var/mob/living/M in view(15, src)) + for(var/mob/living/M in view(13, src)) + if("blob" in M.faction) + continue if(M.client) src << "Someone could see your blob core from here!" return 0 @@ -26,6 +30,16 @@ if(T.density) src << "This spot is too dense to place a blob core on!" return 0 + for(var/obj/O in T) + if(istype(O, /obj/effect/blob)) + if(istype(O, /obj/effect/blob/normal)) + qdel(O) + else + src << "There is already a blob here!" + return 0 + if(O.density) + src << "This spot is too dense to place a blob core on!" + return 0 else if(override == 1) var/turf/T = pick(blobstart) loc = T //got overrided? you're somewhere random, motherfucker From 5f706e5cd1025173a16eeef01125d4ca9c6dc1db Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Thu, 10 Mar 2016 11:47:05 -0500 Subject: [PATCH 5/5] this is old code --- code/game/gamemodes/blob/blobs/core.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index f38cc74d236..eb0955b150a 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -15,7 +15,7 @@ var/point_rate = 2 -/obj/effect/blob/core/New(loc, var/client/new_overmind = null, var/new_rate = 2, var/placed = 0) +/obj/effect/blob/core/New(loc, client/new_overmind = null, new_rate = 2, placed = 0) blob_cores += src SSobj.processing |= src update_icon() //so it atleast appears
Blob
Progress: [blobs_legit.len]/[mode.blobwincount]