Lets blobs mine (#64965)

Allows blobs to destroy mineral turfs when necessary, such as when spawning on Ice Box.

Without this they face a distinct disadvantage against crew that can destroy mineral turfs with plasma cutters like a hot knife through butter to get a better angle on their core.

The fact they can't already seems like an oversight left over from when they would never normally encounter them due to spawning on space stations.

The bubble alerts provide a lot of feedback that was previously missing and saves taking your eyes off the game to look at warning messages in the chat.

The screen tips save you having to read the help screed to at least know what two of the shortcuts are.

Making off-station blobs lighter makes it immediately obvious which blobs count towards victory.
This commit is contained in:
cacogen
2022-02-22 22:40:32 +13:00
committed by GitHub
parent 905fb2685c
commit e07913d751
14 changed files with 102 additions and 31 deletions
+3
View File
@@ -7,6 +7,9 @@
/// Context applied to Ctrl-LMB actions
#define SCREENTIP_CONTEXT_CTRL_LMB "Ctrl-LMB"
/// Context applied to Alt-LMB actions
#define SCREENTIP_CONTEXT_ALT_LMB "Alt-LMB"
/// Screentips are always disabled
#define SCREENTIP_PREFERENCE_DISABLED "Disabled"
@@ -57,17 +57,22 @@
datum/source,
list/context,
obj/item/held_item,
mob/living/user,
mob/user,
)
SIGNAL_HANDLER
if(!isliving(user))
return .
if (!isnull(held_item))
return NONE
var/mob/living/living_user = user
if (!isnull(lmb_text))
context[SCREENTIP_CONTEXT_LMB] = user.combat_mode ? lmb_text_combat_mode : lmb_text
context[SCREENTIP_CONTEXT_LMB] = living_user.combat_mode ? lmb_text_combat_mode : lmb_text
if (!isnull(rmb_text))
context[SCREENTIP_CONTEXT_RMB] = user.combat_mode ? rmb_text_combat_mode : rmb_text
context[SCREENTIP_CONTEXT_RMB] = living_user.combat_mode ? rmb_text_combat_mode : rmb_text
return CONTEXTUAL_SCREENTIP_SET
+1 -1
View File
@@ -18,7 +18,7 @@
atom/source,
list/context,
obj/item/held_item,
mob/living/user,
mob/user,
)
SIGNAL_HANDLER
+15 -9
View File
@@ -2111,9 +2111,11 @@
if(screentips_enabled == SCREENTIP_PREFERENCE_DISABLED || (flags_1 & NO_SCREENTIPS_1))
active_hud.screentip_text.maptext = ""
else
var/lmb_rmb_line = ""
var/ctrl_lmb_alt_lmb_line = ""
var/extra_context = ""
if (isliving(user))
if (isliving(user) || isovermind(user))
var/obj/item/held_item = user.get_active_held_item()
if ((flags_1 & HAS_CONTEXTUAL_SCREENTIPS_1) || (held_item?.item_flags & ITEM_HAS_CONTEXTUAL_SCREENTIPS))
@@ -2129,19 +2131,23 @@
var/rmb_text = (SCREENTIP_CONTEXT_RMB in context) ? "[SCREENTIP_CONTEXT_RMB]: [context[SCREENTIP_CONTEXT_RMB]]" : ""
if (lmb_text)
extra_context = lmb_text
lmb_rmb_line = lmb_text
if (rmb_text)
extra_context += " | [rmb_text]"
lmb_rmb_line += " | [rmb_text]"
else if (rmb_text)
extra_context = rmb_text
lmb_rmb_line = rmb_text
// Ctrl-LMB and (in the future) Alt-LMB on another
// Ctrl-LMB, Alt-LMB on one line...
if (lmb_rmb_line != "")
lmb_rmb_line += "<br>"
if (SCREENTIP_CONTEXT_CTRL_LMB in context)
if (extra_context != "")
extra_context += "<br>"
extra_context += "[SCREENTIP_CONTEXT_CTRL_LMB]: [context[SCREENTIP_CONTEXT_CTRL_LMB]]"
ctrl_lmb_alt_lmb_line += "[SCREENTIP_CONTEXT_CTRL_LMB]: [context[SCREENTIP_CONTEXT_CTRL_LMB]]"
if (SCREENTIP_CONTEXT_ALT_LMB in context)
if (ctrl_lmb_alt_lmb_line != "")
ctrl_lmb_alt_lmb_line += " | "
ctrl_lmb_alt_lmb_line += "[SCREENTIP_CONTEXT_ALT_LMB]: [context[SCREENTIP_CONTEXT_ALT_LMB]]"
extra_context = "<br><span style='font-size: 7px'>[extra_context]</span>"
extra_context = "<br><span style='font-size: 7px'>[lmb_rmb_line][ctrl_lmb_alt_lmb_line]</span>"
if (screentips_enabled == SCREENTIP_PREFERENCE_CONTEXT_ONLY && extra_context == "")
active_hud.screentip_text.maptext = ""
+4 -1
View File
@@ -627,9 +627,12 @@
. += span_notice("Alt-click [src] to [ secondsElectrified ? "un-electrify" : "permanently electrify"] it.")
. += span_notice("Ctrl-Shift-click [src] to [ emergency ? "disable" : "enable"] emergency access.")
/obj/machinery/door/airlock/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
/obj/machinery/door/airlock/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
if(!isliving(user))
return .
switch (held_item?.tool_behaviour)
if (TOOL_CROWBAR)
if (panel_open)
+4 -1
View File
@@ -52,9 +52,12 @@
. += span_notice("In the event of a red alert, its access requirements will automatically lift.")
. += span_notice("Its maintenance panel is [panel_open ? "open" : "<b>screwed</b> in place"].")
/obj/machinery/door/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
/obj/machinery/door/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
if(!isliving(user))
return .
if (isnull(held_item))
context[SCREENTIP_CONTEXT_LMB] = "Open"
return CONTEXTUAL_SCREENTIP_SET
+7 -2
View File
@@ -107,13 +107,18 @@
else
. += span_notice("The bolt locks have been <i>unscrewed</i>, but the bolts themselves are still <b>wrenched</b> to the floor.")
/obj/machinery/door/firedoor/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
/obj/machinery/door/firedoor/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
if(!isliving(user))
return .
var/mob/living/living_user = user
if (isnull(held_item))
if (density)
// This should be LMB/RMB one day
if (user.combat_mode)
if (living_user.combat_mode)
context[SCREENTIP_CONTEXT_LMB] = "Knock"
else
context[SCREENTIP_CONTEXT_LMB] = "Bash"
+6 -2
View File
@@ -176,6 +176,10 @@
gets_drilled(null, FALSE)
return
/turf/closed/mineral/blob_act(obj/structure/blob/B)
if(prob(50))
gets_drilled(give_exp = FALSE)
/turf/closed/mineral/random
var/list/mineralSpawnChanceList = list(/obj/item/stack/ore/uranium = 5, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 10,
/obj/item/stack/ore/silver = 12, /obj/item/stack/ore/plasma = 20, /obj/item/stack/ore/iron = 40, /obj/item/stack/ore/titanium = 11,
@@ -592,7 +596,7 @@
det_time = 0
visible_message(span_notice("The chain reaction stopped! The gibtonite had [det_time] reactions left till the explosion!"))
/turf/closed/mineral/gibtonite/gets_drilled(mob/user, triggered_by_explosion = FALSE)
/turf/closed/mineral/gibtonite/gets_drilled(mob/user, give_exp = FALSE, triggered_by_explosion = FALSE)
if(stage == GIBTONITE_UNSTRUCK && mineralAmt >= 1) //Gibtonite deposit is activated
playsound(src,'sound/effects/hit_on_shattered_glass.ogg',50,TRUE)
explosive_reaction(user, triggered_by_explosion)
@@ -664,7 +668,7 @@
to_chat(usr, span_warning("The rock seems to be too strong to destroy. Maybe I can break it once I become a master miner."))
/turf/closed/mineral/strong/gets_drilled(mob/user)
/turf/closed/mineral/strong/gets_drilled(mob/user, give_exp = FALSE)
if(!ishuman(user))
return // see attackby
var/mob/living/carbon/human/H = user
+11 -2
View File
@@ -3,6 +3,7 @@
/mob/camera/blob/proc/can_buy(cost = 15)
if(blob_points < cost)
to_chat(src, span_warning("You cannot afford this, you need at least [cost] resources!"))
balloon_alert(src, "need [cost-blob_points] more resource\s!")
return FALSE
add_points(-cost)
return TRUE
@@ -85,22 +86,27 @@
var/obj/structure/blob/B = (locate(/obj/structure/blob) in T)
if(!B)
to_chat(src, span_warning("There is no blob here!"))
balloon_alert(src, "no blob here!")
return
if(!istype(B, /obj/structure/blob/normal))
to_chat(src, span_warning("Unable to use this blob, find a normal one."))
balloon_alert(src, "need normal blob!")
return
if(needsNode)
var/area/A = get_area(src)
if(!(A.area_flags & BLOBS_ALLOWED)) //factory and resource blobs must be legit
to_chat(src, span_warning("This type of blob must be placed on the station!"))
balloon_alert(src, "can't place off-station!")
return
if(nodes_required && !(locate(/obj/structure/blob/special/node) in orange(BLOB_NODE_PULSE_RANGE, T)) && !(locate(/obj/structure/blob/special/core) in orange(BLOB_CORE_PULSE_RANGE, T)))
to_chat(src, span_warning("You need to place this blob closer to a node or core!"))
balloon_alert(src, "too far from node or core!")
return //handholdotron 2000
if(minSeparation)
for(var/obj/structure/blob/L in orange(minSeparation, T))
if(L.type == blobstrain)
to_chat(src, span_warning("There is a similar blob nearby, move more than [minSeparation] tiles away from it!"))
L.balloon_alert(src, "too close!")
return
if(!can_buy(price))
return
@@ -124,9 +130,11 @@
to_chat(src, span_warning("This shield blob is too damaged to be modified properly!"))
return
to_chat(src, span_warning("You secrete a reflective ooze over the shield blob, allowing it to reflect projectiles at the cost of reduced integrity."))
S.change_to(/obj/structure/blob/shield/reflective, src)
S = S.change_to(/obj/structure/blob/shield/reflective, src)
S.balloon_alert(src, "upgraded to [S.name]!")
else
createSpecial(BLOB_UPGRADE_STRONG_COST, /obj/structure/blob/shield, 0, FALSE, T)
S = createSpecial(BLOB_UPGRADE_STRONG_COST, /obj/structure/blob/shield, 0, FALSE, T)
S?.balloon_alert(src, "upgraded to [S.name]!")
/mob/camera/blob/proc/create_blobbernaut()
var/turf/T = get_turf(src)
@@ -209,6 +217,7 @@
if(B.point_return)
add_points(B.point_return)
to_chat(src, span_notice("Gained [B.point_return] resources from removing \the [B]."))
B.balloon_alert(src, "+[B.point_return] resource\s")
qdel(B)
/mob/camera/blob/proc/expand_blob(turf/T)
@@ -34,12 +34,10 @@
/obj/structure/blob/Initialize(mapload, owner_overmind)
. = ..()
register_context()
if(owner_overmind)
overmind = owner_overmind
overmind.all_blobs += src
var/area/Ablob = get_area(src)
if(Ablob.area_flags & BLOBS_ALLOWED) //Is this area allowed for winning as blob?
overmind.blobs_legit += src
GLOB.blobs += src //Keep track of the blob in the normal list either way
setDir(pick(GLOB.cardinals))
update_appearance()
@@ -49,6 +47,22 @@
if(!QDELETED(src)) //Consuming our tile can in rare cases cause us to del
AddElement(/datum/element/swabable, CELL_LINE_TABLE_BLOB, CELL_VIRUS_TABLE_GENERIC, 2, 2)
/obj/structure/blob/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
if (!isovermind(user))
return .
if(istype(src, /obj/structure/blob/normal))
context[SCREENTIP_CONTEXT_CTRL_LMB] = "Create strong blob"
if(istype(src, /obj/structure/blob/shield) && !istype(src, /obj/structure/blob/shield/reflective))
context[SCREENTIP_CONTEXT_CTRL_LMB] = "Create reflective blob"
if(point_return >= 0)
context[SCREENTIP_CONTEXT_ALT_LMB] = "Remove blob"
return CONTEXTUAL_SCREENTIP_SET
/obj/structure/blob/proc/creation_action() //When it's created by the overmind, do this.
return
@@ -91,6 +105,9 @@
. = ..()
if(overmind)
add_atom_colour(overmind.blobstrain.color, FIXED_COLOUR_PRIORITY)
var/area/A = get_area(src)
if(!(A.area_flags & BLOBS_ALLOWED))
add_atom_colour(BlendRGB(overmind.blobstrain.color, COLOR_WHITE, 0.5), FIXED_COLOUR_PRIORITY) //lighten it to indicate an off-station blob
else
remove_atom_colour(FIXED_COLOUR_PRIORITY)
@@ -117,12 +134,17 @@
/obj/structure/blob/proc/blob_attack_animation(atom/A = null, controller) //visually attacks an atom
var/obj/effect/temp_visual/blob/O = new /obj/effect/temp_visual/blob(src.loc)
O.setDir(dir)
var/area/my_area = get_area(src)
if(controller)
var/mob/camera/blob/BO = controller
O.color = BO.blobstrain.color
if(!(my_area.area_flags & BLOBS_ALLOWED))
O.color = BlendRGB(O.color, COLOR_WHITE, 0.5) //lighten it to indicate an off-station blob
O.alpha = 200
else if(overmind)
O.color = overmind.blobstrain.color
if(!(my_area.area_flags & BLOBS_ALLOWED))
O.color = BlendRGB(O.color, COLOR_WHITE, 0.5) //lighten it to indicate an off-station blob
if(A)
O.do_attack_animation(A) //visually attack the whatever
return O //just in case you want to do something to the animation.
@@ -164,6 +186,11 @@
if(T.Enter(B)) //NOW we can attempt to move into the tile
B.set_density(initial(B.density))
B.forceMove(T)
var/area/Ablob = get_area(B)
if(Ablob.area_flags & BLOBS_ALLOWED) //Is this area allowed for winning as blob?
overmind.blobs_legit += B
else if(controller)
B.balloon_alert(overmind, "off-station, won't count!")
B.update_appearance()
if(B.overmind && expand_reaction)
B.overmind.blobstrain.expand_reaction(src, B, T, controller)
@@ -49,8 +49,8 @@
. += mutable_appearance('icons/mob/blob.dmi', "blob_core_overlay")
/obj/structure/blob/special/core/update_icon()
. = ..()
color = null
return ..()
/obj/structure/blob/special/core/ex_act(severity, target)
var/damage = 10 * (severity + 1) //remember, the core takes half brute damage, so this is 20/15/10 damage based on severity
@@ -24,14 +24,17 @@
return "Gradually expands and sustains nearby blob spores and blobbernauts."
/obj/structure/blob/special/node/update_icon()
. = ..()
color = null
return ..()
/obj/structure/blob/special/node/update_overlays()
. = ..()
var/mutable_appearance/blob_overlay = mutable_appearance('icons/mob/blob.dmi', "blob")
if(overmind)
blob_overlay.color = overmind.blobstrain.color
var/area/A = get_area(src)
if(!(A.area_flags & BLOBS_ALLOWED))
blob_overlay.color = BlendRGB(overmind.blobstrain.color, COLOR_WHITE, 0.5) //lighten it to indicate an off-station blob
. += blob_overlay
. += mutable_appearance('icons/mob/blob.dmi', "blob_node_overlay")
@@ -27,6 +27,7 @@
flick("blob_resource_glow", src)
if(overmind)
overmind.add_points(BLOB_RESOURCE_GATHER_AMOUNT)
balloon_alert(overmind, "+[BLOB_RESOURCE_GATHER_AMOUNT] resource\s")
resource_delay = world.time + BLOB_RESOURCE_GATHER_DELAY + overmind.resource_blobs.len * BLOB_RESOURCE_GATHER_ADDED_DELAY //4 seconds plus a quarter second for each resource blob the overmind has
else
resource_delay = world.time + BLOB_RESOURCE_GATHER_DELAY
@@ -1,4 +1,4 @@
/mob/living/carbon/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
/mob/living/carbon/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
if (!isnull(held_item))
@@ -7,15 +7,17 @@
if (!ishuman(user))
return .
if (user.combat_mode)
var/mob/living/carbon/human/human_user = user
if (human_user.combat_mode)
context[SCREENTIP_CONTEXT_LMB] = "Attack"
else if (user == src)
else if (human_user == src)
context[SCREENTIP_CONTEXT_LMB] = "Check injuries"
if (get_bodypart(user.zone_selected)?.get_bleed_rate())
if (get_bodypart(human_user.zone_selected)?.get_bleed_rate())
context[SCREENTIP_CONTEXT_CTRL_LMB] = "Grab limb"
if (user != src)
if (human_user != src)
context[SCREENTIP_CONTEXT_RMB] = "Shove"
if (body_position == STANDING_UP)