mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 00:29:02 +01:00
Blob Features!
A blob tile will light up when it is being pulsed by a core/node, adds crucial visual feedback when placing resources/factories. New shortcuts for the blob. Expand = CTRL Click - Rally = Middle Mouse Click - Create Shield = Alt Click Blobs can now talk to each other and ghosts can hear them. Thanks to /vg/ for this code. Removed the unnecessary AI quarantine code. Formated the blob code to use the standard.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
// Blob Overmind Controls
|
||||
|
||||
|
||||
/mob/camera/blob/CtrlClickOn(var/atom/A) // Expand blob
|
||||
var/turf/T = get_turf(A)
|
||||
if(T)
|
||||
expand_blob(T)
|
||||
|
||||
/mob/camera/blob/MiddleClickOn(var/atom/A) // Rally spores
|
||||
var/turf/T = get_turf(A)
|
||||
if(T)
|
||||
rally_spores(T)
|
||||
|
||||
/mob/camera/blob/AltClickOn(var/atom/A) // Create a shield
|
||||
var/turf/T = get_turf(A)
|
||||
if(T)
|
||||
create_shield(T)
|
||||
+1
-1
@@ -1184,7 +1184,7 @@ datum/mind
|
||||
mind.special_role = ""
|
||||
|
||||
//BLOB
|
||||
/mob/camera/overmind/mind_initialize()
|
||||
/mob/camera/blob/mind_initialize()
|
||||
..()
|
||||
mind.special_role = "Blob"
|
||||
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
feedback_set_details("round_end_result","loss - blob took over")
|
||||
world << "<FONT size = 3><B>The blob has taken over the station!</B></FONT>"
|
||||
world << "<B>The entire station was eaten by the Blob</B>"
|
||||
check_quarantine()
|
||||
log_game("Blob mode was lost.")
|
||||
|
||||
else if(station_was_nuked)
|
||||
feedback_set_details("round_end_result","halfwin - nuke")
|
||||
world << "<FONT size = 3><B>Partial Win: The station has been destroyed!</B></FONT>"
|
||||
world << "<B>Directive 7-12 has been successfully carried out preventing the Blob from spreading.</B>"
|
||||
log_game("Blob mode was tie (station destroyed).")
|
||||
|
||||
else if(!blob_cores.len)
|
||||
feedback_set_details("round_end_result","win - blob eliminated")
|
||||
@@ -45,34 +46,4 @@ datum/game_mode/proc/auto_declare_completion_blob()
|
||||
for(var/datum/mind/blob in blob_mode.infected_crew)
|
||||
text += "<br>[blob.key] was [blob.name]"
|
||||
world << text
|
||||
return 1
|
||||
|
||||
/datum/game_mode/blob/proc/check_quarantine()
|
||||
var/numDead = 0
|
||||
var/numAlive = 0
|
||||
var/numSpace = 0
|
||||
var/numOffStation = 0
|
||||
for (var/mob/living/silicon/ai/aiPlayer in mob_list)
|
||||
for(var/mob/living/carbon/human/M in mob_list)
|
||||
if ((M != aiPlayer && M.client))
|
||||
if (M.stat == 2)
|
||||
numDead += 1
|
||||
else
|
||||
var/T = M.loc
|
||||
if (istype(T, /turf/space))
|
||||
numSpace += 1
|
||||
else if(istype(T, /turf))
|
||||
if (M.z!=1)
|
||||
numOffStation += 1
|
||||
else
|
||||
numAlive += 1
|
||||
if (numSpace==0 && numOffStation==0)
|
||||
world << "<FONT size = 3><B>The AI has won!</B></FONT>"
|
||||
world << "<B>The AI successfully maintained the quarantine - no players were in space or were off-station (as far as we can tell).</B>"
|
||||
log_game("AI won at Blob mode despite overall loss.")
|
||||
else
|
||||
world << "<FONT size = 3><B>The AI has lost!</B></FONT>"
|
||||
world << text("<B>The AI failed to maintain the quarantine - [] were in space and [] were off-station (as far as we can tell).</B>", numSpace, numOffStation)
|
||||
log_game("AI lost at Blob mode.")
|
||||
log_game("Blob mode was lost.")
|
||||
return 1
|
||||
return 1
|
||||
@@ -9,81 +9,77 @@
|
||||
var/resource_delay = 0
|
||||
var/point_rate = 2
|
||||
|
||||
New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2)
|
||||
blob_cores += src
|
||||
processing_objects.Add(src)
|
||||
if(!overmind)
|
||||
create_overmind(new_overmind)
|
||||
point_rate = new_rate
|
||||
..(loc, h)
|
||||
/obj/effect/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2)
|
||||
blob_cores += src
|
||||
processing_objects.Add(src)
|
||||
if(!overmind)
|
||||
create_overmind(new_overmind)
|
||||
point_rate = new_rate
|
||||
..(loc, h)
|
||||
|
||||
|
||||
Del()
|
||||
blob_cores -= src
|
||||
if(overmind)
|
||||
del(overmind)
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
/obj/effect/blob/core/Del()
|
||||
blob_cores -= src
|
||||
if(overmind)
|
||||
del(overmind)
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/effect/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return
|
||||
|
||||
/obj/effect/blob/core/update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/effect/blob/core/Life()
|
||||
if(!overmind)
|
||||
create_overmind()
|
||||
else
|
||||
if(resource_delay <= world.time)
|
||||
resource_delay = world.time + 10 // 1 second
|
||||
overmind.add_points(point_rate)
|
||||
health = min(initial(health), health + 1)
|
||||
for(var/i = 1; i < 8; i += i)
|
||||
Pulse(0, i)
|
||||
for(var/b_dir in alldirs)
|
||||
if(!prob(5))
|
||||
continue
|
||||
var/obj/effect/blob/normal/B = locate() in get_step(src, b_dir)
|
||||
if(B)
|
||||
B.change_to(/obj/effect/blob/shield)
|
||||
..()
|
||||
|
||||
|
||||
/obj/effect/blob/core/proc/create_overmind(var/client/new_overmind)
|
||||
|
||||
if(overmind_get_delay > world.time)
|
||||
return
|
||||
|
||||
fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return
|
||||
overmind_get_delay = world.time + 300 // 30 seconds
|
||||
|
||||
update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
return
|
||||
if(overmind)
|
||||
del(overmind)
|
||||
|
||||
Life()
|
||||
if(!overmind)
|
||||
create_overmind()
|
||||
else
|
||||
if(resource_delay <= world.time)
|
||||
resource_delay = world.time + 10 // 1 second
|
||||
overmind.add_points(point_rate)
|
||||
health = min(initial(health), health + 1)
|
||||
for(var/i = 1; i < 8; i += i)
|
||||
Pulse(0, i)
|
||||
for(var/b_dir in alldirs)
|
||||
if(!prob(5))
|
||||
continue
|
||||
var/obj/effect/blob/normal/B = locate() in get_step(src, b_dir)
|
||||
if(B)
|
||||
B.change_to(/obj/effect/blob/shield)
|
||||
..()
|
||||
var/client/C = null
|
||||
var/list/candidates = list()
|
||||
|
||||
if(!new_overmind)
|
||||
candidates = get_candidates(BE_ALIEN)
|
||||
if(candidates.len)
|
||||
C = pick(candidates)
|
||||
else
|
||||
C = new_overmind
|
||||
|
||||
run_action()
|
||||
return 0
|
||||
|
||||
|
||||
proc/create_overmind(var/client/new_overmind)
|
||||
|
||||
if(overmind_get_delay > world.time)
|
||||
return
|
||||
|
||||
overmind_get_delay = world.time + 300 // 30 seconds
|
||||
|
||||
if(overmind)
|
||||
del(overmind)
|
||||
|
||||
var/client/C = null
|
||||
var/list/candidates = list()
|
||||
|
||||
if(!new_overmind)
|
||||
candidates = get_candidates(BE_ALIEN)
|
||||
if(candidates.len)
|
||||
C = pick(candidates)
|
||||
else
|
||||
C = new_overmind
|
||||
|
||||
if(C)
|
||||
var/mob/camera/blob/B = new(src.loc)
|
||||
B.key = C.key
|
||||
B.blob_core = src
|
||||
src.overmind = B
|
||||
return 1
|
||||
return 0
|
||||
if(C)
|
||||
var/mob/camera/blob/B = new(src.loc)
|
||||
B.key = C.key
|
||||
B.blob_core = src
|
||||
src.overmind = B
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -8,22 +8,27 @@
|
||||
var/max_spores = 3
|
||||
var/spore_delay = 0
|
||||
|
||||
update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
/obj/effect/blob/factory/update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/effect/blob/factory/PulseAnimation(var/activate = 0)
|
||||
if(activate)
|
||||
..()
|
||||
return
|
||||
|
||||
run_action()
|
||||
if(spores.len >= max_spores)
|
||||
return 0
|
||||
if(spore_delay > world.time)
|
||||
return 0
|
||||
spore_delay = world.time + 100 // 10 seconds
|
||||
new/mob/living/simple_animal/hostile/blobspore(src.loc, src)
|
||||
return 1
|
||||
/obj/effect/blob/factory/run_action()
|
||||
if(spores.len >= max_spores)
|
||||
return 0
|
||||
if(spore_delay > world.time)
|
||||
return 0
|
||||
spore_delay = world.time + 100 // 10 seconds
|
||||
PulseAnimation(1)
|
||||
new/mob/living/simple_animal/hostile/blobspore(src.loc, src)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/blobspore
|
||||
@@ -52,41 +57,41 @@
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 360
|
||||
|
||||
fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
adjustBruteLoss(Clamp(0.01 * exposed_temperature, 1, 5))
|
||||
/mob/living/simple_animal/hostile/blobspore/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
adjustBruteLoss(Clamp(0.01 * exposed_temperature, 1, 5))
|
||||
|
||||
blob_act()
|
||||
return
|
||||
/mob/living/simple_animal/hostile/blobspore/blob_act()
|
||||
return
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(istype(mover, /obj/effect/blob))
|
||||
return 1
|
||||
return ..()
|
||||
/mob/living/simple_animal/hostile/blobspore/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(istype(mover, /obj/effect/blob))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
New(loc, var/obj/effect/blob/factory/linked_node)
|
||||
if(istype(linked_node))
|
||||
factory = linked_node
|
||||
factory.spores += src
|
||||
..()
|
||||
/mob/living/simple_animal/hostile/blobspore/New(loc, var/obj/effect/blob/factory/linked_node)
|
||||
if(istype(linked_node))
|
||||
factory = linked_node
|
||||
factory.spores += src
|
||||
..()
|
||||
|
||||
Die()
|
||||
// On death, create a small smoke of harmful gas (s-Acid)
|
||||
var/datum/effect/effect/system/chem_smoke_spread/S = new
|
||||
var/turf/location = get_turf(src)
|
||||
/mob/living/simple_animal/hostile/blobspore/Die()
|
||||
// On death, create a small smoke of harmful gas (s-Acid)
|
||||
var/datum/effect/effect/system/chem_smoke_spread/S = new
|
||||
var/turf/location = get_turf(src)
|
||||
|
||||
// Create the reagents to put into the air, s-acid is yellow and stings a little
|
||||
create_reagents(25)
|
||||
reagents.add_reagent("spore", 25)
|
||||
// Create the reagents to put into the air, s-acid is yellow and stings a little
|
||||
create_reagents(25)
|
||||
reagents.add_reagent("spore", 25)
|
||||
|
||||
// Attach the smoke spreader and setup/start it.
|
||||
S.attach(location)
|
||||
S.set_up(reagents, 1, 1, location, 15, 1) // only 1-2 smoke cloud
|
||||
S.start()
|
||||
// Attach the smoke spreader and setup/start it.
|
||||
S.attach(location)
|
||||
S.set_up(reagents, 1, 1, location, 15, 1) // only 1-2 smoke cloud
|
||||
S.start()
|
||||
|
||||
del(src)
|
||||
del(src)
|
||||
|
||||
Del()
|
||||
if(factory)
|
||||
factory.spores -= src
|
||||
..()
|
||||
/mob/living/simple_animal/hostile/blobspore/Del()
|
||||
if(factory)
|
||||
factory.spores -= src
|
||||
..()
|
||||
|
||||
@@ -6,32 +6,28 @@
|
||||
fire_resist = 2
|
||||
|
||||
|
||||
New(loc, var/h = 100)
|
||||
blob_nodes += src
|
||||
processing_objects.Add(src)
|
||||
..(loc, h)
|
||||
/obj/effect/blob/node/New(loc, var/h = 100)
|
||||
blob_nodes += src
|
||||
processing_objects.Add(src)
|
||||
..(loc, h)
|
||||
|
||||
fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
/obj/effect/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return
|
||||
|
||||
/obj/effect/blob/node/Del()
|
||||
blob_nodes -= src
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/effect/blob/node/Life()
|
||||
for(var/i = 1; i < 8; i += i)
|
||||
Pulse(5, i)
|
||||
health = min(initial(health), health + 1)
|
||||
|
||||
/obj/effect/blob/node/update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
|
||||
Del()
|
||||
blob_nodes -= src
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
return
|
||||
|
||||
Life()
|
||||
for(var/i = 1; i < 8; i += i)
|
||||
Pulse(5, i)
|
||||
health = min(initial(health), health + 1)
|
||||
|
||||
update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
run_action()
|
||||
return 0
|
||||
return
|
||||
@@ -7,20 +7,28 @@
|
||||
var/mob/camera/blob/overmind = null
|
||||
var/resource_delay = 0
|
||||
|
||||
update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
/obj/effect/blob/resource/update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
return
|
||||
|
||||
run_action()
|
||||
if(resource_delay > world.time)
|
||||
return 0
|
||||
/obj/effect/blob/resource/PulseAnimation(var/activate = 0)
|
||||
if(activate)
|
||||
..()
|
||||
return
|
||||
|
||||
resource_delay = world.time + 40 // 4 seconds
|
||||
/obj/effect/blob/resource/run_action()
|
||||
|
||||
if(overmind)
|
||||
overmind.add_points(1)
|
||||
return 1
|
||||
if(resource_delay > world.time)
|
||||
return 0
|
||||
|
||||
PulseAnimation(1)
|
||||
|
||||
resource_delay = world.time + 40 // 4 seconds
|
||||
|
||||
if(overmind)
|
||||
overmind.add_points(1)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
fire_resist = 2
|
||||
|
||||
|
||||
update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
/obj/effect/blob/shield/update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
return
|
||||
|
||||
fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return
|
||||
/obj/effect/blob/shield/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
|
||||
return 0
|
||||
/obj/effect/blob/shield/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
|
||||
return 0
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
/mob/camera/blob/Login()
|
||||
..()
|
||||
sync_mind()
|
||||
|
||||
src << "<span class='notice'>You are the overmind!</span>"
|
||||
src << "You are the overmind and can control the blob by placing new blob pieces such as..."
|
||||
src << "<b>Normal Blob</b> will expand your reach and allow you to upgrade into special blobs that perform certain functions."
|
||||
@@ -32,6 +31,7 @@
|
||||
src << "<b>Resource Blob</b> is a blob which will collect more resources for you, try to build these earlier to get a strong income. It will benefit from being near your core or multiple nodes, by having an increased resource rate; put it alone and it won't create resources at all."
|
||||
src << "<b>Node Blob</b> is a blob which will grow, like the core. Unlike the core it won't give you a small income but it can power resource and factory blobs to increase their rate."
|
||||
src << "<b>Factory Blob</b> is a blob which will spawn blob spores which will attack nearby food. Putting this nearby nodes and your core will increase the spawn rate; put it alone and it will not spawn any spores."
|
||||
src << "<b>Shortcuts:</b> CTRL Click = Expand Blob / Middle Mouse Click = Rally Spores / Alt Click = Create Shield"
|
||||
|
||||
|
||||
mob/camera/blob/Life()
|
||||
@@ -40,7 +40,35 @@ mob/camera/blob/Life()
|
||||
return
|
||||
|
||||
/mob/camera/blob/say(var/message)
|
||||
return//No talking for you
|
||||
if (!message)
|
||||
return
|
||||
|
||||
if (src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
src << "You cannot send IC messages (muted)."
|
||||
return
|
||||
if (src.client.handle_spam_prevention(message,MUTE_IC))
|
||||
return
|
||||
|
||||
if (stat)
|
||||
return
|
||||
|
||||
blob_talk(message)
|
||||
|
||||
/mob/camera/blob/proc/blob_talk(message)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
|
||||
if (!message)
|
||||
return
|
||||
|
||||
var/message_a = say_quote(message)
|
||||
var/rendered = "<font color=\"#EE4000\"><i><span class='game say'>Blob Telepathy, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i></font>"
|
||||
|
||||
for (var/mob/M in mob_list)
|
||||
if(isovermind(M) || isobserver(M))
|
||||
M.show_message(rendered, 2)
|
||||
|
||||
/mob/camera/blob/emote(var/act,var/m_type=1,var/message = null)
|
||||
return
|
||||
@@ -64,3 +92,5 @@ mob/camera/blob/Life()
|
||||
loc = NewLoc
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
@@ -35,16 +35,15 @@
|
||||
if(chosen_node)
|
||||
src.loc = chosen_node.loc
|
||||
|
||||
/mob/camera/blob/verb/create_shield()
|
||||
/mob/camera/blob/verb/create_shield_power()
|
||||
set category = "Blob"
|
||||
set name = "Create Shield Blob (10)"
|
||||
set desc = "Create a shield blob."
|
||||
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
create_shield(T)
|
||||
|
||||
if(!T)
|
||||
return
|
||||
/mob/camera/blob/proc/create_shield(var/turf/T)
|
||||
|
||||
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
|
||||
|
||||
@@ -64,6 +63,7 @@
|
||||
return
|
||||
|
||||
|
||||
|
||||
/mob/camera/blob/verb/create_resource()
|
||||
set category = "Blob"
|
||||
set name = "Create Resource Blob (40)"
|
||||
@@ -85,7 +85,7 @@
|
||||
src << "Unable to use this blob, find a normal one."
|
||||
return
|
||||
|
||||
for(var/obj/effect/blob/resource/blob in orange(4))
|
||||
for(var/obj/effect/blob/resource/blob in orange(4, T))
|
||||
src << "There is a resource blob nearby, move more than 4 tiles away from it!"
|
||||
return
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
src << "Unable to use this blob, find a normal one."
|
||||
return
|
||||
|
||||
for(var/obj/effect/blob/node/blob in orange(5))
|
||||
for(var/obj/effect/blob/node/blob in orange(5, T))
|
||||
src << "There is another node nearby, move more than 5 tiles away from it!"
|
||||
return
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
src << "Unable to use this blob, find a normal one."
|
||||
return
|
||||
|
||||
for(var/obj/effect/blob/factory/blob in orange(7))
|
||||
for(var/obj/effect/blob/factory/blob in orange(7, T))
|
||||
src << "There is a factory blob nearby, move more than 7 tiles away from it!"
|
||||
return
|
||||
|
||||
@@ -186,13 +186,15 @@
|
||||
return
|
||||
|
||||
|
||||
/mob/camera/blob/verb/spawn_blob()
|
||||
/mob/camera/blob/verb/expand_blob_power()
|
||||
set category = "Blob"
|
||||
set name = "Expand Blob (5)"
|
||||
set desc = "Attempts to create a new blob in this tile. If the tile isn't clear we will attack it, which might clear it."
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
expand_blob(T)
|
||||
|
||||
/mob/camera/blob/proc/expand_blob(var/turf/T)
|
||||
if(!T)
|
||||
return
|
||||
|
||||
@@ -201,7 +203,7 @@
|
||||
src << "There is a blob here!"
|
||||
return
|
||||
|
||||
var/obj/effect/blob/OB = locate() in circlerange(src, 1)
|
||||
var/obj/effect/blob/OB = locate() in circlerange(T, 1)
|
||||
if(!OB)
|
||||
src << "There is no blob adjacent to you."
|
||||
return
|
||||
@@ -212,20 +214,27 @@
|
||||
return
|
||||
|
||||
|
||||
/mob/camera/blob/verb/rally_spores()
|
||||
/mob/camera/blob/verb/rally_spores_power()
|
||||
set category = "Blob"
|
||||
set name = "Rally Spores (5)"
|
||||
set desc = "Rally the spores to move to your location."
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
rally_spores(T)
|
||||
|
||||
/mob/camera/blob/proc/rally_spores(var/turf/T)
|
||||
|
||||
if(!can_buy(5))
|
||||
return
|
||||
|
||||
var/list/surrounding_turfs = block(locate(x - 1, y - 1, z), locate(x + 1, y + 1, z))
|
||||
src << "You rally your spores."
|
||||
|
||||
var/list/surrounding_turfs = block(locate(T.x - 1, T.y - 1, T.z), locate(T.x + 1, T.y + 1, T.z))
|
||||
if(!surrounding_turfs.len)
|
||||
return
|
||||
|
||||
for(var/mob/living/simple_animal/hostile/blobspore/BS in living_mob_list)
|
||||
if(isturf(BS.loc) && get_dist(BS, src) <= 20)
|
||||
if(isturf(BS.loc) && get_dist(BS, T) <= 35)
|
||||
BS.LoseTarget()
|
||||
BS.Goto(pick(surrounding_turfs), BS.move_to_delay)
|
||||
return
|
||||
+158
-138
@@ -12,160 +12,180 @@
|
||||
var/fire_resist = 1
|
||||
|
||||
|
||||
New(loc)
|
||||
blobs += src
|
||||
src.dir = pick(1, 2, 4, 8)
|
||||
src.update_icon()
|
||||
..(loc)
|
||||
for(var/atom/A in loc)
|
||||
A.blob_act()
|
||||
return
|
||||
/obj/effect/blob/New(loc)
|
||||
blobs += src
|
||||
src.dir = pick(1, 2, 4, 8)
|
||||
src.update_icon()
|
||||
..(loc)
|
||||
for(var/atom/A in loc)
|
||||
A.blob_act()
|
||||
return
|
||||
|
||||
|
||||
Del()
|
||||
blobs -= src
|
||||
..()
|
||||
return
|
||||
/obj/effect/blob/Del()
|
||||
blobs -= src
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0)) return 1
|
||||
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
|
||||
return 0
|
||||
/obj/effect/blob/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0)) return 1
|
||||
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
|
||||
return 0
|
||||
|
||||
|
||||
process()
|
||||
Life()
|
||||
return
|
||||
|
||||
fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
var/damage = Clamp(0.01 * exposed_temperature / fire_resist, 0, 4 - fire_resist)
|
||||
if(damage)
|
||||
health -= damage
|
||||
update_icon()
|
||||
|
||||
proc/Life()
|
||||
return
|
||||
|
||||
|
||||
proc/Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand
|
||||
|
||||
set background = 1
|
||||
|
||||
if(run_action())//If we can do something here then we dont need to pulse more
|
||||
return
|
||||
|
||||
if(pulse > 30)
|
||||
return//Inf loop check
|
||||
|
||||
//Looking for another blob to pulse
|
||||
var/list/dirs = list(1,2,4,8)
|
||||
dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
|
||||
for(var/i = 1 to 4)
|
||||
if(!dirs.len) break
|
||||
var/dirn = pick(dirs)
|
||||
dirs.Remove(dirn)
|
||||
var/turf/T = get_step(src, dirn)
|
||||
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
|
||||
if(!B)
|
||||
expand(T)//No blob here so try and expand
|
||||
return
|
||||
B.Pulse((pulse+1),get_dir(src.loc,T))
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
proc/run_action()
|
||||
return 0
|
||||
|
||||
|
||||
proc/expand(var/turf/T = null, var/prob = 1)
|
||||
if(prob && !prob(health)) return
|
||||
if(istype(T, /turf/space) && prob(75)) return
|
||||
if(!T)
|
||||
var/list/dirs = list(1,2,4,8)
|
||||
for(var/i = 1 to 4)
|
||||
var/dirn = pick(dirs)
|
||||
dirs.Remove(dirn)
|
||||
T = get_step(src, dirn)
|
||||
if(!(locate(/obj/effect/blob) in T)) break
|
||||
else T = null
|
||||
|
||||
if(!T) return 0
|
||||
var/obj/effect/blob/normal/B = new /obj/effect/blob/normal(src.loc, min(src.health, 30))
|
||||
B.density = 1
|
||||
if(T.Enter(B,src))//Attempt to move into the tile
|
||||
B.density = initial(B.density)
|
||||
B.loc = T
|
||||
else
|
||||
T.blob_act()//If we cant move in hit the turf
|
||||
B.Delete()
|
||||
|
||||
for(var/atom/A in T)//Hit everything in the turf
|
||||
A.blob_act()
|
||||
return 1
|
||||
|
||||
|
||||
ex_act(severity)
|
||||
var/damage = 150
|
||||
health -= ((damage/brute_resist) - (severity * 5))
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
bullet_act(var/obj/item/projectile/Proj)
|
||||
..()
|
||||
switch(Proj.damage_type)
|
||||
if(BRUTE)
|
||||
health -= (Proj.damage/brute_resist)
|
||||
if(BURN)
|
||||
health -= (Proj.damage/fire_resist)
|
||||
|
||||
update_icon()
|
||||
return 0
|
||||
|
||||
|
||||
attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
src.visible_message("\red <B>The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]")
|
||||
var/damage = 0
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
damage = (W.force / max(src.fire_resist,1))
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
|
||||
if("brute")
|
||||
damage = (W.force / max(src.brute_resist,1))
|
||||
/obj/effect/blob/process()
|
||||
Life()
|
||||
return
|
||||
|
||||
/obj/effect/blob/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
var/damage = Clamp(0.01 * exposed_temperature / fire_resist, 0, 4 - fire_resist)
|
||||
if(damage)
|
||||
health -= damage
|
||||
update_icon()
|
||||
|
||||
/obj/effect/blob/proc/Life()
|
||||
return
|
||||
|
||||
/obj/effect/blob/proc/PulseAnimation()
|
||||
flick("[icon_state]_glow", src)
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/blob/proc/Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand
|
||||
|
||||
set background = 1
|
||||
|
||||
PulseAnimation()
|
||||
|
||||
if(run_action())//If we can do something here then we dont need to pulse more
|
||||
return
|
||||
|
||||
proc/change_to(var/type)
|
||||
if(!ispath(type))
|
||||
error("[type] is an invalid type for the blob.")
|
||||
new type(src.loc)
|
||||
Delete()
|
||||
return
|
||||
if(pulse > 30)
|
||||
return//Inf loop check
|
||||
|
||||
proc/Delete()
|
||||
del(src)
|
||||
//Looking for another blob to pulse
|
||||
var/list/dirs = list(1,2,4,8)
|
||||
dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
|
||||
for(var/i = 1 to 4)
|
||||
if(!dirs.len) break
|
||||
var/dirn = pick(dirs)
|
||||
dirs.Remove(dirn)
|
||||
var/turf/T = get_step(src, dirn)
|
||||
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
|
||||
if(!B)
|
||||
expand(T)//No blob here so try and expand
|
||||
return
|
||||
B.Pulse((pulse+1),get_dir(src.loc,T))
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/blob/proc/run_action()
|
||||
return 0
|
||||
|
||||
|
||||
/obj/effect/blob/proc/expand(var/turf/T = null, var/prob = 1)
|
||||
if(prob && !prob(health)) return
|
||||
if(istype(T, /turf/space) && prob(75)) return
|
||||
if(!T)
|
||||
var/list/dirs = list(1,2,4,8)
|
||||
for(var/i = 1 to 4)
|
||||
var/dirn = pick(dirs)
|
||||
dirs.Remove(dirn)
|
||||
T = get_step(src, dirn)
|
||||
if(!(locate(/obj/effect/blob) in T)) break
|
||||
else T = null
|
||||
|
||||
if(!T) return 0
|
||||
var/obj/effect/blob/normal/B = new /obj/effect/blob/normal(src.loc, min(src.health, 30))
|
||||
B.density = 1
|
||||
if(T.Enter(B,src))//Attempt to move into the tile
|
||||
B.density = initial(B.density)
|
||||
B.loc = T
|
||||
else
|
||||
T.blob_act()//If we cant move in hit the turf
|
||||
B.Delete()
|
||||
|
||||
for(var/atom/A in T)//Hit everything in the turf
|
||||
A.blob_act()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/effect/blob/ex_act(severity)
|
||||
var/damage = 150
|
||||
health -= ((damage/brute_resist) - (severity * 5))
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/blob/bullet_act(var/obj/item/projectile/Proj)
|
||||
..()
|
||||
switch(Proj.damage_type)
|
||||
if(BRUTE)
|
||||
health -= (Proj.damage/brute_resist)
|
||||
if(BURN)
|
||||
health -= (Proj.damage/fire_resist)
|
||||
|
||||
update_icon()
|
||||
return 0
|
||||
|
||||
|
||||
/obj/effect/blob/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
src.visible_message("\red <B>The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]")
|
||||
var/damage = 0
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
damage = (W.force / max(src.fire_resist,1))
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
|
||||
if("brute")
|
||||
damage = (W.force / max(src.brute_resist,1))
|
||||
|
||||
health -= damage
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/effect/blob/proc/change_to(var/type)
|
||||
if(!ispath(type))
|
||||
error("[type] is an invalid type for the blob.")
|
||||
new type(src.loc)
|
||||
Delete()
|
||||
return
|
||||
|
||||
/obj/effect/blob/proc/Delete()
|
||||
del(src)
|
||||
|
||||
/obj/effect/blob/normal
|
||||
icon_state = "blob"
|
||||
luminosity = 0
|
||||
health = 21
|
||||
|
||||
Delete()
|
||||
src.loc = null
|
||||
blobs -= src
|
||||
/obj/effect/blob/normal/Delete()
|
||||
src.loc = null
|
||||
blobs -= src
|
||||
|
||||
update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
if(health <= 15)
|
||||
icon_state = "blob_damaged"
|
||||
return
|
||||
/obj/effect/blob/normal/update_icon()
|
||||
if(health <= 0)
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
Delete()
|
||||
return
|
||||
if(health <= 15)
|
||||
icon_state = "blob_damaged"
|
||||
return
|
||||
|
||||
/* // Used to create the glow sprites. Remember to set the animate loop to 1, instead of infinite!
|
||||
|
||||
var/datum/blob_colour/B = new()
|
||||
|
||||
/datum/blob_colour/New()
|
||||
..()
|
||||
var/icon/I = 'icons/mob/blob.dmi'
|
||||
I += rgb(35, 35, 0)
|
||||
if(isfile("icons/mob/blob_result.dmi"))
|
||||
fdel("icons/mob/blob_result.dmi")
|
||||
fcopy(I, "icons/mob/blob_result.dmi")
|
||||
|
||||
*/
|
||||
+13
-5
@@ -52,12 +52,20 @@ should be listed in the changelog upon commit tho. Thanks. -->
|
||||
|
||||
<!-- You can simply add changelogs using AddToChangelog.exe -->
|
||||
|
||||
<!-- DO NOT REMOVE OR MOVE THIS COMMENT! THIS MUST BE THE LAST NON-EMPTY LINE BEFORE THE LOGS #ADDTOCHANGELOGMARKER# -->
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- DO NOT REMOVE OR MOVE THIS COMMENT! THIS MUST BE THE LAST NON-EMPTY LINE BEFORE THE LOGS #ADDTOCHANGELOGMARKER# -->␍
|
||||
|
||||
<div class='commit sansserif'>
|
||||
<h2 class='date'>6 October 2013</h2>
|
||||
<h3 class='author'>Giacom updated:</h3>
|
||||
<ul class='changes bgimages16'>
|
||||
<li class='rscadd'>New blob features!</li>
|
||||
<li class='rscadd'>The blob will glow when it is being pulsed from a core/node. Resource/factories have depended on being pulsed to work, but you couldn't see; well now you can.</li>
|
||||
<li class='rscadd'>Overminds can talk! But only to other overminds, but ghosts can hear their conversations.</li>
|
||||
<li class='rscadd'>As a blob overmind you can now use shortcuts to help robust that assistant with the welding tank dangerously close to your core.</li>
|
||||
<li class='rscadd'>Expand = CTRL Click - Rally = Middle Mouse Click - Create Shield = Alt Click</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class='commit sansserif'>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 229 KiB After Width: | Height: | Size: 446 KiB |
@@ -42,6 +42,7 @@
|
||||
#include "code\_onclick\item_attack.dm"
|
||||
#include "code\_onclick\observer.dm"
|
||||
#include "code\_onclick\other_mobs.dm"
|
||||
#include "code\_onclick\overmind.dm"
|
||||
#include "code\_onclick\telekinesis.dm"
|
||||
#include "code\_onclick\hud\_defines.dm"
|
||||
#include "code\_onclick\hud\alien.dm"
|
||||
|
||||
Reference in New Issue
Block a user