From 20b17eceec39546022670d04325667dc33a750a1 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Wed, 18 Oct 2017 20:55:28 -0500 Subject: [PATCH 01/30] Disentangles blob from blob mode/removes blob mode --- code/__DEFINES/role_preferences.dm | 2 +- code/game/gamemodes/blob/blob_finish.dm | 72 -------------------- code/game/gamemodes/blob/blob_report.dm | 3 + code/game/gamemodes/blob/blobs/core.dm | 35 +--------- code/game/gamemodes/blob/overmind.dm | 76 +++++++++++++++++----- code/game/gamemodes/blob/powers.dm | 3 +- code/game/gamemodes/blob/theblob.dm | 22 +++---- code/modules/admin/player_panel.dm | 10 +-- code/modules/admin/verbs/debug.dm | 5 +- code/modules/events/blob.dm | 32 +++++++++ code/modules/mob/dead/observer/observer.dm | 9 --- code/modules/mob/living/living.dm | 12 +--- code/modules/mob/transform_procs.dm | 4 +- config/game_options.txt | 3 + tgstation.dme | 2 - 15 files changed, 119 insertions(+), 171 deletions(-) delete mode 100644 code/game/gamemodes/blob/blob_finish.dm diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index ab62710652..39f28528d0 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -40,7 +40,7 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_ALIEN, ROLE_PAI, ROLE_CULTIST = /datum/game_mode/cult, - ROLE_BLOB = /datum/game_mode/blob, + ROLE_BLOB, ROLE_NINJA, ROLE_MONKEY = /datum/game_mode/monkey, ROLE_REVENANT, diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm deleted file mode 100644 index 6d97fb52f9..0000000000 --- a/code/game/gamemodes/blob/blob_finish.dm +++ /dev/null @@ -1,72 +0,0 @@ -/datum/game_mode/blob/check_finished() - if(blobwincount <= GLOB.blobs_legit.len)//Blob took over - return 1 - for(var/datum/mind/blob in blob_overminds) - if(isovermind(blob.current)) - var/mob/camera/blob/B = blob.current - if(B.blob_core || !B.placed) - return 0 - if(!GLOB.blob_cores.len) //blob is dead - if(CONFIG_GET(keyed_flag_list/continuous)["blob"]) - message_sent = FALSE //disable the win count at this point - continuous_sanity_checked = 1 //Nonstandard definition of "alive" gets past the check otherwise - SSshuttle.clearHostileEnvironment(src) - return ..() - return 1 - return ..() - - -/datum/game_mode/blob/declare_completion() - if(round_converted) //So badmin blobs later don't step on the dead natural blobs metaphorical toes - ..() - if(blobwincount <= GLOB.blobs_legit.len) - SSticker.mode_result = "win - blob took over" - to_chat(world, "The blob has taken over the station!") - to_chat(world, "The entire station was eaten by the Blob!") - log_game("Blob mode completed with a blob victory.") - - SSticker.news_report = BLOB_WIN - - else if(station_was_nuked) - SSticker.mode_result = "halfwin - nuke" - to_chat(world, "Partial Win: The station has been destroyed!") - to_chat(world, "Directive 7-12 has been successfully carried out, preventing the Blob from spreading.") - log_game("Blob mode completed with a tie (station destroyed).") - - SSticker.news_report = BLOB_NUKE - - else if(!GLOB.blob_cores.len) - SSticker.mode_result = "loss - blob eliminated" - to_chat(world, "The staff has won!") - to_chat(world, "The alien organism has been eradicated from the station!") - log_game("Blob mode completed with a crew victory.") - - SSticker.news_report = BLOB_DESTROYED - - ..() - return 1 - -/datum/game_mode/blob/printplayer(datum/mind/ply, fleecheck) - if((ply in blob_overminds)) - var/text = "
[ply.key] was [ply.name]" - if(isovermind(ply.current)) - var/mob/camera/blob/B = ply.current - text += "([B.blob_reagent_datum.name]) and" - if(B.blob_core) - text += " survived" - else - text += " was destroyed" - else - text += " and was destroyed" - return text - return ..() - -/datum/game_mode/proc/auto_declare_completion_blob() - if(istype(SSticker.mode, /datum/game_mode/blob) ) - var/datum/game_mode/blob/blob_mode = src - 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) - to_chat(world, text) - return 1 diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm index 519fc2e296..7f8a61ef90 100644 --- a/code/game/gamemodes/blob/blob_report.dm +++ b/code/game/gamemodes/blob/blob_report.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /datum/game_mode/blob/send_intercept(report = 0) @@ -40,6 +41,8 @@ +======= +>>>>>>> be748e3... Disentangles blob from blob mode/removes blob mode (#31780) /datum/station_state var/floor = 0 var/wall = 0 diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index 3099b6f3f8..28be931f9b 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -9,7 +9,6 @@ point_return = -1 health_regen = 0 //we regen in Life() instead of when pulsed var/core_regen = 2 - var/overmind_get_delay = 0 //we don't want to constantly try to find an overmind, this var tracks when we'll try to get an overmind again var/resource_delay = 0 var/point_rate = 2 @@ -20,7 +19,7 @@ GLOB.poi_list |= src update_icon() //so it atleast appears if(!placed && !overmind) - create_overmind(new_overmind) + qdel(src) if(overmind) update_icon() point_rate = new_rate @@ -61,7 +60,7 @@ if(QDELETED(src)) return if(!overmind) - create_overmind() + qdel(src) else if(resource_delay <= world.time) resource_delay = world.time + 10 // 1 second @@ -75,33 +74,3 @@ B.change_to(/obj/structure/blob/shield/core, overmind) ..() - -/obj/structure/blob/core/proc/create_overmind(client/new_overmind, override_delay) - if(overmind_get_delay > world.time && !override_delay) - return - - overmind_get_delay = world.time + 150 //if this fails, we'll try again in 15 seconds - - if(overmind) - qdel(overmind) - - var/client/C = null - var/list/candidates = list() - - if(!new_overmind) - candidates = pollCandidatesForMob("Do you want to play as a blob overmind?", ROLE_BLOB, null, ROLE_BLOB, 50, src) //we're technically not a mob but behave similarly - if(candidates.len) - C = pick(candidates) - else - C = new_overmind - - if(C) - var/mob/camera/blob/B = new(src.loc, 1) - B.key = C.key - B.blob_core = src - src.overmind = B - update_icon() - if(B.mind && !B.mind.special_role) - B.mind.special_role = "Blob Overmind" - return 1 - return 0 diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 9f8a44bed2..c14f072d1b 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -1,3 +1,9 @@ +//Few global vars to track the blob +GLOBAL_LIST_EMPTY(blobs) //complete list of all blobs made. +GLOBAL_LIST_EMPTY(blob_cores) +GLOBAL_LIST_EMPTY(overminds) +GLOBAL_LIST_EMPTY(blob_nodes) + /mob/camera/blob name = "Blob Overmind" real_name = "Blob Overmind" @@ -26,19 +32,14 @@ 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 + var/list/blobs_legit = list() + var/blobwincount = 400 + var/victory_in_progress = FALSE -/mob/camera/blob/Initialize(mapload, pre_placed = 0, mode_made = 0, starting_points = 60) +/mob/camera/blob/Initialize(mapload, starting_points = 60) blob_points = starting_points - if(pre_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 + manualplace_min_time += world.time + autoplace_max_time += world.time GLOB.overminds += src var/new_name = "[initial(name)] ([rand(1, 999)])" name = new_name @@ -50,6 +51,8 @@ if(blob_core) blob_core.update_icon() + SSshuttle.registerHostileEnvironment(src) + .= ..() /mob/camera/blob/Life() @@ -63,8 +66,49 @@ place_blob_core(base_point_rate, 1) else qdel(src) + else if(!victory_in_progress && (blobs_legit.len >= blobwincount)) + victory_in_progress = TRUE + priority_announce("Biohazard has reached critical mass. Station loss is imminent.", "Biohazard Alert") + set_security_level("delta") + max_blob_points = INFINITY + blob_points = INFINITY + addtimer(CALLBACK(src, .proc/victory), 660) ..() + +/mob/camera/blob/proc/victory() + for(var/mob/living/L in GLOB.mob_list) + var/turf/T = get_turf(L) + if(!T || !(T.z in GLOB.station_z_levels)) + continue + + if(L in GLOB.overminds || L.checkpass(PASSBLOB)) + continue + + var/area/Ablob = get_area(T) + + if(!Ablob.blob_allowed) + continue + + playsound(L, 'sound/effects/splat.ogg', 50, 1) + L.death() + new/mob/living/simple_animal/hostile/blob/blobspore(T) + + for(var/V in GLOB.sortedAreas) + var/area/A = V + if(!A.blob_allowed) + continue + A.color = blob_reagent_datum.color + A.name = "blob" + A.icon = 'icons/mob/blob.dmi' + A.icon_state = "blob_shield" + A.layer = BELOW_MOB_LAYER + A.invisibility = 0 + A.blend_mode = 0 + to_chat(world, "[real_name] consumed the station in an unstoppable tide!") + SSticker.news_report = BLOB_WIN + SSticker.force_ending = 1 + /mob/camera/blob/Destroy() for(var/BL in GLOB.blobs) var/obj/structure/blob/B = BL @@ -78,6 +122,8 @@ BM.update_icons() GLOB.overminds -= src + SSshuttle.clearHostileEnvironment(src) + return ..() /mob/camera/blob/Login() @@ -150,12 +196,8 @@ if(statpanel("Status")) if(blob_core) stat(null, "Core Health: [blob_core.obj_integrity]") - stat(null, "Power Stored: [blob_points]/[max_blob_points]") - if(istype(SSticker.mode, /datum/game_mode/blob)) - var/datum/game_mode/blob/B = SSticker.mode - stat(null, "Blobs to Win: [GLOB.blobs_legit.len]/[B.blobwincount]") - else - stat(null, "Total Blobs: [GLOB.blobs.len]") + stat(null, "Power Stored: [blob_points]/[max_blob_points]") + stat(null, "Blobs to Win: [blobs_legit.len]/[blobwincount]") if(free_chem_rerolls) stat(null, "You have [free_chem_rerolls] Free Chemical Reroll\s Remaining") if(!placed) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 865a58fd81..0dd592665f 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -46,8 +46,9 @@ if(placed && blob_core) blob_core.forceMove(loc) else - var/obj/structure/blob/core/core = new(get_turf(src), null, point_rate, 1) + var/obj/structure/blob/core/core = new(get_turf(src), src, point_rate, 1) core.overmind = src + blobs_legit += src blob_core = core core.update_icon() update_health_hud() diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 183ec88b23..8570cf294c 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -20,10 +20,11 @@ var/atmosblock = FALSE //if the blob blocks atmos and heat spread var/mob/camera/blob/overmind -/obj/structure/blob/Initialize() +/obj/structure/blob/Initialize(mapload, owner_overmind) + overmind = owner_overmind var/area/Ablob = get_area(loc) if(Ablob.blob_allowed) //Is this area allowed for winning as blob? - GLOB.blobs_legit += src + overmind.blobs_legit += src GLOB.blobs += src //Keep track of the blob in the normal list either way setDir(pick(GLOB.cardinals)) update_icon() @@ -39,7 +40,8 @@ if(atmosblock) atmosblock = FALSE air_update_turf(1) - GLOB.blobs_legit -= src //if it was in the legit blobs list, it isn't now + if(overmind) + overmind.blobs_legit -= src //if it was in the legit blobs list, it isn't now GLOB.blobs -= src //it's no longer in the all blobs list either playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Expand() is no longer broken, no check necessary. return ..() @@ -182,11 +184,7 @@ A.blob_act(src) //also hit everything in the turf if(make_blob) //well, can we? - var/obj/structure/blob/B = new /obj/structure/blob/normal(src.loc) - if(controller) - B.overmind = controller - else - B.overmind = overmind + var/obj/structure/blob/B = new /obj/structure/blob/normal(src.loc, (controller || overmind)) B.density = TRUE if(T.Enter(B,src)) //NOW we can attempt to move into the tile B.density = initial(B.density) @@ -232,6 +230,7 @@ user.changeNext_move(CLICK_CD_MELEE) to_chat(user, "The analyzer beeps once, then reports:
") SEND_SOUND(user, sound('sound/machines/ping.ogg')) + to_chat(user, "Progress to Critical Mass: [overmind.blobs_legit.len]/[overmind.blobwincount].") chemeffectreport(user) typereport(user) else @@ -296,9 +295,7 @@ if(!ispath(type)) throw EXCEPTION("change_to(): invalid type for blob") return - var/obj/structure/blob/B = new type(src.loc) - if(controller) - B.overmind = controller + var/obj/structure/blob/B = new type(src.loc, controller) B.creation_action() B.update_icon() B.setDir(dir) @@ -310,9 +307,12 @@ var/datum/atom_hud/hud_to_check = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] if(user.research_scanner || hud_to_check.hudusers[user]) to_chat(user, "Your HUD displays an extensive report...
") + to_chat(user, "Progress to Critical Mass: [overmind.blobs_legit.len]/[overmind.blobwincount].") chemeffectreport(user) typereport(user) else + if(isobserver(user)) + to_chat(user, "Progress to Critical Mass: [overmind.blobs_legit.len]/[overmind.blobwincount].") to_chat(user, "It seems to be made of [get_chem_name()].") /obj/structure/blob/proc/scannerreport() diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index f40b85f7d7..070a1e7e6c 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -594,19 +594,13 @@ for(var/mob/camera/blob/B in GLOB.mob_list) blob_minds |= B.mind - if(istype(SSticker.mode, /datum/game_mode/blob) || blob_minds.len) - dat += "
" - if(istype(SSticker.mode, /datum/game_mode/blob)) - var/datum/game_mode/blob/mode = SSticker.mode - blob_minds |= mode.blob_overminds - dat += "" - for(var/datum/mind/blob in blob_minds) - var/mob/M = blob.current + var/mob/camera/blob/M = blob.current if(M) dat += "" dat += "" dat += "" + dat += "" else dat += "" dat += "" diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 735d0d9f95..a747a347a2 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -261,10 +261,7 @@ GLOBAL_PROTECT(LastAdminCalledProc) if(ishuman(M)) log_admin("[key_name(src)] has blobized [M.key].") var/mob/living/carbon/human/H = M - spawn(0) - var/mob/camera/blob/B = H.become_overmind(FALSE) - B.place_blob_core(B.base_point_rate, -1) //place them wherever they are - + H.become_overmind() else alert("Invalid mob") diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 42b54f3856..4720a9c92f 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /datum/round_event_control/blob name = "Blob" typepath = /datum/round_event/ghost_role/blob @@ -36,3 +37,34 @@ message_admins("[key_name_admin(BC.overmind)] has been made into a blob overmind by an event.") log_game("[key_name(BC.overmind)] was spawned as a blob overmind by an event.") return SUCCESSFUL_SPAWN +======= +/datum/round_event_control/blob + name = "Blob" + typepath = /datum/round_event/ghost_role/blob + weight = 10 + max_occurrences = 1 + + min_players = 20 + + gamemode_blacklist = list("blob") //Just in case a blob survives that long + +/datum/round_event/ghost_role/blob + announceWhen = 12 + role_name = "blob overmind" + +/datum/round_event/ghost_role/blob/announce() + priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg') + +/datum/round_event/ghost_role/blob/spawn_role() + if(!GLOB.blobstart.len) + return MAP_ERROR + var/list/candidates = get_candidates("blob", null, ROLE_BLOB) + if(!candidates.len) + return NOT_ENOUGH_PLAYERS + var/mob/dead/observer/new_blob = pick(candidates) + var/mob/camera/blob/BC = new_blob.become_overmind() + spawned_mobs += BC + message_admins("[key_name_admin(BC)] has been made into a blob overmind by an event.") + log_game("[key_name(BC)] was spawned as a blob overmind by an event.") + return SUCCESSFUL_SPAWN +>>>>>>> be748e3... Disentangles blob from blob mode/removes blob mode (#31780) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 6cc0a9324f..a423f361ce 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -305,15 +305,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/is_active() return 0 -/mob/dead/observer/Stat() - ..() - if(statpanel("Status")) - if(SSticker.HasRoundStarted()) - if(istype(SSticker.mode, /datum/game_mode/blob)) - var/datum/game_mode/blob/B = SSticker.mode - if(B.message_sent) - stat(null, "Blobs to Blob Win: [GLOB.blobs_legit.len]/[B.blobwincount]") - /mob/dead/observer/verb/reenter_corpse() set category = "Ghost" set name = "Re-enter Corpse" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bbb36edad3..e510f90e3a 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -196,7 +196,7 @@ M.pass_flags &= ~PASSMOB now_pushing = 0 - + if(!move_failed) return 1 @@ -780,16 +780,6 @@ /mob/living/proc/get_standard_pixel_y_offset(lying = 0) return initial(pixel_y) -/mob/living/Stat() - ..() - - if(statpanel("Status")) - if(SSticker && SSticker.mode) - if(istype(SSticker.mode, /datum/game_mode/blob)) - var/datum/game_mode/blob/B = SSticker.mode - if(B.message_sent) - stat(null, "Blobs to Blob Win: [GLOB.blobs_legit.len]/[B.blobwincount]") - /mob/living/cancel_camera() ..() cameraFollow = null diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index dc87736e5d..592d19e0b1 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -462,8 +462,8 @@ . = new_slime qdel(src) -/mob/proc/become_overmind(mode_made, starting_points = 60) - var/mob/camera/blob/B = new /mob/camera/blob(loc, 0, mode_made, starting_points) +/mob/proc/become_overmind(starting_points = 60) + var/mob/camera/blob/B = new /mob/camera/blob(loc, starting_points) if(mind) mind.transfer_to(B) else diff --git a/config/game_options.txt b/config/game_options.txt index d577756061..841adf8dca 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -85,8 +85,11 @@ PROBABILITY REVOLUTION 2 PROBABILITY CULT 2 PROBABILITY CHANGELING 2 PROBABILITY WIZARD 4 +<<<<<<< HEAD PROBABILITY BLOB 2 PROBABILITY RAGINMAGES 2 +======= +>>>>>>> be748e3... Disentangles blob from blob mode/removes blob mode (#31780) PROBABILITY MONKEY 0 PROBABILITY METEOR 0 PROBABILITY EXTENDED 0 diff --git a/tgstation.dme b/tgstation.dme index 903f4878c8..bf006f8e65 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -444,8 +444,6 @@ #include "code\game\gamemodes\objective.dm" #include "code\game\gamemodes\objective_items.dm" #include "code\game\gamemodes\objective_team.dm" -#include "code\game\gamemodes\blob\blob.dm" -#include "code\game\gamemodes\blob\blob_finish.dm" #include "code\game\gamemodes\blob\blob_report.dm" #include "code\game\gamemodes\blob\overmind.dm" #include "code\game\gamemodes\blob\powers.dm" From 7c020af6283d8ccf220b7504fe659c1b6b4bbfef Mon Sep 17 00:00:00 2001 From: oranges Date: Fri, 20 Oct 2017 12:56:39 +1300 Subject: [PATCH 02/30] Fixes stack overflow in orbit datum --- code/modules/orbit/orbit.dm | 117 ++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/code/modules/orbit/orbit.dm b/code/modules/orbit/orbit.dm index 27fc2d86df..600042a827 100644 --- a/code/modules/orbit/orbit.dm +++ b/code/modules/orbit/orbit.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /datum/orbit var/atom/movable/orbiter var/atom/orbiting @@ -110,3 +111,119 @@ . = ..() if (orbiting) stop_orbit() +======= +/datum/orbit + var/atom/movable/orbiter + var/atom/orbiting + var/lock = TRUE + var/turf/lastloc + var/lastprocess + +/datum/orbit/New(_orbiter, _orbiting, _lock) + orbiter = _orbiter + orbiting = _orbiting + SSorbit.processing += src + if (!orbiting.orbiters) + orbiting.orbiters = list() + orbiting.orbiters += src + + if (orbiter.orbiting) + orbiter.stop_orbit() + orbiter.orbiting = src + Check() + lock = _lock + +//do not qdel directly, use stop_orbit on the orbiter. (This way the orbiter can bind to the orbit stopping) +/datum/orbit/Destroy(force = FALSE) + SSorbit.processing -= src + if (orbiter) + orbiter.orbiting = null + orbiter = null + if (orbiting) + if (orbiting.orbiters) + orbiting.orbiters -= src + if (!orbiting.orbiters.len)//we are the last orbit, delete the list + orbiting.orbiters = null + orbiting = null + return ..() + +/datum/orbit/proc/Check(turf/targetloc) + if (!orbiter) + qdel(src) + return + if (!orbiting) + orbiter.stop_orbit() + return + if (!orbiter.orbiting) //admin wants to stop the orbit. + orbiter.orbiting = src //set it back to us first + orbiter.stop_orbit() + lastprocess = world.time + if (!targetloc) + targetloc = get_turf(orbiting) + if (!targetloc || (!lock && orbiter.loc != lastloc && orbiter.loc != targetloc)) + orbiter.stop_orbit() + return + orbiter.loc = targetloc + orbiter.update_parallax_contents() + lastloc = orbiter.loc + for(var/other_orbit in orbiter.orbiters) + var/datum/orbit/OO = other_orbit + if(OO == src) + continue + OO.Check(targetloc) + +/atom/movable/var/datum/orbit/orbiting = null +/atom/var/list/orbiters = null + +//A: atom to orbit +//radius: range to orbit at, radius of the circle formed by orbiting (in pixels) +//clockwise: whether you orbit clockwise or anti clockwise +//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete) +//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default. +//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts +//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts) + +/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE) + if (!istype(A)) + return + + new/datum/orbit(src, A, lockinorbit) + if (!orbiting) //something failed, and our orbit datum deleted itself + return + var/matrix/initial_transform = matrix(transform) + + //Head first! + if (pre_rotation) + var/matrix/M = matrix(transform) + var/pre_rot = 90 + if(!clockwise) + pre_rot = -90 + M.Turn(pre_rot) + transform = M + + var/matrix/shift = matrix(transform) + shift.Translate(0,radius) + transform = shift + + SpinAnimation(rotation_speed, -1, clockwise, rotation_segments) + + //we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit + transform = initial_transform + +/atom/movable/proc/stop_orbit() + SpinAnimation(0,0) + qdel(orbiting) + +/atom/Destroy(force = FALSE) + . = ..() + if (orbiters) + for (var/thing in orbiters) + var/datum/orbit/O = thing + if (O.orbiter) + O.orbiter.stop_orbit() + +/atom/movable/Destroy(force = FALSE) + . = ..() + if (orbiting) + stop_orbit() +>>>>>>> e474c91... Merge pull request #31904 from AnturK/infinite From b7c8330761694e1baff602d42a1c53bde06e4159 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 20 Oct 2017 09:33:39 -0500 Subject: [PATCH 03/30] Update blob_report.dm --- code/game/gamemodes/blob/blob_report.dm | 45 ------------------------- 1 file changed, 45 deletions(-) diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm index 7f8a61ef90..2a3c5e6faa 100644 --- a/code/game/gamemodes/blob/blob_report.dm +++ b/code/game/gamemodes/blob/blob_report.dm @@ -1,48 +1,3 @@ -<<<<<<< HEAD - - -/datum/game_mode/blob/send_intercept(report = 0) - var/intercepttext = "" - switch(report) - if(1) - intercepttext += "NanoTrasen Update: Biohazard Alert.
" - intercepttext += "Reports indicate the probable transfer of a biohazardous agent onto [station_name()] during the last crew deployment cycle.
" - intercepttext += "Preliminary analysis of the organism classifies it as a level 5 biohazard. The origin of the biohazard is unknown.
" - intercepttext += "Biohazard Response Procedure 5-6 has been issued for [station_name()].
" - intercepttext += "Orders for all [station_name()] personnel are as follows:
" - intercepttext += " 1. Locate any outbreaks of the organism on the station.
" - intercepttext += " 2. If found, use any neccesary means to contain and destroy the organism.
" - intercepttext += " 3. Avoid damage to the capital infrastructure of the station.
" - intercepttext += "
Note in the event of a quarantine breach or uncontrolled spread of the biohazard, Biohazard Response Procedure 5-12 may be issued.
" - print_command_report(text=intercepttext,title="Level 5-6 Biohazard Response Procedures",announce=FALSE) - priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg') - if(2) - var/nukecode = random_nukecode() - for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines) - if(bomb && bomb.r_code) - if(bomb.z in GLOB.station_z_levels) - bomb.r_code = nukecode - - intercepttext += "NanoTrasen Update: Biohazard Alert.
" - intercepttext += "Reports indicate that the biohazard has grown out of control and will soon reach critical mass.
" - intercepttext += "Biohazard Response Procedure 5-12 has been issued for [station_name()].
" - intercepttext += "Orders for all [station_name()] personnel are as follows:
" - intercepttext += "1. Secure the Nuclear Authentication Disk.
" - intercepttext += "2. Detonate the Nuke located in the vault.
" - intercepttext += "Nuclear Authentication Code: [nukecode]
" - print_command_report(text=intercepttext,announce=TRUE) - - for(var/mob/living/silicon/ai/aiPlayer in GLOB.player_list) - if (aiPlayer.client) - 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. The nuclear failsafe must be activated at any cost, the code is: [nukecode]." - aiPlayer.set_zeroth_law(law) - else - ..() - - - -======= ->>>>>>> be748e3... Disentangles blob from blob mode/removes blob mode (#31780) /datum/station_state var/floor = 0 var/wall = 0 From c0ddbacd2955da6cf47c901f7b05aa533e0d661d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 20 Oct 2017 09:33:50 -0500 Subject: [PATCH 04/30] Update blob.dm --- code/modules/events/blob.dm | 41 ------------------------------------- 1 file changed, 41 deletions(-) diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 4720a9c92f..bb0f59f205 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -1,43 +1,3 @@ -<<<<<<< HEAD -/datum/round_event_control/blob - name = "Blob" - typepath = /datum/round_event/ghost_role/blob - weight = 5 - max_occurrences = 1 - - min_players = 20 - earliest_start = 18000 //30 minutes - - gamemode_blacklist = list("blob") //Just in case a blob survives that long - -/datum/round_event/ghost_role/blob - announceWhen = 12 - role_name = "blob overmind" - var/new_rate = 2 - -/datum/round_event/ghost_role/blob/New(my_processing = TRUE, set_point_rate) - ..() - if(set_point_rate) - new_rate = set_point_rate - -/datum/round_event/ghost_role/blob/announce() - priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg') - - -/datum/round_event/ghost_role/blob/spawn_role() - if(!GLOB.blobstart.len) - return MAP_ERROR - var/list/candidates = get_candidates("blob", null, ROLE_BLOB) - if(!candidates.len) - return NOT_ENOUGH_PLAYERS - var/mob/dead/observer/new_blob = pick(candidates) - var/obj/structure/blob/core/BC = new/obj/structure/blob/core(pick(GLOB.blobstart), new_blob.client, new_rate) - BC.overmind.blob_points = min(20 + GLOB.player_list.len, BC.overmind.max_blob_points) - spawned_mobs += BC.overmind - message_admins("[key_name_admin(BC.overmind)] has been made into a blob overmind by an event.") - log_game("[key_name(BC.overmind)] was spawned as a blob overmind by an event.") - return SUCCESSFUL_SPAWN -======= /datum/round_event_control/blob name = "Blob" typepath = /datum/round_event/ghost_role/blob @@ -67,4 +27,3 @@ message_admins("[key_name_admin(BC)] has been made into a blob overmind by an event.") log_game("[key_name(BC)] was spawned as a blob overmind by an event.") return SUCCESSFUL_SPAWN ->>>>>>> be748e3... Disentangles blob from blob mode/removes blob mode (#31780) From f41c8ccccf5d7fdf40bed567e56b4cb8429c5c93 Mon Sep 17 00:00:00 2001 From: Michiyamenotehifunana <31995558+Michiyamenotehifunana@users.noreply.github.com> Date: Sat, 21 Oct 2017 11:43:41 +0800 Subject: [PATCH 05/30] Nerfs nerfs NO MORE INSTANT BAGGABLE STUNS FROM AUTOLATHES! --- code/citadel/cit_guns.dm | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/code/citadel/cit_guns.dm b/code/citadel/cit_guns.dm index 7127371830..bf8d034148 100644 --- a/code/citadel/cit_guns.dm +++ b/code/citadel/cit_guns.dm @@ -190,13 +190,15 @@ needs_permit = 0 mag_type = /obj/item/ammo_box/magazine/toy/x9 casing_ejector = 0 - spread = 45 //MAXIMUM XCOM MEMES (actually that'd be 90 spread) + spread = 90 //MAXIMUM XCOM MEMES (actually that'd be 180 spread) + w_class = WEIGHT_CLASS_BULKY + weapon_weight = WEAPON_HEAVY /datum/design/foam_x9 name = "Foam Force X9 Rifle" id = "foam_x9" build_type = AUTOLATHE - materials = list(MAT_METAL = 20000, MAT_GLASS = 10000) + materials = list(MAT_METAL = 24000, MAT_GLASS = 14000) build_path = /obj/item/gun/ballistic/automatic/x9/toy category = list("hacked", "Misc") @@ -496,6 +498,9 @@ mag_type = /obj/item/ammo_box/magazine/toy/foamag casing_ejector = FALSE origin_tech = "combat=2;engineering=2;magnets=2" + spread = 60 + w_class = WEIGHT_CLASS_BULKY + weapon_weight = WEAPON_HEAVY /datum/design/foam_magrifle name = "Foam Force MagRifle" @@ -635,7 +640,7 @@ name = "MagTag Hyper Rifle" id = "foam_hyperburst" build_type = AUTOLATHE - materials = list(MAT_METAL = 35000, MAT_GLASS = 15000) + materials = list(MAT_METAL = 35000, MAT_GLASS = 25000) build_path = /obj/item/gun/energy/laser/practice/hyperburst category = list("hacked", "Misc") @@ -680,6 +685,7 @@ suppressed = TRUE burst_size = 1 fire_delay = 0 + spread = 60 actions_types = list() /obj/item/gun/ballistic/automatic/toy/pistol/stealth/update_icon() @@ -695,7 +701,7 @@ name = "Foam Force Stealth Pistol" id = "foam_sp" build_type = AUTOLATHE - materials = list(MAT_METAL = 15000, MAT_GLASS = 1000) + materials = list(MAT_METAL = 30000, MAT_GLASS = 15000) build_path = /obj/item/gun/ballistic/automatic/toy/pistol/stealth category = list("hacked", "Misc") From cd74a1333c1f98b4db02fdf89606677fe7f4c3a5 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 21 Oct 2017 02:30:47 -0400 Subject: [PATCH 06/30] Blank globals will no longer assign null to themselves --- code/__DATASTRUCTURES/globals.dm | 43 +++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/code/__DATASTRUCTURES/globals.dm b/code/__DATASTRUCTURES/globals.dm index bcc860245f..a9199a6f7b 100644 --- a/code/__DATASTRUCTURES/globals.dm +++ b/code/__DATASTRUCTURES/globals.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD //See controllers/globals.dm #define GLOBAL_MANAGED(X, InitValue)\ /datum/controller/global_vars/proc/InitGlobal##X(){\ @@ -35,4 +36,44 @@ #define GLOBAL_LIST(X) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, null) -#define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, null) \ No newline at end of file +#define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, null) +======= +//See controllers/globals.dm +#define GLOBAL_MANAGED(X, InitValue)\ +/datum/controller/global_vars/proc/InitGlobal##X(){\ + ##X = ##InitValue;\ + gvars_datum_init_order += #X;\ +} +#define GLOBAL_UNMANAGED(X) /datum/controller/global_vars/proc/InitGlobal##X() { return; } + +#ifndef TESTING +#define GLOBAL_PROTECT(X)\ +/datum/controller/global_vars/InitGlobal##X(){\ + ..();\ + gvars_datum_protected_varlist += #X;\ +} +#else +#define GLOBAL_PROTECT(X) +#endif + +#define GLOBAL_REAL_VAR(X) var/global/##X +#define GLOBAL_REAL(X, Typepath) var/global##Typepath/##X + +#define GLOBAL_RAW(X) /datum/controller/global_vars/var/global##X + +#define GLOBAL_VAR_INIT(X, InitValue) GLOBAL_RAW(/##X); GLOBAL_MANAGED(X, InitValue) + +#define GLOBAL_VAR_CONST(X, InitValue) GLOBAL_RAW(/const/##X) = InitValue; GLOBAL_UNMANAGED(X) + +#define GLOBAL_LIST_INIT(X, InitValue) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, InitValue) + +#define GLOBAL_LIST_EMPTY(X) GLOBAL_LIST_INIT(X, list()) + +#define GLOBAL_DATUM_INIT(X, Typepath, InitValue) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, InitValue) + +#define GLOBAL_VAR(X) GLOBAL_RAW(/##X); GLOBAL_UNMANAGED(X) + +#define GLOBAL_LIST(X) GLOBAL_RAW(/list/##X); GLOBAL_UNMANAGED(X) + +#define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_UNMANAGED(X) +>>>>>>> 1029b5a... Blank globals will no longer assign null to themselves (#31882) From d48cea337bd3ad316fb94e2a529ebaa2dac52183 Mon Sep 17 00:00:00 2001 From: Cruix Date: Sat, 21 Oct 2017 07:19:06 -0500 Subject: [PATCH 07/30] Fixed projectile runtimes (#31973) --- code/modules/projectiles/projectile.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 4ecfc3bde8..3f70f4f8ff 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -220,7 +220,7 @@ var/mob/M = safepick(mobs) if(M) return M.lowest_buckled_mob() - var/obj/O = safepick(typecache_filter_list(T, GLOB.typecache_machine_or_structure)) - A + var/obj/O = safepick(typecache_filter_list(T, GLOB.typecache_machine_or_structure) - A) if(O) return O From 007907940d822c6a3c0d46b4a9d7416e931d9bb7 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Sat, 21 Oct 2017 07:24:50 -0500 Subject: [PATCH 09/30] Update globals.dm --- code/__DATASTRUCTURES/globals.dm | 41 -------------------------------- 1 file changed, 41 deletions(-) diff --git a/code/__DATASTRUCTURES/globals.dm b/code/__DATASTRUCTURES/globals.dm index a9199a6f7b..808f8da757 100644 --- a/code/__DATASTRUCTURES/globals.dm +++ b/code/__DATASTRUCTURES/globals.dm @@ -1,43 +1,3 @@ -<<<<<<< HEAD -//See controllers/globals.dm -#define GLOBAL_MANAGED(X, InitValue)\ -/datum/controller/global_vars/proc/InitGlobal##X(){\ - ##X = ##InitValue;\ - gvars_datum_init_order += #X;\ -} -#define GLOBAL_UNMANAGED(X, InitValue) /datum/controller/global_vars/proc/InitGlobal##X() - -#ifndef TESTING -#define GLOBAL_PROTECT(X)\ -/datum/controller/global_vars/InitGlobal##X(){\ - ..();\ - gvars_datum_protected_varlist += #X;\ -} -#else -#define GLOBAL_PROTECT(X) -#endif - -#define GLOBAL_REAL_VAR(X) var/global/##X -#define GLOBAL_REAL(X, Typepath) var/global##Typepath/##X - -#define GLOBAL_RAW(X) /datum/controller/global_vars/var/global##X - -#define GLOBAL_VAR_INIT(X, InitValue) GLOBAL_RAW(/##X); GLOBAL_MANAGED(X, InitValue) - -#define GLOBAL_VAR_CONST(X, InitValue) GLOBAL_RAW(/const/##X) = InitValue; GLOBAL_UNMANAGED(X, InitValue) - -#define GLOBAL_LIST_INIT(X, InitValue) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, InitValue) - -#define GLOBAL_LIST_EMPTY(X) GLOBAL_LIST_INIT(X, list()) - -#define GLOBAL_DATUM_INIT(X, Typepath, InitValue) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, InitValue) - -#define GLOBAL_VAR(X) GLOBAL_RAW(/##X); GLOBAL_MANAGED(X, null) - -#define GLOBAL_LIST(X) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, null) - -#define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, null) -======= //See controllers/globals.dm #define GLOBAL_MANAGED(X, InitValue)\ /datum/controller/global_vars/proc/InitGlobal##X(){\ @@ -76,4 +36,3 @@ #define GLOBAL_LIST(X) GLOBAL_RAW(/list/##X); GLOBAL_UNMANAGED(X) #define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_UNMANAGED(X) ->>>>>>> 1029b5a... Blank globals will no longer assign null to themselves (#31882) From 1b7d441f7b70fbb313019fee4193c9fb63010432 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Sat, 21 Oct 2017 07:27:52 -0500 Subject: [PATCH 10/30] Update orbit.dm --- code/modules/orbit/orbit.dm | 115 ------------------------------------ 1 file changed, 115 deletions(-) diff --git a/code/modules/orbit/orbit.dm b/code/modules/orbit/orbit.dm index 600042a827..e4df15efaf 100644 --- a/code/modules/orbit/orbit.dm +++ b/code/modules/orbit/orbit.dm @@ -1,117 +1,3 @@ -<<<<<<< HEAD -/datum/orbit - var/atom/movable/orbiter - var/atom/orbiting - var/lock = TRUE - var/turf/lastloc - var/lastprocess - -/datum/orbit/New(_orbiter, _orbiting, _lock) - orbiter = _orbiter - orbiting = _orbiting - SSorbit.processing += src - if (!orbiting.orbiters) - orbiting.orbiters = list() - orbiting.orbiters += src - - if (orbiter.orbiting) - orbiter.stop_orbit() - orbiter.orbiting = src - Check() - lock = _lock - - - -//do not qdel directly, use stop_orbit on the orbiter. (This way the orbiter can bind to the orbit stopping) -/datum/orbit/Destroy(force = FALSE) - SSorbit.processing -= src - if (orbiter) - orbiter.orbiting = null - orbiter = null - if (orbiting) - if (orbiting.orbiters) - orbiting.orbiters -= src - if (!orbiting.orbiters.len)//we are the last orbit, delete the list - orbiting.orbiters = null - orbiting = null - return ..() - -/datum/orbit/proc/Check(turf/targetloc) - if (!orbiter) - qdel(src) - return - if (!orbiting) - orbiter.stop_orbit() - return - if (!orbiter.orbiting) //admin wants to stop the orbit. - orbiter.orbiting = src //set it back to us first - orbiter.stop_orbit() - lastprocess = world.time - if (!targetloc) - targetloc = get_turf(orbiting) - if (!targetloc || (!lock && orbiter.loc != lastloc && orbiter.loc != targetloc)) - orbiter.stop_orbit() - return - orbiter.loc = targetloc - orbiter.update_parallax_contents() - lastloc = orbiter.loc - - -/atom/movable/var/datum/orbit/orbiting = null -/atom/var/list/orbiters = null - -//A: atom to orbit -//radius: range to orbit at, radius of the circle formed by orbiting (in pixels) -//clockwise: whether you orbit clockwise or anti clockwise -//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete) -//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default. -//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts -//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts) - -/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE) - if (!istype(A)) - return - - new/datum/orbit(src, A, lockinorbit) - if (!orbiting) //something failed, and our orbit datum deleted itself - return - var/matrix/initial_transform = matrix(transform) - - //Head first! - if (pre_rotation) - var/matrix/M = matrix(transform) - var/pre_rot = 90 - if(!clockwise) - pre_rot = -90 - M.Turn(pre_rot) - transform = M - - var/matrix/shift = matrix(transform) - shift.Translate(0,radius) - transform = shift - - SpinAnimation(rotation_speed, -1, clockwise, rotation_segments) - - //we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit - transform = initial_transform - -/atom/movable/proc/stop_orbit() - SpinAnimation(0,0) - qdel(orbiting) - -/atom/Destroy(force = FALSE) - . = ..() - if (orbiters) - for (var/thing in orbiters) - var/datum/orbit/O = thing - if (O.orbiter) - O.orbiter.stop_orbit() - -/atom/movable/Destroy(force = FALSE) - . = ..() - if (orbiting) - stop_orbit() -======= /datum/orbit var/atom/movable/orbiter var/atom/orbiting @@ -226,4 +112,3 @@ . = ..() if (orbiting) stop_orbit() ->>>>>>> e474c91... Merge pull request #31904 from AnturK/infinite From 7d9162d6082e7154e92036df2166c18b34c02749 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 21 Oct 2017 14:27:00 -0400 Subject: [PATCH 11/30] Logs subsystem shutdowns (#31951) --- code/controllers/master.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 5607dde491..852437705b 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -86,8 +86,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new sortTim(subsystems, /proc/cmp_subsystem_init) reverseRange(subsystems) for(var/datum/controller/subsystem/ss in subsystems) - testing("Shutdown [ss.name] subsystem") + log_world("Shutting down [ss.name] subsystem...") ss.Shutdown() + log_world("Shutdown complete") // Returns 1 if we created a new mc, 0 if we couldn't due to a recent restart, // -1 if we encountered a runtime trying to recreate it @@ -595,4 +596,4 @@ GLOBAL_REAL(Master, /datum/controller/master) = new if (client_count < CONFIG_GET(number/mc_tick_rate/disable_high_pop_mc_mode_amount)) processing = CONFIG_GET(number/mc_tick_rate/base_mc_tick_rate) else if (client_count > CONFIG_GET(number/mc_tick_rate/high_pop_mc_mode_amount)) - processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate) \ No newline at end of file + processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate) From ea4fc92dae6038c8c2c1f4d8b9c50ddd29b83518 Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 19 Oct 2017 21:59:10 +0200 Subject: [PATCH 13/30] Fixes wizard roundend with liches around --- code/game/gamemodes/game_mode.dm | 7 +++++++ code/game/gamemodes/wizard/wizard.dm | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 694255702a..128a794bc6 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -182,6 +182,10 @@ /datum/game_mode/process() return 0 +//For things that do not die easily +/datum/game_mode/proc/are_special_antags_dead() + return TRUE + /datum/game_mode/proc/check_finished(force_ending) //to be called by SSticker if(!SSticker.setup_done) @@ -218,6 +222,9 @@ living_antag_player = Player return 0 + if(!are_special_antags_dead()) + return FALSE + if(!continuous[config_tag] || force_ending) return 1 diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 326889b872..304f80b470 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -42,7 +42,8 @@ man is a dangerous mutant with the ability to alter himself and the world around him by what he and his leaders believe to be magic. If this man attempts an attack on your station, \ his execution is highly encouraged, as is the preservation of his body for later study." -/datum/game_mode/wizard/check_finished() + +/datum/game_mode/wizard/are_special_antags_dead() for(var/datum/mind/wizard in wizards) if(isliving(wizard.current) && wizard.current.stat!=DEAD) return FALSE @@ -54,8 +55,8 @@ if(SSevents.wizardmode) //If summon events was active, turn it off SSevents.toggleWizardmode() SSevents.resetFrequency() - - return ..() + + return TRUE /datum/game_mode/wizard/declare_completion() if(finished) From 0a14bf3fd49c0f2daaaa0e6a6f3dcee82c8404fe Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Sat, 21 Oct 2017 19:52:03 -0400 Subject: [PATCH 15/30] Adds sanity check to Narsie pickcultist proc (#31937) * Adds sanity check to Narsie pickcultist proc * claned up src * cleaned --- code/modules/power/singularity/narsie.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index b566d65f49..81dcd573f5 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -142,7 +142,7 @@ for(var/mob/living/carbon/food in GLOB.living_mob_list) //we don't care about constructs or cult-Ians or whatever. cult-monkeys are fair game i guess var/turf/pos = get_turf(food) - if(pos.z != src.z) + if(!pos || (pos.z != z)) continue if(iscultist(food)) @@ -163,7 +163,7 @@ if(!ghost.client) continue var/turf/pos = get_turf(ghost) - if(pos.z != src.z) + if(!pos || (pos.z != z)) continue cultists += ghost if(cultists.len) From e48fb05f06d2a0a267e4f71b46308935057b476f Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Sat, 21 Oct 2017 16:51:29 -0700 Subject: [PATCH 17/30] Fixes quick_attack_loop stack overflow (#31958) Fixes quick_attack_loop stack overflow --- .../hostile/megafauna/blood_drunk_miner.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index 14b313d815..03f466ddfd 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -159,18 +159,18 @@ Difficulty: Medium Shoot(target) changeNext_move(CLICK_CD_RANGE) +//I'm still of the belief that this entire proc needs to be wiped from existence. +// do not take my touching of it to be endorsement of it. ~mso /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop() - if(next_move <= world.time) - stoplag(1) - .() //retry - return - sleep((next_move - world.time) * 1.5) + while(!QDELETED(target) && next_move <= world.time) //this is done this way because next_move can change to be sooner while we sleep. + stoplag(1) + sleep((next_move - world.time) * 1.5) //but don't ask me what the fuck this is about if(QDELETED(target)) return if(dashing || next_move > world.time || !Adjacent(target)) if(dashing && next_move <= world.time) next_move = world.time + 1 - .() //recurse + INVOKE_ASYNC(src, .proc/quick_attack_loop) //lets try that again. return AttackingTarget() From 1ee238218c505d184934bc5fe99cdbd2e723e671 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 21 Oct 2017 19:53:33 -0400 Subject: [PATCH 19/30] Merge pull request #31931 from vuonojenmustaturska/penfix It's a time to stop warning about paper bins eating pens --- code/modules/paperwork/paperbin.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 55a0875b62..962802aa6d 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -25,10 +25,6 @@ P.loc = src bin_pen = P update_icon() - var/static/warned = FALSE - if(P.type == /obj/item/pen && !warned) - warning("one or more paperbins ate a pen duing initialize()") - warned = TRUE /obj/item/paper_bin/fire_act(exposed_temperature, exposed_volume) if(!total_paper) From 17d2ff88c56f0d76beddc384b9aed0c1499bea55 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 21 Oct 2017 19:52:57 -0400 Subject: [PATCH 21/30] Merge pull request #31935 from ShizCalev/shade-qdel-fix Fixes shades being sent back to the arrival shuttle when their stone is qdel'd --- code/game/gamemodes/wizard/soulstone.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 149c2ae912..b38ac384fb 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -44,6 +44,11 @@ if(spent) to_chat(user, "This shard is spent; it is now just a creepy rock.") +/obj/item/device/soulstone/Destroy() //Stops the shade from being qdel'd immediately and their ghost being sent back to the arrival shuttle. + for(var/mob/living/simple_animal/shade/A in src) + A.death() + return ..() + //////////////////////////////Capturing//////////////////////////////////////////////////////// /obj/item/device/soulstone/attack(mob/living/carbon/human/M, mob/living/user) From ff1a3e9f0a437460d74e1f368db7961ca186ba8a Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 21 Oct 2017 19:55:50 -0400 Subject: [PATCH 23/30] Safeguards GetAllContents and makes it throw a warning --- code/__DEFINES/misc.dm | 4 +++- code/__HELPERS/unsorted.dm | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index b83fc3dd39..66c12adc72 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -468,4 +468,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE #define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation" #define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round - //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored \ No newline at end of file + //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored + +#define MAX_PROC_DEPTH 195 // 200 proc calls deep and shit breaks, this is a bit lower to give some safety room \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index cae42d62e8..ff0693a839 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -503,12 +503,31 @@ Turf and target are separate in case you want to teleport some distance from a t var/y=arcsin(x/sqrt(1+x*x)) return y +<<<<<<< HEAD /atom/proc/GetAllContents(list/output=list()) . = output output += src for(var/i in 1 to contents.len) var/atom/thing = contents[i] thing.GetAllContents(output) +======= +/* +Recursively gets all contents of contents and returns them all in a list. + +recursive_depth is useful if you only want a turf and everything on it (recursive_depth=1) +Do not set recursive depth higher than MAX_PROC_DEPTH as byond breaks when that limit is reached. +*/ +/atom/proc/GetAllContents(list/output=list(), recursive_depth=MAX_PROC_DEPTH, _current_depth=0) + . = output + output += src + if(_current_depth == recursive_depth) + if(_current_depth == MAX_PROC_DEPTH) + WARNING("Get all contents reached the max recursive depth of [MAX_PROC_DEPTH]. More and we would break shit. Offending atom: [src]") + return + for(var/i in 1 to contents.len) + var/atom/thing = contents[i] + thing.GetAllContents(output, recursive_depth, ++_current_depth) +>>>>>>> 179cd9d... Merge pull request #31927 from ninjanomnom/recursive-depth //Step-towards method of determining whether one atom can see another. Similar to viewers() /proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate. From 637273285dddb2493c4b7b53df7c4e1c0ba099b2 Mon Sep 17 00:00:00 2001 From: MoreRobustThanYou Date: Sat, 21 Oct 2017 21:15:21 -0400 Subject: [PATCH 24/30] Blood Brother now properly sets special role (#31964) * Blood Brother now properly sets special role * Update mob_helpers.dm * Update mob_helpers.dm * Update mob_helpers.dm --- code/datums/antagonists/brother.dm | 1 + code/modules/mob/mob_helpers.dm | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/code/datums/antagonists/brother.dm b/code/datums/antagonists/brother.dm index 77f611cf2c..6458e6da09 100644 --- a/code/datums/antagonists/brother.dm +++ b/code/datums/antagonists/brother.dm @@ -20,6 +20,7 @@ /datum/antagonist/brother/on_gain() SSticker.mode.brothers += owner owner.objectives += team.objectives + owner.special_role = special_role finalize_brother() return ..() diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index a605d5e479..af12b87eec 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -335,9 +335,9 @@ It's fairly easy to fix if dealing with single letters but not so much with comp /proc/is_special_character(mob/M) // returns 1 for special characters and 2 for heroes of gamemode //moved out of admins.dm because things other than admin procs were calling this. if(!SSticker.HasRoundStarted()) - return 0 + return FALSE if(!istype(M)) - return 0 + return FALSE if(issilicon(M)) if(iscyborg(M)) //For cyborgs, returns 1 if the cyborg has a law 0 and special_role. Returns 0 if the borg is merely slaved to an AI traitor. var/mob/living/silicon/robot/R = M @@ -346,13 +346,13 @@ It's fairly easy to fix if dealing with single letters but not so much with comp if(R.connected_ai) if(is_special_character(R.connected_ai) && R.connected_ai.laws && (R.connected_ai.laws.zeroth_borg == R.laws.zeroth || R.connected_ai.laws.zeroth == R.laws.zeroth)) return 0 //AI is the real traitor here, so the borg itself is not a traitor - return 1 //Slaved but also a traitor - return 1 //Unslaved, traitor + return TRUE//Slaved but also a traitor + return TRUE //Unslaved, traitor else if(isAI(M)) var/mob/living/silicon/ai/A = M if(A.laws && A.laws.zeroth && A.mind && A.mind.special_role) - return 1 - return 0 + return TRUE + return FALSE if(M.mind && M.mind.special_role)//If they have a mind and special role, they are some type of traitor or antagonist. switch(SSticker.mode.config_tag) if("revolution") @@ -379,8 +379,10 @@ It's fairly easy to fix if dealing with single letters but not so much with comp if("abductor") if(M.mind in SSticker.mode.abductors) return 2 - return 1 - return 0 + return TRUE + if(M.mind && LAZYLEN(M.mind.antag_datums)) //they have an antag datum! + return TRUE + return FALSE /mob/proc/reagent_check(datum/reagent/R) // utilized in the species code return 1 From 7eb2af06c3253f356e4701b10bd08bb94aabf930 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Sat, 21 Oct 2017 22:18:19 -0500 Subject: [PATCH 26/30] fixes compile --- code/__HELPERS/unsorted.dm | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index ff0693a839..75e912dee7 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -503,14 +503,6 @@ Turf and target are separate in case you want to teleport some distance from a t var/y=arcsin(x/sqrt(1+x*x)) return y -<<<<<<< HEAD -/atom/proc/GetAllContents(list/output=list()) - . = output - output += src - for(var/i in 1 to contents.len) - var/atom/thing = contents[i] - thing.GetAllContents(output) -======= /* Recursively gets all contents of contents and returns them all in a list. @@ -519,15 +511,14 @@ Do not set recursive depth higher than MAX_PROC_DEPTH as byond breaks when that */ /atom/proc/GetAllContents(list/output=list(), recursive_depth=MAX_PROC_DEPTH, _current_depth=0) . = output - output += src + output += src if(_current_depth == recursive_depth) if(_current_depth == MAX_PROC_DEPTH) WARNING("Get all contents reached the max recursive depth of [MAX_PROC_DEPTH]. More and we would break shit. Offending atom: [src]") return - for(var/i in 1 to contents.len) - var/atom/thing = contents[i] - thing.GetAllContents(output, recursive_depth, ++_current_depth) ->>>>>>> 179cd9d... Merge pull request #31927 from ninjanomnom/recursive-depth + for(var/i in 1 to contents.len) + var/atom/thing = contents[i] + thing.GetAllContents(output, recursive_depth, ++_current_depth) //Step-towards method of determining whether one atom can see another. Similar to viewers() /proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate. From 5cb53d91b870396f3d30a396fa8ad305313f82c6 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Sat, 21 Oct 2017 22:20:09 -0500 Subject: [PATCH 27/30] Update game_options.txt --- config/game_options.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config/game_options.txt b/config/game_options.txt index 841adf8dca..e835a4b1a6 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -85,11 +85,6 @@ PROBABILITY REVOLUTION 2 PROBABILITY CULT 2 PROBABILITY CHANGELING 2 PROBABILITY WIZARD 4 -<<<<<<< HEAD -PROBABILITY BLOB 2 -PROBABILITY RAGINMAGES 2 -======= ->>>>>>> be748e3... Disentangles blob from blob mode/removes blob mode (#31780) PROBABILITY MONKEY 0 PROBABILITY METEOR 0 PROBABILITY EXTENDED 0 From 1cc89b55e8f0b53d71f27fc1be5b21fd8d75d909 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 22 Oct 2017 11:18:37 -0500 Subject: [PATCH 28/30] Automatic changelog generation for PR #3529 [ci skip] --- html/changelogs/AutoChangeLog-pr-3529.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3529.yml diff --git a/html/changelogs/AutoChangeLog-pr-3529.yml b/html/changelogs/AutoChangeLog-pr-3529.yml new file mode 100644 index 0000000000..02a915824f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3529.yml @@ -0,0 +1,7 @@ +author: "Toriate" +delete-after: True +changes: + - balance: "OP foam stuff now cost slightly more to build from autolathes" + - balance: "OP foam stuff now turned into total memes instead of practical weapons, all burst firing foam guns have at least 60 spread. Stealth pistol also has 60 spread." + - balance: "Foam X9 and Mag Rifle now requires two hands to fire" + - bugfix: "Foam Force X9 and Mag Rifle now has its correct weight class of NOT FITTING IN FUCKING BACKPACKS" From f450abcaab91cac82365e8b421e7038e1fff1134 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 22 Oct 2017 11:26:02 -0500 Subject: [PATCH 29/30] Automatic changelog generation for PR #3546 [ci skip] --- html/changelogs/AutoChangeLog-pr-3546.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3546.yml diff --git a/html/changelogs/AutoChangeLog-pr-3546.yml b/html/changelogs/AutoChangeLog-pr-3546.yml new file mode 100644 index 0000000000..3ce8ca350c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3546.yml @@ -0,0 +1,4 @@ +author: "More Robust Than You" +delete-after: True +changes: + - bugfix: "Blood Brother now properly shows up in player panel" From d2719c03f76305fd2ac60590881cc245158e78f5 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 22 Oct 2017 15:39:37 -0500 Subject: [PATCH 30/30] Automatic changelog generation for PR #3492 [ci skip] --- html/changelogs/AutoChangeLog-pr-3492.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-3492.yml diff --git a/html/changelogs/AutoChangeLog-pr-3492.yml b/html/changelogs/AutoChangeLog-pr-3492.yml new file mode 100644 index 0000000000..bcae1670b8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3492.yml @@ -0,0 +1,9 @@ +author: "Kor" +delete-after: True +changes: + - rscadd: "Blob is now a side antagonist." + - rscadd: "Event and admin blobs will now be able to choose their spawn location." + - rscadd: "Blob can now win in any mode by gaining enough tiles to reach Critical Mass." + - rscadd: "Blobs that have Critical Mass have unlimited points, and a minute after achieving critical mass, they will spread to every tile on station, killing anyone still on board and ending the round." + - rscadd: "Using an analyzer on a blob will now reveal its progress towards Critical Mass." + - rscadd: "The blob event is now more common."
Blob
Progress: [GLOB.blobs_legit.len]/[mode.blobwincount]
[M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""]PMFLW
Progress: [M.blobs_legit.len]/[M.blobwincount]
[blob.name]([blob.key])Blob not found!PM