mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-01-06 07:22:42 +00:00
Blob Genesis (#7781)
* Allows the regeneration of blobs from the core chunks they leave behind on death. * Blobtalk. * Font
This commit is contained in:
@@ -23,6 +23,14 @@ var/list/overminds = list()
|
||||
var/ai_controlled = TRUE
|
||||
var/auto_pilot = FALSE // If true, and if a client is attached, the AI routine will continue running.
|
||||
|
||||
universal_understand = TRUE
|
||||
|
||||
var/list/has_langs = list(LANGUAGE_BLOB)
|
||||
var/datum/language/default_language = null
|
||||
|
||||
/mob/observer/blob/get_default_language()
|
||||
return default_language
|
||||
|
||||
/mob/observer/blob/Initialize(newloc, pre_placed = 0, starting_points = 60, desired_blob_type = null)
|
||||
blob_points = starting_points
|
||||
if(pre_placed) //we already have a core!
|
||||
@@ -41,6 +49,11 @@ var/list/overminds = list()
|
||||
if(blob_core)
|
||||
blob_core.update_icon()
|
||||
|
||||
for(var/L in has_langs)
|
||||
languages |= GLOB.all_languages[L]
|
||||
if(languages.len)
|
||||
default_language = languages[1]
|
||||
|
||||
return ..(newloc)
|
||||
|
||||
/mob/observer/blob/Destroy()
|
||||
@@ -67,9 +80,9 @@ var/list/overminds = list()
|
||||
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
|
||||
stat(null, "Total Blobs: [GLOB.all_blobs.len]")
|
||||
|
||||
/mob/observer/blob/Move(NewLoc, Dir = 0)
|
||||
/mob/observer/blob/Move(var/atom/NewLoc, Dir = 0)
|
||||
if(placed)
|
||||
var/obj/structure/blob/B = locate() in range("3x3", NewLoc)
|
||||
var/obj/structure/blob/B = (locate() in view("5x5", NewLoc))
|
||||
if(B)
|
||||
forceMove(NewLoc)
|
||||
return TRUE
|
||||
@@ -93,3 +106,62 @@ var/list/overminds = list()
|
||||
if(blob_points >= 100)
|
||||
if(!auto_factory() && !auto_resource())
|
||||
auto_node()
|
||||
|
||||
/mob/observer/blob/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
|
||||
message = sanitize(message)
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
//If you're muted for IC chat
|
||||
if(client)
|
||||
if(message)
|
||||
client.handle_spam_prevention(MUTE_IC)
|
||||
if((client.prefs.muted & MUTE_IC) || say_disabled)
|
||||
to_chat(src, "<span class='warning'>You cannot speak in IC (Muted).</span>")
|
||||
return
|
||||
|
||||
//These will contain the main receivers of the message
|
||||
var/list/listening = list()
|
||||
var/list/listening_obj = list()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
//Obtain the mobs and objects in the message range
|
||||
var/list/results = get_mobs_and_objs_in_view_fast(T, world.view, remote_ghosts = client ? TRUE : FALSE)
|
||||
listening = results["mobs"]
|
||||
listening_obj = results["objs"]
|
||||
else
|
||||
return 1 //If we're in nullspace, then forget it.
|
||||
|
||||
var/list/message_pieces = parse_languages(message)
|
||||
if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quirk for dealing with hivemind/signlang languages.
|
||||
var/datum/multilingual_say_piece/S = message_pieces // Yay for BYOND's hilariously broken typecasting for allowing us to do this.
|
||||
S.speaking.broadcast(src, S.message)
|
||||
return 1
|
||||
|
||||
if(!LAZYLEN(message_pieces))
|
||||
log_runtime(EXCEPTION("Message failed to generate pieces. [message] - [json_encode(message_pieces)]"))
|
||||
return 0
|
||||
|
||||
//Handle nonverbal languages here
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
if(S.speaking.flags & NONVERBAL)
|
||||
custom_emote(1, "[pick(S.speaking.signlang_verb)].")
|
||||
|
||||
for(var/mob/M in listening)
|
||||
spawn()
|
||||
if(M && src)
|
||||
if(get_dist(M, src) <= world.view || (M.stat == DEAD && !forbid_seeing_deadchat))
|
||||
M.hear_say(message_pieces, "conveys", (M.faction == blob_type.faction), src)
|
||||
|
||||
//Object message delivery
|
||||
for(var/obj/O in listening_obj)
|
||||
spawn(0)
|
||||
if(O && src) //If we still exist, when the spawn processes
|
||||
var/dst = get_dist(get_turf(O),get_turf(src))
|
||||
if(dst <= world.view)
|
||||
O.hear_talk(src, message_pieces, "conveys")
|
||||
|
||||
log_say(message, src)
|
||||
return 1
|
||||
|
||||
@@ -80,8 +80,8 @@
|
||||
potential_blobs -= temp // Don't take up the core's shield spot.
|
||||
else if(!istype(temp, /obj/structure/blob/normal))
|
||||
potential_blobs -= temp // Not a normal blob.
|
||||
else if(temp.overmind != src)
|
||||
potential_blobs -= temp // Not our blob.
|
||||
else if(temp.overmind != src || temp.overmind.blob_type.faction != blob_type.faction)
|
||||
potential_blobs -= temp // Not our blob, or even an ally.
|
||||
else
|
||||
B = temp
|
||||
break
|
||||
@@ -123,8 +123,8 @@
|
||||
potential_blobs -= temp // Don't take up the core's shield spot.
|
||||
else if(!istype(temp, /obj/structure/blob/normal))
|
||||
potential_blobs -= temp // Not a normal blob.
|
||||
else if(temp.overmind != src)
|
||||
potential_blobs -= temp // Not our blob.
|
||||
else if(temp.overmind != src || temp.overmind.blob_type.faction != blob_type.faction)
|
||||
potential_blobs -= temp // Not our blob, or even an ally
|
||||
else
|
||||
B = temp
|
||||
break
|
||||
@@ -165,8 +165,8 @@
|
||||
potential_blobs -= temp
|
||||
else if(!istype(temp, /obj/structure/blob/normal))
|
||||
potential_blobs -= temp
|
||||
else if(temp.overmind != src)
|
||||
potential_blobs -= temp // Not our blob.
|
||||
else if(temp.overmind != src || temp.overmind.blob_type.faction != blob_type.faction)
|
||||
potential_blobs -= temp // Not our blob, or even our ally.
|
||||
else
|
||||
B = temp
|
||||
break
|
||||
@@ -216,7 +216,7 @@
|
||||
for(var/mob/living/L in view(src))
|
||||
if(L.stat == DEAD)
|
||||
continue // Already dying or dead.
|
||||
if(L.faction == "blob")
|
||||
if(L.faction == blob_type.faction)
|
||||
continue // No friendly fire.
|
||||
if(locate(/obj/structure/blob) in L.loc)
|
||||
continue // Already has a blob over them.
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
var/color = "#FFFFFF" // The actual blob's color.
|
||||
var/complementary_color = "#000000" //a color that's complementary to the normal blob color. Blob mobs are colored in this.
|
||||
|
||||
var/faction = "blob" // The blob's faction.
|
||||
|
||||
var/attack_message = "The blob attacks you" // Base message the mob gets when blob_act() gets called on them by the blob. An exclaimation point is added to the end.
|
||||
var/attack_message_living = null // Appended to attack_message, if the target fails isSynthetic() check.
|
||||
var/attack_message_synth = null // Ditto, but if they pass isSynthetic().
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
env.add_thermal_energy(10 * 1000)
|
||||
|
||||
/datum/blob_type/blazing_oil/on_chunk_tick(obj/item/weapon/blobcore_chunk/B)
|
||||
B.reagents.add_reagent("thermite_v", 0.5)
|
||||
|
||||
var/turf/T = get_turf(B)
|
||||
if(!T)
|
||||
return
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
env.add_thermal_energy(-10 * 1000)
|
||||
|
||||
/datum/blob_type/cryogenic_goo/on_chunk_tick(obj/item/weapon/blobcore_chunk/B)
|
||||
B.reagents.add_reagent("cryoslurry", 0.5)
|
||||
|
||||
var/turf/simulated/T = get_turf(B)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
listclearnulls(active_beams)
|
||||
var/atom/movable/beam_origin = B
|
||||
for(var/mob/living/L in oview(world.view, B))
|
||||
if(L.stat == DEAD || L.faction == "blob")
|
||||
if(L.stat == DEAD || L.faction == faction)
|
||||
continue
|
||||
if(prob(5))
|
||||
var/beamtarget_exists = FALSE
|
||||
@@ -82,7 +82,7 @@
|
||||
if(nearby_mobs.len)
|
||||
listclearnulls(active_beams)
|
||||
for(var/mob/living/L in nearby_mobs)
|
||||
if(L.stat == DEAD || L.faction == "blob")
|
||||
if(L.stat == DEAD || L.faction == faction)
|
||||
continue
|
||||
if(prob(5))
|
||||
var/beamtarget_exists = FALSE
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
for(var/mob/living/L in range(get_turf(victim), 1)) // We don't use orange(), in case there is more than one mob on the target tile.
|
||||
if(L == victim) // Already hit.
|
||||
continue
|
||||
if(L.faction == "blob") // No friendly fire
|
||||
if(L.faction == faction) // No friendly fire
|
||||
continue
|
||||
L.blob_act()
|
||||
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
var/mob/living/simple_mob/blob/spore/S = new spore_type(T)
|
||||
if(istype(S))
|
||||
S.overmind = O
|
||||
S.faction = faction
|
||||
O.blob_mobs.Add(S)
|
||||
else
|
||||
S.faction = "blob"
|
||||
S.faction = faction
|
||||
S.update_icons()
|
||||
|
||||
/datum/blob_type/fulminant_organism/on_death(obj/structure/blob/B)
|
||||
@@ -35,9 +36,10 @@
|
||||
B.visible_message("<span class='danger'>\The [S] floats free from the [name]!</span>")
|
||||
if(istype(S))
|
||||
S.overmind = B.overmind
|
||||
S.faction = faction
|
||||
B.overmind.blob_mobs.Add(S)
|
||||
else
|
||||
S.faction = "blob"
|
||||
S.faction = faction
|
||||
S.update_icons()
|
||||
|
||||
/datum/blob_type/fulminant_organism/on_chunk_use(obj/item/weapon/blobcore_chunk/B, mob/living/user)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
attack_message = "The tide tries to swallow you"
|
||||
attack_message_living = ", and you feel your skin dissolve"
|
||||
attack_message_synth = ", and your external plating dissolves"
|
||||
faction = "nanomachines"
|
||||
|
||||
/datum/blob_type/grey_goo/on_emp(obj/structure/blob/B, severity)
|
||||
B.adjust_integrity(-(20 / severity))
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
if(!istype(L))
|
||||
return
|
||||
|
||||
if(istype(B, /obj/structure/blob/factory) && L.stat != DEAD && prob(ai_aggressiveness) && L.faction != "blob")
|
||||
if(istype(B, /obj/structure/blob/factory) && L.stat != DEAD && prob(ai_aggressiveness) && L.faction != faction)
|
||||
var/obj/item/projectile/arc/spore/P = new(get_turf(B))
|
||||
P.launch_projectile(L, BP_TORSO, B)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user