diff --git a/code/__defines/_layers.dm b/code/__defines/_layers.dm index b16dcbed19d..44011bcee2e 100644 --- a/code/__defines/_layers.dm +++ b/code/__defines/_layers.dm @@ -38,4 +38,9 @@ #define MECH_GEAR_LAYER 4.08 #define MECH_ABOVE_LAYER 4.09 +// Blob Layers +#define BLOB_SHIELD_LAYER 4.11 +#define BLOB_NODE_LAYER 4.12 +#define BLOB_CORE_LAYER 4.13 + #define CLICKCATCHER_PLANE -100 \ No newline at end of file diff --git a/code/__defines/color.dm b/code/__defines/color.dm index 2c4d1813a8d..2ddfaf18475 100644 --- a/code/__defines/color.dm +++ b/code/__defines/color.dm @@ -122,4 +122,10 @@ #define COLOR_DARKMODE_BACKGROUND "#202020" #define COLOR_DARKMODE_DARKBACKGROUND "#171717" -#define COLOR_DARKMODE_TEXT "#a4bad6" \ No newline at end of file +#define COLOR_DARKMODE_TEXT "#a4bad6" + +// Blob Colours +#define BLOB_COLOR_CORE "#c96e28" +#define BLOB_COLOR_SHIELD "#9ed659" +#define BLOB_COLOR_RAV "#d65f42" +#define BLOB_COLOR_PULS "#b5ff5b" diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index e28e5bd4b2c..f7f46ef75aa 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -404,7 +404,14 @@ close() return +/obj/machinery/door/firedoor/can_close() + if(locate(/obj/effect/blob) in get_turf(src)) + return FALSE + return ..() + /obj/machinery/door/firedoor/close() + if(!can_close()) + return cut_overlays() latetoggle() return ..() diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index bc9ab89d5ec..b3dece6366d 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -178,20 +178,17 @@ LINEN BINS /obj/item/bedsheet/attackby(obj/item/I, mob/user) if(I.isscrewdriver()) - user.visible_message(SPAN_NOTICE("\The [user] begins poking eyeholes in \the [src] with \the [I]."), - SPAN_NOTICE("You begin poking eyeholes in \the [src] with \the [I].")) + user.visible_message(SPAN_NOTICE("\The [user] begins poking eyeholes in \the [src] with \the [I]."), SPAN_NOTICE("You begin poking eyeholes in \the [src] with \the [I].")) if(do_after(user, 50/I.toolspeed)) to_chat(user, SPAN_NOTICE("You poke eyeholes in \the [src]!")) new /obj/item/bedsheet/costume(get_turf(src)) qdel(src) return else if(is_sharp(I)) - user.visible_message(SPAN_NOTICE("\The [user] begins cutting up [src] with [I]."), - SPAN_NOTICE("You begin cutting up [src] with [I].")) - if(do_after(user, 50/I.toolspeed)) - to_chat(user, SPAN_NOTICE("You cut [src] into pieces!")) - for(var/i in 1 to rand(2,5)) - new /obj/item/reagent_containers/glass/rag(get_turf(src)) + user.visible_message(SPAN_NOTICE("\The [user] begins cutting up \the [src] with \the [I]."), SPAN_NOTICE("You begin cutting up \the [src] with \the [I].")) + if(do_after(user, 50 / I.toolspeed)) + to_chat(user, SPAN_NOTICE("You cut \the [src] into pieces!")) + new /obj/item/stack/material/cloth(get_turf(src), rand(2, 5)) qdel(src) return ..() diff --git a/code/modules/blob/blob.dm b/code/modules/blob/blob.dm index f6ed5ddb8c9..0d192c8f0a4 100644 --- a/code/modules/blob/blob.dm +++ b/code/modules/blob/blob.dm @@ -1,127 +1,48 @@ -//I will need to recode parts of this but I am way too tired atm /obj/effect/blob - name = "blob" + name = "pulsating mass" + desc = "A pulsating mass of interwoven tendrils." icon = 'icons/mob/npc/blob.dmi' icon_state = "blob" light_range = 3 - light_color = "#b5ff5b" - desc = "Some blob creature thingy" - density = 1 - opacity = 0 - anchored = 1 + light_power = 4 + light_color = BLOB_COLOR_PULS + density = TRUE + anchored = TRUE mouse_opacity = 2 - layer = 4 + + layer = BLOB_SHIELD_LAYER var/maxHealth = 30 var/health - var/regen_rate = 4 - var/brute_resist = 4 - var/fire_resist = 1.75 - var/secondary_core_growth_chance = 10.0 //% chance to grow a secondary blob core instead of whatever was suposed to grown. Secondary cores are considerably weaker, but still nasty. + var/regen_rate = 5 + + // damage gets divided by these modifiers, based on damage type + var/brute_resist = 4.3 + var/fire_resist = 0.8 + var/laser_resist = 2 // Special resist for laser based weapons - Emitters or handheld energy weaponry. Damage is divided by this and THEN by fire_resist. + var/expandType = /obj/effect/blob - var/obj/effect/blob/core/parent_core = null - var/blob_may_process = 0 - var/hangry = 0 //if the blob will attack or not. - var/blob_cost = 1 //point cost of the blob tile + var/secondary_core_growth_chance = 5 //% chance to grow a secondary blob core instead of whatever was supposed to grow. Secondary cores are considerably weaker, but still nasty. + var/damage_min = 15 + var/damage_max = 25 + var/pruned = FALSE + var/product = /obj/item/blob_tendril + var/attack_time = 0 + var/attack_cooldown = 60 // time in deciseconds before next attack will occur -/obj/effect/blob/New(loc) - START_PROCESSING(SScalamity, src) + var/obj/effect/blob/parent_core // the core this blob piece belongs to + var/is_core = FALSE // determines how to pass core inheritance + +/obj/effect/blob/Initialize() + . = ..() health = maxHealth - var/matrix/M = matrix() - M.Turn(90 * pick(0,1,2,3)) - src.transform = M update_icon() - return ..(loc) - -/obj/effect/blob/Destroy() - // Sanity time. - if (parent_core) - parent_core.blob_count -= blob_cost - parent_core = null - - STOP_PROCESSING(SScalamity, src) - - return ..() - -/obj/effect/blob/process() - if(!parent_core) - src.take_damage(5) - src.regen_rate = -5 - playsound(loc, 'sound/effects/splat.ogg', 50, 1) - return - - // Make deleting the parent more responsive. - if(QDELING(parent_core)) - parent_core = null - return - - for(var/mob/living/L in src.loc) - if(L.stat == DEAD) - if(prob(10)) - if(istype(L, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = L - H.ChangeToHusk() - if(!(HUSK in H.mutations)) - if(health < maxHealth) - health += rand(10,30) - if(health > maxHealth) - health = maxHealth - else if(istype(L, /mob/living/silicon)) - continue - else - L.gib() - if(health < maxHealth) - health += rand(10,30) - if(health > maxHealth) - health = maxHealth - continue - L.visible_message("The blob absorbs \the [L]!", "The blob absorbs you!") - playsound(loc, 'sound/effects/attackblob.ogg', 50, 1) - L.take_organ_damage(rand(5, 10)) - if(health < maxHealth) - health += rand(1,10) - if(health > maxHealth) - health = maxHealth - hangry += 8 - - for(var/mob/living/L in range(src,"3x3")) - var/obj/effect/blob/B = locate() in get_turf(L) - if(!B) - if(!hangry) - if(L.stat == DEAD) - continue - if(prob(40)) - L.visible_message("The blob sucks \the [L] into itself!", "The blob sucks you in!") - playsound(loc, 'sound/effects/attackblob.ogg', 50, 1) - L.take_organ_damage(rand(5, 10)) - L.forceMove(src.loc) - else - L.visible_message("The blob glomps \the [L]!", "The blob glomps you!") - playsound(loc, 'sound/effects/attackblob.ogg', 50, 1) - L.take_organ_damage(rand(5, 20)) - if(health < maxHealth) - health += rand(1,10) - if(health > maxHealth) - health = maxHealth - hangry += 2 - - for(var/obj/fire/F in range(src,"3x3")) //very snowflake, but much better than actually coding complex thermodynamics for these fuckers - if(prob(50)) - src.visible_message("The blob melts away under the heat of the flames!") - F = locate() in get_turf(src) - if(F) - src.take_damage(rand(5, 20) / fire_resist) - else - src.take_damage(rand(1, 10) / fire_resist) - - hangry -= 1 - if(hangry < 0) - hangry = 0 + START_PROCESSING(SSprocessing, src) /obj/effect/blob/CanPass(var/atom/movable/mover, var/turf/target, var/height = 0, var/air_group = 0) if(air_group || height == 0) - return 1 - return 0 + return TRUE + return FALSE /obj/effect/blob/ex_act(var/severity) switch(severity) @@ -138,10 +59,19 @@ else icon_state = "blob_damaged" +/obj/effect/blob/process() + if(!parent_core || QDELETED(parent_core)) + take_damage(maxHealth / 4) // four processes to die if main core is deddo + return + regen() + if(world.time < (attack_time + attack_cooldown)) + return + attempt_attack() + /obj/effect/blob/proc/take_damage(var/damage) health -= damage if(health < 0) - playsound(loc, 'sound/effects/splat.ogg', 50, 1) + playsound(get_turf(src), 'sound/effects/splat.ogg', 50, TRUE) qdel(src) else update_icon() @@ -151,77 +81,112 @@ update_icon() /obj/effect/blob/proc/expand(var/turf/T) - //Dont epxand over unsimulated unless its astroid trufs - if(istype(T, /turf/unsimulated/) && !istype(T, /turf/unsimulated/floor/asteroid/)) + if(istype(T, /turf/space) || (isopenturf(T)) || (istype(T, /turf/simulated/mineral) && T.density)) return - - //Dont expand over space or holes, unless there“s a lattice - if((istype(T, /turf/simulated/open) || istype(T, /turf/space)) && !(locate(/obj/structure/lattice) in T)) - return - - //If its rock, mine it - if(istype(T,/turf/simulated/mineral)) - var/turf/simulated/mineral/M = T - M.kinetic_hit(8,get_dir(src,M)) //8 so its destroyed in 2 or 3 hits (mineral health is randomized between 10 and 20) - return - - //If its a wall, destroy it if(istype(T, /turf/simulated/wall)) var/turf/simulated/wall/SW = T - SW.ex_act(2) + if(SW.reinf_material && SW.reinf_material.hardness > 60) + return TRUE + SW.take_damage(80) return - - for(var/obj/O in T) - if(O.density) - O.ex_act(2) + var/obj/structure/girder/G = locate() in T + if(G) + G.take_damage(rand(40, 80)) + return + var/obj/structure/window/W = locate() in T + if(W) + W.shatter() + return + var/obj/structure/grille/GR = locate() in T + if(GR) + qdel(GR) + return + for(var/obj/machinery/door/D in T) // There can be several - and some of them can be open, locate() is not suitable + if(D.density) + attack_door(D) + if(D.health <= 0) + if(!D.open(TRUE)) + D.visible_message(SPAN_WARNING("\The [src] bashes through \the [D], demolishing it!")) + qdel(D) return + var/obj/structure/foamedmetal/F = locate() in T + if(F) + F.visible_message(SPAN_WARNING("\The [src] lashes into \the [F], tearing it apart!")) + qdel(F) + return + var/obj/structure/reagent_dispensers/RT = locate() in T + if(RT) + RT.visible_message(SPAN_WARNING("\The [src] pierces into \the [RT], blowing it apart!")) + RT.ex_act(2) + return + var/obj/structure/inflatable/I = locate() in T + if(I) + I.visible_message(SPAN_WARNING("\The [src] rips into \the [F], tearing a hole into it!")) + I.deflate(TRUE) + return + var/obj/vehicle/V = locate() in T + if(V) + V.ex_act(2) + return + var/obj/machinery/camera/CA = locate() in T + if(CA && !(CA.stat & BROKEN)) + CA.take_damage(30) + return // Above things, we destroy completely and thus can use locate. Mobs are different. for(var/mob/living/L in T) if(L.stat == DEAD) continue - if(prob(30)) - L.visible_message("The blob sucks \the [L] into itself!", "The blob sucks you in!") - playsound(loc, 'sound/effects/attackblob.ogg', 50, 1) - L.take_organ_damage(rand(5, 10)) - L.forceMove(src.loc) - else - L.visible_message("The blob pulverizes \the [L]!", "The blob pulverizes you!") - playsound(loc, 'sound/effects/attackblob.ogg', 50, 1) - L.take_organ_damage(rand(30, 40)) - if(health < maxHealth) - health += rand(1,10) - if(health > maxHealth) - health = maxHealth - return + attack_living(L) - //If its a astroid turf, ignore it with a 50% chance (so the expansion mostly focuses on the station) - if(istype(T,/turf/unsimulated/floor/asteroid/) && prob(50)) - return + var/inherited_core = parent_core + if(is_core) + inherited_core = src - if(parent_core) - if(parent_core.blob_count < parent_core.blob_limit) - if(!(locate(/obj/effect/blob/core/) in range(T, 2)) && prob(secondary_core_growth_chance) && (parent_core.core_count < parent_core.core_limit)) - var/obj/effect/blob/core/secondary/S = new /obj/effect/blob/core/secondary(T) - S.parent_core = src.parent_core - src.parent_core.core_count += blob_cost - else - var/obj/effect/blob/C = new expandType(T) - C.parent_core = src.parent_core - parent_core.blob_count += blob_cost + if(!(locate(/obj/effect/blob/core) in range(2, T)) && prob(secondary_core_growth_chance)) + var/obj/effect/blob/core/secondary/S = new /obj/effect/blob/core/secondary(T) + S.parent_core = inherited_core + else + var/obj/effect/blob/B = new expandType(T, min(health, 30)) + B.parent_core = inherited_core -/obj/effect/blob/proc/pulse(var/forceLeft, var/list/dirs) - regen() +/obj/effect/blob/proc/pulse(var/forceLeft, var/list/dirs, var/bad_dir) sleep(4) - var/pushDir = pick(dirs) + var/pushDir = pick(dirs - bad_dir) var/turf/T = get_step(src, pushDir) - var/obj/effect/blob/B = (locate() in T) + var/obj/effect/blob/B = locate() in T if(!B) - if(prob(health+45)) - expand(T) + if(prob(health)) + var/retry = expand(T) + if(retry) + pulse(forceLeft - 1, dirs, pushDir) + else if(forceLeft) + B.pulse(forceLeft - 1, dirs - get_dir(B, src)) + +/obj/effect/blob/proc/attack_msg(atom/source) + source.visible_message(SPAN_WARNING("A tendril flies out from \the [src] and smashes into \the [source]!"), SPAN_DANGER("A tendril flies out from \the [src] and smashes into you!")) + playsound(get_turf(src), 'sound/effects/attackblob.ogg', 50, TRUE) + +/obj/effect/blob/proc/attack_door(var/obj/machinery/door/D) + if(!D) return - if(forceLeft) - B.pulse(forceLeft - 1, dirs) + attack_msg(D) + D.take_damage(rand(damage_min, damage_max)) + +/obj/effect/blob/proc/attack_living(var/mob/living/L) + if(!L) + return + var/blob_damage = pick(BRUTE, BURN) + attack_msg(L) + L.apply_damage(rand(damage_min, damage_max), blob_damage, used_weapon = "blob tendril") + +/obj/effect/blob/proc/attempt_attack() + var/mob/living/victim = locate() in view(1, src) + if(victim) + if(victim.stat == DEAD) + return + attack_living(victim) + attack_time = world.time /obj/effect/blob/bullet_act(var/obj/item/projectile/Proj) if(!Proj) @@ -231,56 +196,83 @@ if(BRUTE) take_damage(Proj.damage / brute_resist) if(BURN) - take_damage(Proj.damage / fire_resist) - return 0 + take_damage((Proj.damage / laser_resist) / fire_resist) + return FALSE -/obj/effect/blob/attackby(var/obj/item/W, var/mob/user) +/obj/effect/blob/attackby(obj/item/W, mob/user) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.do_attack_animation(src) - playsound(loc, 'sound/effects/attackblob.ogg', 50, 1) - visible_message("\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]") + playsound(get_turf(src), 'sound/effects/attackblob.ogg', 50, TRUE) + if(W.iswirecutter()) + if(!pruned) + to_chat(user, SPAN_NOTICE("You collect a sample from \the [src].")) + var/obj/P = new product(get_turf(user)) + user.put_in_hands(P) + pruned = TRUE + return + else + to_chat(user, SPAN_WARNING("\The [src] has already been pruned.")) + return + var/damage = 0 switch(W.damtype) - if("fire") + if(BURN) damage = (W.force / fire_resist) if(W.iswelder()) - playsound(loc, 'sound/items/welder.ogg', 100, 1) - if("brute") - if(prob(30) && !issilicon(user)) - visible_message("\The [W] gets caught in the gelatinous folds of \the [src]") - user.drop_from_inventory(W,get_turf(src)) - return + playsound(get_turf(src), 'sound/items/Welder.ogg', 100, TRUE) + if(BRUTE) damage = (W.force / brute_resist) take_damage(damage) - return + +/obj/effect/blob/fire_act() + take_damage(rand(5, 20) / fire_resist) + +#define CORE_SHIELD_HIGH "high" +#define CORE_SHIELD_LOW "low" /obj/effect/blob/core - name = "blob core" + name = "master nucleus" + desc = "A massive, fragile nucleus guarded by a shield of thick tendrils." icon_state = "blob_core" - light_range = 1 - light_power = 2 - light_color = "#F3D203" - maxHealth = 200 - brute_resist = 2 - regen_rate = 2 - fire_resist = 2 - var/core_count //amount of secondary cores - var/core_limit = 4 //for if a badmin ever wants the station to die, they can set this higher - var/blob_count = 1 //amount of actual blob pieces - var/blob_limit = 150 //9x4+100 + a bit, maximum amount of blobs allowed. - + maxHealth = 450 + damage_min = 25 + damage_max = 35 expandType = /obj/effect/blob/shield + product = /obj/item/blob_core + is_core = TRUE + light_color = BLOB_COLOR_CORE + layer = BLOB_CORE_LAYER -/obj/effect/blob/core/New() - if(!parent_core) - parent_core = src - ..() + var/blob_may_process = TRUE + var/reported_low_damage = FALSE + var/pulse_power = 50 // How far the core can potentially grow in size + var/times_to_pulse = 4 +/obj/effect/blob/core/proc/get_health_percent() + return ((health / maxHealth) * 100) + +/obj/effect/blob/core/proc/process_core_health() + var/health_percent = get_health_percent() + if(health_percent > 75) + if(reported_low_damage) + report_shield_status(CORE_SHIELD_HIGH) + else if(health_percent < 33) + if(!reported_low_damage) + report_shield_status(CORE_SHIELD_LOW) + +/obj/effect/blob/core/proc/report_shield_status(var/status) + if(status == CORE_SHIELD_LOW) + visible_message(SPAN_DANGER("\The [src]'s internal tendril shield fails, leaving the nucleus vulnerable!"), 3) + reported_low_damage = TRUE + if(status == CORE_SHIELD_HIGH) + visible_message(SPAN_DANGER("\The [src]'s internal tendril shield seems to have fully reformed."), 3) + reported_low_damage = FALSE + +// Rough icon state changes that reflect the core's health /obj/effect/blob/core/update_icon() - var/health_percent = (health / maxHealth) * 100 - switch(health_percent) + switch(get_health_percent()) if(66 to INFINITY) icon_state = "blob_core" if(33 to 66) @@ -290,49 +282,63 @@ /obj/effect/blob/core/process() set waitfor = 0 - ..() - if(world.time < blob_may_process) + if(!blob_may_process) return - blob_may_process = world.time + 8 SECONDS - sleep(0) - pulse(20, list(NORTH, EAST)) - pulse(20, list(NORTH, WEST)) - pulse(20, list(SOUTH, EAST)) - pulse(20, list(SOUTH, WEST)) + blob_may_process = FALSE + process_core_health() + regen() + for(var/i = 1 to times_to_pulse) + pulse(pulse_power, global.cardinal.Copy()) + blob_may_process = TRUE + if(world.time < (attack_time + attack_cooldown)) + return + attempt_attack() +// Blob has a very small probability of growing these when spreading. These will spread the blob further. /obj/effect/blob/core/secondary - name = "small blob core" - icon_state = "blob_core" - maxHealth = 100 - brute_resist = 1 - fire_resist = 1.75 + name = "auxiliary nucleus" + desc = "An interwoven mass of tendrils. A glowing nucleus pulses at its center." + icon_state = "blob_node" + maxHealth = 125 regen_rate = 1 - expandType = /obj/effect/blob + damage_min = 15 + damage_max = 20 + layer = BLOB_NODE_LAYER + product = /obj/item/blob_core/aux + pulse_power = 20 // Not as strong as big daddy core + times_to_pulse = 4 -/obj/effect/blob/core/secondary/New() - health = maxHealth - update_icon() - return ..(loc) +/obj/effect/blob/core/secondary/process() + if(!parent_core || QDELETED(parent_core)) + take_damage(maxHealth / 4) // four processes to die if main core is deddo + return + ..() -/obj/effect/blob/core/secondary/Destroy() - if(parent_core) - parent_core.core_count -= 1 - return ..() +/obj/effect/blob/core/secondary/process_core_health() + return + +/obj/effect/blob/core/secondary/update_icon() + icon_state = (health / maxHealth >= 0.5) ? "blob_node" : "blob_factory" /obj/effect/blob/shield - name = "strong blob" + name = "shielding mass" + desc = "A pulsating mass of interwoven tendrils. These seem particularly robust, but not quite as active." icon_state = "blob_idle" - maxHealth = 60 - brute_resist = 1 - fire_resist = 2.5 - blob_cost = 0 //so that the core can regrow its shields when they break + maxHealth = 120 + damage_min = 15 + damage_max = 25 + attack_cooldown = 45 + regen_rate = 4 + opacity = TRUE + expandType = /obj/effect/blob/ravaging + light_color = BLOB_COLOR_SHIELD -/obj/effect/blob/shield/New() +/obj/effect/blob/shield/Initialize() + . = ..() update_nearby_tiles() - ..() /obj/effect/blob/shield/Destroy() - density = 0 + density = FALSE update_nearby_tiles() return ..() @@ -346,3 +352,72 @@ /obj/effect/blob/shield/CanPass(var/atom/movable/mover, var/turf/target, var/height = 0, var/air_group = 0) return !density + +/obj/effect/blob/ravaging + name = "ravaging mass" + desc = "A mass of interwoven tendrils. They thrash around haphazardly at anything in reach." + maxHealth = 20 + damage_min = 20 + damage_max = 25 + attack_cooldown = 30 + light_color = BLOB_COLOR_RAV + color = "#ffd400" //Temporary, for until they get a new sprite. + +#define TENDRIL_SOLID "solid" +#define TENDRIL_FIRE "fire" + +//produce +/obj/item/blob_tendril + name = "asteroclast tendril" + desc = "A tendril removed from an asteroclast. It's entirely lifeless." + icon = 'icons/mob/npc/blob.dmi' + icon_state = "tendril" + item_state = "blob_tendril" + w_class = ITEMSIZE_LARGE + reach = 2 // long range tentacle whips - geeves + attack_verb = list("smacked", "smashed", "whipped") + var/types_of_tendril = list(TENDRIL_SOLID, TENDRIL_FIRE) + +/obj/item/blob_tendril/Initialize() + . = ..() + var/tendril_type = pick(types_of_tendril) + switch(tendril_type) + if(TENDRIL_SOLID) + desc = "An incredibly dense, yet flexible, tendril, removed from an asteroclast." + force = 10 + color = COLOR_BRONZE + origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2) + if(TENDRIL_FIRE) + desc = "A tendril removed from an asteroclast. It's hot to the touch." + damtype = BURN + force = 15 + color = COLOR_AMBER + origin_tech = list(TECH_POWER = 2, TECH_BIO = 2) + +/obj/item/blob_tendril/afterattack(obj/O, mob/user) + if(prob(50)) + force-- + if(force <= 0) + visible_message(SPAN_NOTICE("\The [src] crumbles apart!")) + user.drop_from_inventory(src) + new /obj/effect/decal/cleanable/ash(get_turf(src)) + qdel(src) + +/obj/item/blob_core + name = "asteroclast nucleus sample" + desc = "A sample taken from an asteroclast's nucleus. It pulses with energy." + icon_state = "core_sample" + item_state = "blob_core" + w_class = ITEMSIZE_NORMAL + origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 5, TECH_BIO = 7) + +/obj/item/blob_core/aux + name = "asteroclast auxiliary nucleus sample" + desc = "A sample taken from an asteroclast's auxiliary nucleus." + icon_state = "core_sample_2" + origin_tech = list(TECH_MATERIAL = 2, TECH_BLUESPACE = 3, TECH_BIO = 4) + +#undef CORE_SHIELD_HIGH +#undef CORE_SHIELD_LOW +#undef TENDRIL_SOLID +#undef TENDRIL_FIRE \ No newline at end of file diff --git a/code/modules/reagents/dispenser/dispenser_presets.dm b/code/modules/reagents/dispenser/dispenser_presets.dm index 34066f04bcb..008380da7e1 100644 --- a/code/modules/reagents/dispenser/dispenser_presets.dm +++ b/code/modules/reagents/dispenser/dispenser_presets.dm @@ -72,6 +72,7 @@ ui_title = "Soda Dispenser" accept_drinking = 1 density = 0//It's a half-height machine that sits on a table, this allows small things to walk under that table + pass_flags = PASSTABLE // put it back on the table /obj/machinery/chemical_dispenser/bar_soft/full spawn_cartridges = list( @@ -108,6 +109,7 @@ ui_title = "Booze Dispenser" accept_drinking = 1 density = 0//It's a half-height machine that sits on a table, this allows small things to walk under that table + pass_flags = PASSTABLE // put it back on the table /obj/machinery/chemical_dispenser/bar_alc/full spawn_cartridges = list( @@ -140,6 +142,7 @@ ui_title = "Coffee Master 3000" accept_drinking = 1 density = 0 + pass_flags = PASSTABLE // put it back on the table /obj/machinery/chemical_dispenser/coffeemaster/full spawn_cartridges = list( @@ -164,6 +167,7 @@ ui_title = "Morning Glory Coffee Mate" icon_state_active = null accept_drinking = 1 + pass_flags = PASSTABLE // put it back on the table /obj/machinery/chemical_dispenser/coffee/full spawn_cartridges = list( diff --git a/html/changelog.html b/html/changelog.html index 87dfb8eda9f..c94f4966c66 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -35,6 +35,19 @@ -->
+

10 February 2021

+

Geeves updated:

+ +

09 February 2021

Geeves updated: