mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Does something, likely to be important, to blob (#19831)
🆑 Joan rscadd: Once the blob alert message is sent in the blob game mode, all mobs get to see how many tiles the blob has until it wins, via the Status tab. rscdel: Removed/merged a bunch of blob chems, you probably don't care about the specifics. tweak: The remaining blob chems should, overall, be more powerful. tweak: Shield blobs soak brute damage less well. tweak: Flashbangs do higher damage to blobs up close, but their damage falls off faster. experiment: Shield blobs now cost 15 resources to make instead of 10. Node blobs now cost 50 resources to make instead of 60. experiment: Expanding/attacking now costs 4 resources instead of 5, and blobs can now ATTACK DIAGONALLY. Diagonal attacks are weaker than normal attacks, especially against cyborgs(which may be entirely immune, depending), and they remain unable to expand diagonally. rscadd: Shield blobs no longer block atmos while under half health. Shield blobs are still immune to fire, even if they can't block atmos. tweak: Blobs should block explosions less well. rscadd: Blob cores and nodes are no longer immune to fire and no longer block atmos. rscadd: Blobs can only auto-expand one tile at a time per expanding thing, and should be easier to beat back in general. tweak: Blobbernauts now attack faster. tweak: Blob Overminds attack mobs slower but can attack non-mobs much faster. rscadd: Blob Overminds start with some amount of resources; in the gamemode, it's 80 divided by the number of overminds, in the event, it's 20 plus the number of active players, and otherwise, it's 60. bugfix: You can no longer move blob cores into space, onto the mining shuttle, white ship, gulag shuttle, or solars. bugfix: Blob rounds might be less laggy, if they were laggy? tweak: Blobs don't heal as fast, excluding the core. experiment: Blobs are marginally less destructive to their environment. /🆑 Objective: maybe possibly make blob something you can fight instead of wishing the blob didn't exist? but also make the blob lethal enough that it can still deal with the crew if it knows what it's doing(and still lose if the crew is good instead of snowballing forever)
This commit is contained in:
@@ -152,6 +152,7 @@
|
|||||||
|
|
||||||
#define CLICK_CD_MELEE 8
|
#define CLICK_CD_MELEE 8
|
||||||
#define CLICK_CD_RANGE 4
|
#define CLICK_CD_RANGE 4
|
||||||
|
#define CLICK_CD_RAPID 2
|
||||||
#define CLICK_CD_CLICK_ABILITY 6
|
#define CLICK_CD_CLICK_ABILITY 6
|
||||||
#define CLICK_CD_BREAKOUT 100
|
#define CLICK_CD_BREAKOUT 100
|
||||||
#define CLICK_CD_HANDCUFFED 10
|
#define CLICK_CD_HANDCUFFED 10
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
/obj/screen/blob/Blobbernaut
|
/obj/screen/blob/Blobbernaut
|
||||||
icon_state = "ui_blobbernaut"
|
icon_state = "ui_blobbernaut"
|
||||||
name = "Produce Blobbernaut (40)"
|
name = "Produce Blobbernaut (40)"
|
||||||
desc = "Produces a strong, smart blobbernaut from a factory blob for 40 points.<br>The factory blob used will become fragile and unable to produce spores."
|
desc = "Produces a strong, smart blobbernaut from a factory blob for 40 resources.<br>The factory blob used will become fragile and unable to produce spores."
|
||||||
|
|
||||||
/obj/screen/blob/Blobbernaut/Click()
|
/obj/screen/blob/Blobbernaut/Click()
|
||||||
if(isovermind(usr))
|
if(isovermind(usr))
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
/obj/screen/blob/ResourceBlob
|
/obj/screen/blob/ResourceBlob
|
||||||
icon_state = "ui_resource"
|
icon_state = "ui_resource"
|
||||||
name = "Produce Resource Blob (40)"
|
name = "Produce Resource Blob (40)"
|
||||||
desc = "Produces a resource blob for 40 points.<br>Resource blobs will give you points every few seconds."
|
desc = "Produces a resource blob for 40 resources.<br>Resource blobs will give you resources every few seconds."
|
||||||
|
|
||||||
/obj/screen/blob/ResourceBlob/Click()
|
/obj/screen/blob/ResourceBlob/Click()
|
||||||
if(isovermind(usr))
|
if(isovermind(usr))
|
||||||
@@ -73,8 +73,8 @@
|
|||||||
|
|
||||||
/obj/screen/blob/NodeBlob
|
/obj/screen/blob/NodeBlob
|
||||||
icon_state = "ui_node"
|
icon_state = "ui_node"
|
||||||
name = "Produce Node Blob (60)"
|
name = "Produce Node Blob (50)"
|
||||||
desc = "Produces a node blob for 60 points.<br>Node blobs will expand and activate nearby resource and factory blobs."
|
desc = "Produces a node blob for 50 resources.<br>Node blobs will expand and activate nearby resource and factory blobs."
|
||||||
|
|
||||||
/obj/screen/blob/NodeBlob/Click()
|
/obj/screen/blob/NodeBlob/Click()
|
||||||
if(isovermind(usr))
|
if(isovermind(usr))
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
/obj/screen/blob/FactoryBlob
|
/obj/screen/blob/FactoryBlob
|
||||||
icon_state = "ui_factory"
|
icon_state = "ui_factory"
|
||||||
name = "Produce Factory Blob (60)"
|
name = "Produce Factory Blob (60)"
|
||||||
desc = "Produces a factory blob for 60 points.<br>Factory blobs will produce spores every few seconds."
|
desc = "Produces a factory blob for 60 resources.<br>Factory blobs will produce spores every few seconds."
|
||||||
|
|
||||||
/obj/screen/blob/FactoryBlob/Click()
|
/obj/screen/blob/FactoryBlob/Click()
|
||||||
if(isovermind(usr))
|
if(isovermind(usr))
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
/obj/screen/blob/ReadaptChemical
|
/obj/screen/blob/ReadaptChemical
|
||||||
icon_state = "ui_chemswap"
|
icon_state = "ui_chemswap"
|
||||||
name = "Readapt Chemical (40)"
|
name = "Readapt Chemical (40)"
|
||||||
desc = "Randomly rerolls your chemical for 40 points."
|
desc = "Randomly rerolls your chemical for 40 resources."
|
||||||
|
|
||||||
/obj/screen/blob/ReadaptChemical/MouseEntered(location,control,params)
|
/obj/screen/blob/ReadaptChemical/MouseEntered(location,control,params)
|
||||||
if(hud && hud.mymob && isovermind(hud.mymob))
|
if(hud && hud.mymob && isovermind(hud.mymob))
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
/obj/screen/blob/RelocateCore
|
/obj/screen/blob/RelocateCore
|
||||||
icon_state = "ui_swap"
|
icon_state = "ui_swap"
|
||||||
name = "Relocate Core (80)"
|
name = "Relocate Core (80)"
|
||||||
desc = "Swaps a node and your core for 80 points."
|
desc = "Swaps a node and your core for 80 resources."
|
||||||
|
|
||||||
/obj/screen/blob/RelocateCore/Click()
|
/obj/screen/blob/RelocateCore/Click()
|
||||||
if(isovermind(usr))
|
if(isovermind(usr))
|
||||||
@@ -159,11 +159,11 @@
|
|||||||
static_inventory += using
|
static_inventory += using
|
||||||
|
|
||||||
using = new /obj/screen/blob/NodeBlob()
|
using = new /obj/screen/blob/NodeBlob()
|
||||||
using.screen_loc = ui_lhand
|
using.screen_loc = ui_rhand
|
||||||
static_inventory += using
|
static_inventory += using
|
||||||
|
|
||||||
using = new /obj/screen/blob/FactoryBlob()
|
using = new /obj/screen/blob/FactoryBlob()
|
||||||
using.screen_loc = ui_rhand
|
using.screen_loc = ui_lhand
|
||||||
static_inventory += using
|
static_inventory += using
|
||||||
|
|
||||||
using = new /obj/screen/blob/ReadaptChemical()
|
using = new /obj/screen/blob/ReadaptChemical()
|
||||||
|
|||||||
@@ -139,27 +139,34 @@ var/list/teleportlocs = list()
|
|||||||
|
|
||||||
/area/shuttle/mining
|
/area/shuttle/mining
|
||||||
name = "Mining Shuttle"
|
name = "Mining Shuttle"
|
||||||
|
blob_allowed = FALSE
|
||||||
|
|
||||||
/area/shuttle/labor
|
/area/shuttle/labor
|
||||||
name = "Labor Camp Shuttle"
|
name = "Labor Camp Shuttle"
|
||||||
|
blob_allowed = FALSE
|
||||||
|
|
||||||
/area/shuttle/supply
|
/area/shuttle/supply
|
||||||
name = "Supply Shuttle"
|
name = "Supply Shuttle"
|
||||||
|
blob_allowed = FALSE
|
||||||
|
|
||||||
/area/shuttle/escape
|
/area/shuttle/escape
|
||||||
name = "Emergency Shuttle"
|
name = "Emergency Shuttle"
|
||||||
|
|
||||||
/area/shuttle/transport
|
/area/shuttle/transport
|
||||||
name = "Transport Shuttle"
|
name = "Transport Shuttle"
|
||||||
|
blob_allowed = FALSE
|
||||||
|
|
||||||
/area/shuttle/syndicate
|
/area/shuttle/syndicate
|
||||||
name = "Syndicate Infiltrator"
|
name = "Syndicate Infiltrator"
|
||||||
|
blob_allowed = FALSE
|
||||||
|
|
||||||
/area/shuttle/assault_pod
|
/area/shuttle/assault_pod
|
||||||
name = "Steel Rain"
|
name = "Steel Rain"
|
||||||
|
blob_allowed = FALSE
|
||||||
|
|
||||||
/area/shuttle/abandoned
|
/area/shuttle/abandoned
|
||||||
name = "Abandoned Ship"
|
name = "Abandoned Ship"
|
||||||
|
blob_allowed = FALSE
|
||||||
|
|
||||||
/area/start
|
/area/start
|
||||||
name = "start area"
|
name = "start area"
|
||||||
@@ -658,6 +665,7 @@ var/list/teleportlocs = list()
|
|||||||
luminosity = 1
|
luminosity = 1
|
||||||
lighting_use_dynamic = DYNAMIC_LIGHTING_IFSTARLIGHT
|
lighting_use_dynamic = DYNAMIC_LIGHTING_IFSTARLIGHT
|
||||||
valid_territory = 0
|
valid_territory = 0
|
||||||
|
blob_allowed = FALSE
|
||||||
|
|
||||||
/area/solar/auxport
|
/area/solar/auxport
|
||||||
name = "Fore Port Solar Array"
|
name = "Fore Port Solar Array"
|
||||||
|
|||||||
@@ -25,11 +25,12 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b
|
|||||||
<span class='green'>Blobs</span>: Consume the station and spread as far as you can.\n\
|
<span class='green'>Blobs</span>: Consume the station and spread as far as you can.\n\
|
||||||
<span class='notice'>Crew</span>: Fight back the blobs and minimize station damage."
|
<span class='notice'>Crew</span>: Fight back the blobs and minimize station damage."
|
||||||
|
|
||||||
var/burst = 0
|
var/message_sent = FALSE
|
||||||
|
|
||||||
var/cores_to_spawn = 1
|
var/cores_to_spawn = 1
|
||||||
var/players_per_core = 25
|
var/players_per_core = 25
|
||||||
var/blob_point_rate = 3
|
var/blob_point_rate = 3
|
||||||
|
var/blob_base_starting_points = 80
|
||||||
|
|
||||||
var/blobwincount = 350
|
var/blobwincount = 350
|
||||||
|
|
||||||
@@ -73,7 +74,8 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b
|
|||||||
/datum/game_mode/blob/post_setup()
|
/datum/game_mode/blob/post_setup()
|
||||||
|
|
||||||
for(var/datum/mind/blob in blob_overminds)
|
for(var/datum/mind/blob in blob_overminds)
|
||||||
var/mob/camera/blob/B = blob.current.become_overmind(1)
|
var/mob/camera/blob/B = blob.current.become_overmind(TRUE, round(blob_base_starting_points/blob_overminds.len))
|
||||||
|
B.mind.name = B.name
|
||||||
var/turf/T = pick(blobstart)
|
var/turf/T = pick(blobstart)
|
||||||
B.loc = T
|
B.loc = T
|
||||||
B.base_point_rate = blob_point_rate
|
B.base_point_rate = blob_point_rate
|
||||||
@@ -91,6 +93,7 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b
|
|||||||
sleep(message_delay)
|
sleep(message_delay)
|
||||||
|
|
||||||
send_intercept(1)
|
send_intercept(1)
|
||||||
|
message_sent = TRUE
|
||||||
|
|
||||||
sleep(24000) //40 minutes, plus burst_delay*3(minimum of 6 minutes, maximum of 8)
|
sleep(24000) //40 minutes, plus burst_delay*3(minimum of 6 minutes, maximum of 8)
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
/datum/game_mode/blob/check_finished()
|
/datum/game_mode/blob/check_finished()
|
||||||
if(blobwincount <= blobs_legit.len)//Blob took over
|
if(blobwincount <= blobs_legit.len)//Blob took over
|
||||||
return 1
|
return 1
|
||||||
if(overminds.len)
|
for(var/datum/mind/blob in blob_overminds)
|
||||||
return 0
|
if(isovermind(blob.current))
|
||||||
|
var/mob/camera/blob/B = blob.current
|
||||||
|
if(B.blob_core || !B.placed)
|
||||||
|
return 0
|
||||||
if(!blob_cores.len) //blob is dead
|
if(!blob_cores.len) //blob is dead
|
||||||
if(config.continuous["blob"])
|
if(config.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
|
continuous_sanity_checked = 1 //Nonstandard definition of "alive" gets past the check otherwise
|
||||||
SSshuttle.clearHostileEnvironment(src)
|
SSshuttle.clearHostileEnvironment(src)
|
||||||
return ..()
|
return ..()
|
||||||
@@ -18,23 +22,38 @@
|
|||||||
if(blobwincount <= blobs_legit.len)
|
if(blobwincount <= blobs_legit.len)
|
||||||
feedback_set_details("round_end_result","win - blob took over")
|
feedback_set_details("round_end_result","win - blob took over")
|
||||||
world << "<FONT size = 3><B>The blob has taken over the station!</B></FONT>"
|
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>"
|
world << "<B>The entire station was eaten by the Blob!</B>"
|
||||||
log_game("Blob mode completed with a blob victory.")
|
log_game("Blob mode completed with a blob victory.")
|
||||||
|
|
||||||
else if(station_was_nuked)
|
else if(station_was_nuked)
|
||||||
feedback_set_details("round_end_result","halfwin - nuke")
|
feedback_set_details("round_end_result","halfwin - nuke")
|
||||||
world << "<FONT size = 3><B>Partial Win: The station has been destroyed!</B></FONT>"
|
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>"
|
world << "<B>Directive 7-12 has been successfully carried out, preventing the Blob from spreading.</B>"
|
||||||
log_game("Blob mode completed with a tie (station destroyed).")
|
log_game("Blob mode completed with a tie (station destroyed).")
|
||||||
|
|
||||||
else if(!blob_cores.len)
|
else if(!blob_cores.len)
|
||||||
feedback_set_details("round_end_result","loss - blob eliminated")
|
feedback_set_details("round_end_result","loss - blob eliminated")
|
||||||
world << "<FONT size = 3><B>The staff has won!</B></FONT>"
|
world << "<FONT size = 3><B>The staff has won!</B></FONT>"
|
||||||
world << "<B>The alien organism has been eradicated from the station</B>"
|
world << "<B>The alien organism has been eradicated from the station!</B>"
|
||||||
log_game("Blob mode completed with a crew victory.")
|
log_game("Blob mode completed with a crew victory.")
|
||||||
..()
|
..()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
/datum/game_mode/blob/printplayer(datum/mind/ply, fleecheck)
|
||||||
|
if((ply in blob_overminds))
|
||||||
|
var/text = "<br><b>[ply.key]</b> was <b>[ply.name]</b>"
|
||||||
|
if(isovermind(ply.current))
|
||||||
|
var/mob/camera/blob/B = ply.current
|
||||||
|
text += "<b>(<font color=\"[B.blob_reagent_datum.color]\">[B.blob_reagent_datum.name]</font>)</b> and"
|
||||||
|
if(B.blob_core)
|
||||||
|
text += " <span class='greenannounce'>survived</span>"
|
||||||
|
else
|
||||||
|
text += " <span class='boldannounce'>was destroyed</span>"
|
||||||
|
else
|
||||||
|
text += " and <span class='boldannounce'>was destroyed</span>"
|
||||||
|
return text
|
||||||
|
return ..()
|
||||||
|
|
||||||
/datum/game_mode/proc/auto_declare_completion_blob()
|
/datum/game_mode/proc/auto_declare_completion_blob()
|
||||||
if(istype(ticker.mode,/datum/game_mode/blob) )
|
if(istype(ticker.mode,/datum/game_mode/blob) )
|
||||||
var/datum/game_mode/blob/blob_mode = src
|
var/datum/game_mode/blob/blob_mode = src
|
||||||
|
|||||||
@@ -168,20 +168,23 @@
|
|||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/mob/living/simple_animal/hostile/blob/blobspore/update_icons()
|
/mob/living/simple_animal/hostile/blob/blobspore/update_icons()
|
||||||
..()
|
if(overmind)
|
||||||
|
color = overmind.blob_reagent_datum.complementary_color
|
||||||
|
else
|
||||||
|
color = initial(color)
|
||||||
if(is_zombie)
|
if(is_zombie)
|
||||||
cut_overlays()
|
cut_overlays()
|
||||||
overlays = human_overlays
|
overlays = human_overlays
|
||||||
var/image/I = image('icons/mob/blob.dmi', icon_state = "blob_head")
|
var/image/I = image('icons/mob/blob.dmi', icon_state = "blob_head")
|
||||||
if(overmind)
|
if(overmind)
|
||||||
I.color = overmind.blob_reagent_datum.color
|
I.color = overmind.blob_reagent_datum.complementary_color
|
||||||
color = initial(color)//looks better.
|
color = initial(color)//looks better.
|
||||||
add_overlay(I)
|
add_overlay(I)
|
||||||
|
|
||||||
/mob/living/simple_animal/hostile/blob/blobspore/weak
|
/mob/living/simple_animal/hostile/blob/blobspore/weak
|
||||||
name = "fragile blob spore"
|
name = "fragile blob spore"
|
||||||
health = 20
|
health = 15
|
||||||
maxHealth = 20
|
maxHealth = 15
|
||||||
melee_damage_lower = 1
|
melee_damage_lower = 1
|
||||||
melee_damage_upper = 2
|
melee_damage_upper = 2
|
||||||
death_cloud_size = 0
|
death_cloud_size = 0
|
||||||
@@ -199,7 +202,6 @@
|
|||||||
health = 200
|
health = 200
|
||||||
maxHealth = 200
|
maxHealth = 200
|
||||||
damage_coeff = list(BRUTE = 0.5, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
|
damage_coeff = list(BRUTE = 0.5, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
|
||||||
next_move_modifier = 1.5 //slow-ass attack speed, 3 times higher than how fast the blob can attack
|
|
||||||
melee_damage_lower = 20
|
melee_damage_lower = 20
|
||||||
melee_damage_upper = 20
|
melee_damage_upper = 20
|
||||||
obj_damage = 20
|
obj_damage = 20
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
maxhealth = 400
|
maxhealth = 400
|
||||||
explosion_block = 6
|
explosion_block = 6
|
||||||
point_return = -1
|
point_return = -1
|
||||||
atmosblock = 1
|
|
||||||
health_regen = 0 //we regen in Life() instead of when pulsed
|
health_regen = 0 //we regen in Life() instead of when pulsed
|
||||||
var/core_regen = 2
|
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/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
|
||||||
@@ -50,7 +49,8 @@
|
|||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/obj/effect/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
/obj/effect/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||||
return
|
exposed_temperature *= 0.5
|
||||||
|
..()
|
||||||
|
|
||||||
/obj/effect/blob/core/ex_act(severity, target)
|
/obj/effect/blob/core/ex_act(severity, target)
|
||||||
var/damage = 50 - 10 * severity //remember, the core takes half brute damage, so this is 20/15/10 damage based on severity
|
var/damage = 50 - 10 * severity //remember, the core takes half brute damage, so this is 20/15/10 damage based on severity
|
||||||
|
|||||||
@@ -7,13 +7,12 @@
|
|||||||
maxhealth = 200
|
maxhealth = 200
|
||||||
health_regen = 3
|
health_regen = 3
|
||||||
point_return = 25
|
point_return = 25
|
||||||
atmosblock = 1
|
|
||||||
|
|
||||||
|
|
||||||
/obj/effect/blob/node/New(loc, var/h = 100)
|
/obj/effect/blob/node/New(loc)
|
||||||
blob_nodes += src
|
blob_nodes += src
|
||||||
START_PROCESSING(SSobj, src)
|
START_PROCESSING(SSobj, src)
|
||||||
..(loc, h)
|
..(loc)
|
||||||
|
|
||||||
/obj/effect/blob/node/scannerreport()
|
/obj/effect/blob/node/scannerreport()
|
||||||
return "Gradually expands and sustains nearby blob spores and blobbernauts."
|
return "Gradually expands and sustains nearby blob spores and blobbernauts."
|
||||||
@@ -28,14 +27,15 @@
|
|||||||
var/image/C = new('icons/mob/blob.dmi', "blob_node_overlay")
|
var/image/C = new('icons/mob/blob.dmi', "blob_node_overlay")
|
||||||
src.add_overlay(C)
|
src.add_overlay(C)
|
||||||
|
|
||||||
/obj/effect/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
|
||||||
return
|
|
||||||
|
|
||||||
/obj/effect/blob/node/Destroy()
|
/obj/effect/blob/node/Destroy()
|
||||||
blob_nodes -= src
|
blob_nodes -= src
|
||||||
STOP_PROCESSING(SSobj, src)
|
STOP_PROCESSING(SSobj, src)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||||
|
exposed_temperature *= 0.75
|
||||||
|
..()
|
||||||
|
|
||||||
/obj/effect/blob/node/Life()
|
/obj/effect/blob/node/Life()
|
||||||
Pulse_Area(overmind, 10, 3, 2)
|
Pulse_Area(overmind, 10, 3, 2)
|
||||||
color = null
|
color = null
|
||||||
|
|||||||
@@ -1,21 +1,37 @@
|
|||||||
/obj/effect/blob/shield
|
/obj/effect/blob/shield
|
||||||
name = "strong blob"
|
name = "strong blob"
|
||||||
icon = 'icons/mob/blob.dmi'
|
icon = 'icons/mob/blob.dmi'
|
||||||
icon_state = "blob_idle"
|
icon_state = "blob_shield"
|
||||||
desc = "A solid wall of slightly twitching tendrils."
|
desc = "A solid wall of slightly twitching tendrils."
|
||||||
health = 150
|
health = 150
|
||||||
maxhealth = 150
|
maxhealth = 150
|
||||||
brute_resist = 0.1
|
brute_resist = 0.25
|
||||||
explosion_block = 3
|
explosion_block = 3
|
||||||
point_return = 4
|
point_return = 4
|
||||||
atmosblock = 1
|
atmosblock = 1
|
||||||
|
|
||||||
|
|
||||||
/obj/effect/blob/shield/scannerreport()
|
/obj/effect/blob/shield/scannerreport()
|
||||||
return "Will prevent the spread of atmospheric changes."
|
if(atmosblock)
|
||||||
|
return "Will prevent the spread of atmospheric changes."
|
||||||
|
return "N/A"
|
||||||
|
|
||||||
/obj/effect/blob/shield/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
/obj/effect/blob/shield/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||||
return
|
return
|
||||||
|
|
||||||
/obj/effect/blob/shield/core
|
/obj/effect/blob/shield/core
|
||||||
point_return = 0
|
point_return = 0
|
||||||
|
|
||||||
|
/obj/effect/blob/shield/update_icon()
|
||||||
|
..()
|
||||||
|
if(health <= 75)
|
||||||
|
icon_state = "blob_shield_damaged"
|
||||||
|
name = "weakened strong blob"
|
||||||
|
desc = "A wall of twitching tendrils."
|
||||||
|
atmosblock = 0
|
||||||
|
else
|
||||||
|
icon_state = initial(icon_state)
|
||||||
|
name = initial(name)
|
||||||
|
desc = initial(desc)
|
||||||
|
atmosblock = 1
|
||||||
|
air_update_turf(1)
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
/mob/camera/blob
|
/mob/camera/blob
|
||||||
name = "Blob Overmind"
|
name = "Blob Overmind"
|
||||||
real_name = "Blob Overmind"
|
real_name = "Blob Overmind"
|
||||||
|
desc = "The overmind. It controls the blob."
|
||||||
icon = 'icons/mob/blob.dmi'
|
icon = 'icons/mob/blob.dmi'
|
||||||
icon_state = "marker"
|
icon_state = "marker"
|
||||||
|
mouse_opacity = 1
|
||||||
|
move_on_shuttle = 1
|
||||||
see_in_dark = 8
|
see_in_dark = 8
|
||||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||||
invisibility = INVISIBILITY_OBSERVER
|
invisibility = INVISIBILITY_OBSERVER
|
||||||
|
layer = FLY_LAYER
|
||||||
|
|
||||||
pass_flags = PASSBLOB
|
pass_flags = PASSBLOB
|
||||||
faction = list("blob")
|
faction = list("blob")
|
||||||
@@ -26,7 +29,8 @@
|
|||||||
var/manualplace_min_time = 600 //in deciseconds //a minute, to get bearings
|
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/autoplace_max_time = 3600 //six minutes, as long as should be needed
|
||||||
|
|
||||||
/mob/camera/blob/New(loc, pre_placed = 0, mode_made = 0)
|
/mob/camera/blob/New(loc, pre_placed = 0, mode_made = 0, starting_points = 60)
|
||||||
|
blob_points = starting_points
|
||||||
if(pre_placed) //we already have a core!
|
if(pre_placed) //we already have a core!
|
||||||
manualplace_min_time = 0
|
manualplace_min_time = 0
|
||||||
autoplace_max_time = 0
|
autoplace_max_time = 0
|
||||||
@@ -42,10 +46,9 @@
|
|||||||
name = new_name
|
name = new_name
|
||||||
real_name = new_name
|
real_name = new_name
|
||||||
last_attack = world.time
|
last_attack = world.time
|
||||||
var/list/possible_reagents = list()
|
var/datum/reagent/blob/BC = pick((subtypesof(/datum/reagent/blob)))
|
||||||
for(var/type in (subtypesof(/datum/reagent/blob)))
|
blob_reagent_datum = new BC
|
||||||
possible_reagents.Add(new type)
|
color = blob_reagent_datum.complementary_color
|
||||||
blob_reagent_datum = pick(possible_reagents)
|
|
||||||
if(blob_core)
|
if(blob_core)
|
||||||
blob_core.update_icon()
|
blob_core.update_icon()
|
||||||
|
|
||||||
@@ -70,18 +73,19 @@
|
|||||||
/mob/camera/blob/Destroy()
|
/mob/camera/blob/Destroy()
|
||||||
for(var/BL in blobs)
|
for(var/BL in blobs)
|
||||||
var/obj/effect/blob/B = BL
|
var/obj/effect/blob/B = BL
|
||||||
if(B.overmind == src)
|
if(B && B.overmind == src)
|
||||||
B.overmind = null
|
B.overmind = null
|
||||||
B.update_icon() //reset anything that was ours
|
B.update_icon() //reset anything that was ours
|
||||||
for(var/BLO in blob_mobs)
|
for(var/BLO in blob_mobs)
|
||||||
var/mob/living/simple_animal/hostile/blob/BM = BLO
|
var/mob/living/simple_animal/hostile/blob/BM = BLO
|
||||||
BM.overmind = null
|
if(BM)
|
||||||
BM.update_icons()
|
BM.overmind = null
|
||||||
|
BM.update_icons()
|
||||||
overminds -= src
|
overminds -= src
|
||||||
if(ghostimage)
|
if(ghostimage)
|
||||||
ghost_darkness_images -= ghostimage
|
ghost_darkness_images -= ghostimage
|
||||||
qdel(ghostimage)
|
qdel(ghostimage)
|
||||||
ghostimage = null;
|
ghostimage = null
|
||||||
updateallghostimages()
|
updateallghostimages()
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
@@ -91,6 +95,12 @@
|
|||||||
src << "<span class='notice'>You are the overmind!</span>"
|
src << "<span class='notice'>You are the overmind!</span>"
|
||||||
blob_help()
|
blob_help()
|
||||||
update_health_hud()
|
update_health_hud()
|
||||||
|
add_points(0)
|
||||||
|
|
||||||
|
/mob/camera/blob/examine(mob/user)
|
||||||
|
..()
|
||||||
|
if(blob_reagent_datum)
|
||||||
|
user << "Its chemical is <font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</font>."
|
||||||
|
|
||||||
/mob/camera/blob/update_health_hud()
|
/mob/camera/blob/update_health_hud()
|
||||||
if(blob_core)
|
if(blob_core)
|
||||||
@@ -100,9 +110,8 @@
|
|||||||
B.hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_core.health)]</font></div>"
|
B.hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_core.health)]</font></div>"
|
||||||
|
|
||||||
/mob/camera/blob/proc/add_points(points)
|
/mob/camera/blob/proc/add_points(points)
|
||||||
if(points != 0)
|
blob_points = Clamp(blob_points + points, 0, max_blob_points)
|
||||||
blob_points = Clamp(blob_points + points, 0, max_blob_points)
|
hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_points)]</font></div>"
|
||||||
hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(src.blob_points)]</font></div>"
|
|
||||||
|
|
||||||
/mob/camera/blob/say(message)
|
/mob/camera/blob/say(message)
|
||||||
if (!message)
|
if (!message)
|
||||||
@@ -150,6 +159,11 @@
|
|||||||
if(blob_core)
|
if(blob_core)
|
||||||
stat(null, "Core Health: [blob_core.health]")
|
stat(null, "Core Health: [blob_core.health]")
|
||||||
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
|
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
|
||||||
|
if(ticker && istype(ticker.mode, /datum/game_mode/blob))
|
||||||
|
var/datum/game_mode/blob/B = ticker.mode
|
||||||
|
stat(null, "Blobs to Win: [blobs_legit.len]/[B.blobwincount]")
|
||||||
|
else
|
||||||
|
stat(null, "Total Blobs: [blobs.len]")
|
||||||
if(free_chem_rerolls)
|
if(free_chem_rerolls)
|
||||||
stat(null, "You have [free_chem_rerolls] Free Chemical Reroll\s Remaining")
|
stat(null, "You have [free_chem_rerolls] Free Chemical Reroll\s Remaining")
|
||||||
if(!placed)
|
if(!placed)
|
||||||
@@ -170,6 +184,3 @@
|
|||||||
return 0
|
return 0
|
||||||
loc = NewLoc
|
loc = NewLoc
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
/mob/camera/blob/proc/can_attack()
|
|
||||||
return (world.time > (last_attack + CLICK_CD_RANGE))
|
|
||||||
|
|||||||
@@ -67,12 +67,13 @@
|
|||||||
set desc = "Move your camera to a selected node."
|
set desc = "Move your camera to a selected node."
|
||||||
if(blob_nodes.len)
|
if(blob_nodes.len)
|
||||||
var/list/nodes = list()
|
var/list/nodes = list()
|
||||||
for(var/i = 1; i <= blob_nodes.len; i++)
|
for(var/i in 1 to blob_nodes.len)
|
||||||
nodes["Blob Node #[i]"] = blob_nodes[i]
|
var/obj/effect/blob/node/B = blob_nodes[i]
|
||||||
|
nodes["Blob Node #[i] ([B.overmind ? "B.overmind.blob_reagent_datum.name":"No Chemical"]"] = B
|
||||||
var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes
|
var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes
|
||||||
var/obj/effect/blob/node/chosen_node = nodes[node_name]
|
var/obj/effect/blob/node/chosen_node = nodes[node_name]
|
||||||
if(chosen_node)
|
if(chosen_node)
|
||||||
src.loc = chosen_node.loc
|
loc = chosen_node.loc
|
||||||
|
|
||||||
/mob/camera/blob/proc/createSpecial(price, blobType, nearEquals, needsNode, turf/T)
|
/mob/camera/blob/proc/createSpecial(price, blobType, nearEquals, needsNode, turf/T)
|
||||||
if(!T)
|
if(!T)
|
||||||
@@ -110,12 +111,12 @@
|
|||||||
|
|
||||||
/mob/camera/blob/verb/create_shield_power()
|
/mob/camera/blob/verb/create_shield_power()
|
||||||
set category = "Blob"
|
set category = "Blob"
|
||||||
set name = "Create Shield Blob (10)"
|
set name = "Create Shield Blob (15)"
|
||||||
set desc = "Create a shield blob, which will block fire and is hard to kill."
|
set desc = "Create a shield blob, which will block fire and is hard to kill."
|
||||||
create_shield()
|
create_shield()
|
||||||
|
|
||||||
/mob/camera/blob/proc/create_shield(turf/T)
|
/mob/camera/blob/proc/create_shield(turf/T)
|
||||||
createSpecial(10, /obj/effect/blob/shield, 0, 0, T)
|
createSpecial(15, /obj/effect/blob/shield, 0, 0, T)
|
||||||
|
|
||||||
/mob/camera/blob/verb/create_resource()
|
/mob/camera/blob/verb/create_resource()
|
||||||
set category = "Blob"
|
set category = "Blob"
|
||||||
@@ -125,9 +126,9 @@
|
|||||||
|
|
||||||
/mob/camera/blob/verb/create_node()
|
/mob/camera/blob/verb/create_node()
|
||||||
set category = "Blob"
|
set category = "Blob"
|
||||||
set name = "Create Node Blob (60)"
|
set name = "Create Node Blob (50)"
|
||||||
set desc = "Create a node, which will power nearby factory and resource blobs."
|
set desc = "Create a node, which will power nearby factory and resource blobs."
|
||||||
createSpecial(60, /obj/effect/blob/node, 5, 0)
|
createSpecial(50, /obj/effect/blob/node, 5, 0)
|
||||||
|
|
||||||
/mob/camera/blob/verb/create_factory()
|
/mob/camera/blob/verb/create_factory()
|
||||||
set category = "Blob"
|
set category = "Blob"
|
||||||
@@ -166,9 +167,8 @@
|
|||||||
blobber.adjustHealth(blobber.maxHealth * 0.5)
|
blobber.adjustHealth(blobber.maxHealth * 0.5)
|
||||||
blob_mobs += blobber
|
blob_mobs += blobber
|
||||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
|
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
|
||||||
var/client/C = null
|
|
||||||
if(candidates.len) //if we got at least one candidate, they're a blobbernaut now.
|
if(candidates.len) //if we got at least one candidate, they're a blobbernaut now.
|
||||||
C = pick(candidates)
|
var/client/C = pick(candidates)
|
||||||
blobber.notransform = 0
|
blobber.notransform = 0
|
||||||
blobber.key = C.key
|
blobber.key = C.key
|
||||||
blobber << 'sound/effects/blobattack.ogg'
|
blobber << 'sound/effects/blobattack.ogg'
|
||||||
@@ -190,11 +190,21 @@
|
|||||||
if(!B)
|
if(!B)
|
||||||
src << "<span class='warning'>You must be on a blob node!</span>"
|
src << "<span class='warning'>You must be on a blob node!</span>"
|
||||||
return
|
return
|
||||||
|
if(!blob_core)
|
||||||
|
src << "<span class='userdanger'>You have no core and are about to die! May you rest in peace.</span>"
|
||||||
|
return
|
||||||
|
var/area/A = get_area(T)
|
||||||
|
if(istype(T, /turf/open/space) || A && !A.blob_allowed)
|
||||||
|
src << "<span class='warning'>You cannot relocate your core here!</span>"
|
||||||
|
return
|
||||||
if(!can_buy(80))
|
if(!can_buy(80))
|
||||||
return
|
return
|
||||||
var/turf/old_turf = blob_core.loc
|
var/turf/old_turf = get_turf(blob_core)
|
||||||
blob_core.loc = T
|
var/olddir = blob_core.dir
|
||||||
B.loc = old_turf
|
blob_core.forceMove(T)
|
||||||
|
blob_core.setDir(B.dir)
|
||||||
|
B.forceMove(old_turf)
|
||||||
|
B.setDir(olddir)
|
||||||
|
|
||||||
/mob/camera/blob/verb/revert()
|
/mob/camera/blob/verb/revert()
|
||||||
set category = "Blob"
|
set category = "Blob"
|
||||||
@@ -221,21 +231,22 @@
|
|||||||
|
|
||||||
/mob/camera/blob/verb/expand_blob_power()
|
/mob/camera/blob/verb/expand_blob_power()
|
||||||
set category = "Blob"
|
set category = "Blob"
|
||||||
set name = "Expand/Attack Blob (5)"
|
set name = "Expand/Attack Blob (4)"
|
||||||
set desc = "Attempts to create a new blob in this tile. If the tile isn't clear, instead attacks it, damaging mobs and objects."
|
set desc = "Attempts to create a new blob in this tile. If the tile isn't clear, instead attacks it, damaging mobs and objects."
|
||||||
var/turf/T = get_turf(src)
|
var/turf/T = get_turf(src)
|
||||||
expand_blob(T)
|
expand_blob(T)
|
||||||
|
|
||||||
/mob/camera/blob/proc/expand_blob(turf/T)
|
/mob/camera/blob/proc/expand_blob(turf/T)
|
||||||
if(!can_attack())
|
if(world.time > last_attack)
|
||||||
return
|
return
|
||||||
var/obj/effect/blob/OB = locate() in circlerange(T, 1)
|
var/list/possibleblobs = list()
|
||||||
if(!OB)
|
for(var/obj/effect/blob/AB in range(T, 1))
|
||||||
|
possibleblobs += AB
|
||||||
|
if(!possibleblobs.len)
|
||||||
src << "<span class='warning'>There is no blob adjacent to the target tile!</span>"
|
src << "<span class='warning'>There is no blob adjacent to the target tile!</span>"
|
||||||
return
|
return
|
||||||
if(can_buy(5))
|
if(can_buy(4))
|
||||||
var/attacksuccess = FALSE
|
var/attacksuccess = FALSE
|
||||||
last_attack = world.time
|
|
||||||
for(var/mob/living/L in T)
|
for(var/mob/living/L in T)
|
||||||
if("blob" in L.faction) //no friendly/dead fire
|
if("blob" in L.faction) //no friendly/dead fire
|
||||||
continue
|
continue
|
||||||
@@ -250,10 +261,31 @@
|
|||||||
B.blob_attack_animation(T, src)
|
B.blob_attack_animation(T, src)
|
||||||
else
|
else
|
||||||
src << "<span class='warning'>There is a blob there!</span>"
|
src << "<span class='warning'>There is a blob there!</span>"
|
||||||
add_points(5) //otherwise, refund all of the cost
|
add_points(4) //otherwise, refund all of the cost
|
||||||
return
|
|
||||||
else
|
else
|
||||||
OB.expand(T, src)
|
var/list/cardinalblobs = list()
|
||||||
|
var/list/diagonalblobs = list()
|
||||||
|
for(var/I in possibleblobs)
|
||||||
|
var/obj/effect/blob/IB = I
|
||||||
|
if(get_dir(IB, T) in cardinal)
|
||||||
|
cardinalblobs += IB
|
||||||
|
else
|
||||||
|
diagonalblobs += IB
|
||||||
|
var/obj/effect/blob/OB
|
||||||
|
if(cardinalblobs.len)
|
||||||
|
OB = pick(cardinalblobs)
|
||||||
|
OB.expand(T, src)
|
||||||
|
else
|
||||||
|
OB = pick(diagonalblobs)
|
||||||
|
if(attacksuccess)
|
||||||
|
OB.blob_attack_animation(T, src)
|
||||||
|
playsound(OB, 'sound/effects/splat.ogg', 50, 1)
|
||||||
|
else
|
||||||
|
add_points(4) //if we're attacking diagonally and didn't hit anything, refund
|
||||||
|
if(attacksuccess)
|
||||||
|
last_attack = world.time + CLICK_CD_MELEE
|
||||||
|
else
|
||||||
|
last_attack = world.time + CLICK_CD_RAPID
|
||||||
|
|
||||||
/mob/camera/blob/verb/rally_spores_power()
|
/mob/camera/blob/verb/rally_spores_power()
|
||||||
set category = "Blob"
|
set category = "Blob"
|
||||||
@@ -298,6 +330,7 @@
|
|||||||
/mob/camera/blob/proc/set_chemical()
|
/mob/camera/blob/proc/set_chemical()
|
||||||
var/datum/reagent/blob/BC = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type))
|
var/datum/reagent/blob/BC = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type))
|
||||||
blob_reagent_datum = new BC
|
blob_reagent_datum = new BC
|
||||||
|
color = blob_reagent_datum.complementary_color
|
||||||
for(var/BL in blobs)
|
for(var/BL in blobs)
|
||||||
var/obj/effect/blob/B = BL
|
var/obj/effect/blob/B = BL
|
||||||
B.update_icon()
|
B.update_icon()
|
||||||
@@ -308,6 +341,8 @@
|
|||||||
BM << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.shortdesc ? "[blob_reagent_datum.shortdesc]" : "[blob_reagent_datum.description]"]"
|
BM << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.shortdesc ? "[blob_reagent_datum.shortdesc]" : "[blob_reagent_datum.description]"]"
|
||||||
src << "Your reagent is now: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!"
|
src << "Your reagent is now: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!"
|
||||||
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.description]"
|
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.description]"
|
||||||
|
if(blob_reagent_datum.effectdesc)
|
||||||
|
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.effectdesc]"
|
||||||
|
|
||||||
/mob/camera/blob/verb/blob_help()
|
/mob/camera/blob/verb/blob_help()
|
||||||
set category = "Blob"
|
set category = "Blob"
|
||||||
@@ -316,6 +351,8 @@
|
|||||||
src << "<b>As the overmind, you can control the blob!</b>"
|
src << "<b>As the overmind, you can control the blob!</b>"
|
||||||
src << "Your blob reagent is: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!"
|
src << "Your blob reagent is: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!"
|
||||||
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.description]"
|
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.description]"
|
||||||
|
if(blob_reagent_datum.effectdesc)
|
||||||
|
src << "The <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font> reagent [blob_reagent_datum.effectdesc]"
|
||||||
src << "<b>You can expand, which will attack people, damage objects, or place a Normal Blob if the tile is clear.</b>"
|
src << "<b>You can expand, which will attack people, damage objects, or place a Normal Blob if the tile is clear.</b>"
|
||||||
src << "<i>Normal Blobs</i> will expand your reach and can be upgraded into special blobs that perform certain functions."
|
src << "<i>Normal Blobs</i> will expand your reach and can be upgraded into special blobs that perform certain functions."
|
||||||
src << "<b>You can upgrade normal blobs into the following types of blob:</b>"
|
src << "<b>You can upgrade normal blobs into the following types of blob:</b>"
|
||||||
@@ -329,4 +366,4 @@
|
|||||||
src << "Attempting to talk will send a message to all other overminds, allowing you to coordinate with them."
|
src << "Attempting to talk will send a message to all other overminds, allowing you to coordinate with them."
|
||||||
if(!placed && autoplace_max_time <= world.time)
|
if(!placed && autoplace_max_time <= world.time)
|
||||||
src << "<span class='big'><font color=\"#EE4000\">You will automatically place your blob core in [round((autoplace_max_time - world.time)/600, 0.5)] minutes.</font></span>"
|
src << "<span class='big'><font color=\"#EE4000\">You will automatically place your blob core in [round((autoplace_max_time - world.time)/600, 0.5)] minutes.</font></span>"
|
||||||
src << "<span class='big'><font color=\"#EE4000\">You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the button in the bottom right corner of the screen.</font></span>"
|
src << "<span class='big'><font color=\"#EE4000\">You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen.</font></span>"
|
||||||
|
|||||||
@@ -7,12 +7,13 @@
|
|||||||
density = 0 //this being 0 causes two bugs, being able to attack blob tiles behind other blobs and being unable to move on blob tiles in no gravity, but turning it to 1 causes the blob mobs to be unable to path through blobs, which is probably worse.
|
density = 0 //this being 0 causes two bugs, being able to attack blob tiles behind other blobs and being unable to move on blob tiles in no gravity, but turning it to 1 causes the blob mobs to be unable to path through blobs, which is probably worse.
|
||||||
opacity = 0
|
opacity = 0
|
||||||
anchored = 1
|
anchored = 1
|
||||||
explosion_block = 1
|
layer = BELOW_MOB_LAYER
|
||||||
var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed.
|
var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed.
|
||||||
var/health = 30
|
var/health = 30
|
||||||
var/maxhealth = 30
|
var/maxhealth = 30
|
||||||
var/health_regen = 2 //how much health this blob regens when pulsed
|
var/health_regen = 2 //how much health this blob regens when pulsed
|
||||||
var/pulse_timestamp = 0 //we got pulsed/healed when?
|
var/pulse_timestamp = 0 //we got pulsed when?
|
||||||
|
var/heal_timestamp = 0 //we got healed when?
|
||||||
var/brute_resist = 0.5 //multiplies brute damage by this
|
var/brute_resist = 0.5 //multiplies brute damage by this
|
||||||
var/fire_resist = 1 //multiplies burn damage by this
|
var/fire_resist = 1 //multiplies burn damage by this
|
||||||
var/atmosblock = 0 //if the blob blocks atmos and heat spread
|
var/atmosblock = 0 //if the blob blocks atmos and heat spread
|
||||||
@@ -24,8 +25,8 @@
|
|||||||
if(Ablob.blob_allowed) //Is this area allowed for winning as blob?
|
if(Ablob.blob_allowed) //Is this area allowed for winning as blob?
|
||||||
blobs_legit += src
|
blobs_legit += src
|
||||||
blobs += src //Keep track of the blob in the normal list either way
|
blobs += src //Keep track of the blob in the normal list either way
|
||||||
src.setDir(pick(1, 2, 4, 8))
|
setDir(pick(cardinal))
|
||||||
src.update_icon()
|
update_icon()
|
||||||
..(loc)
|
..(loc)
|
||||||
ConsumeTile()
|
ConsumeTile()
|
||||||
if(atmosblock)
|
if(atmosblock)
|
||||||
@@ -84,46 +85,56 @@
|
|||||||
if(overmind)
|
if(overmind)
|
||||||
overmind.blob_reagent_datum.death_reaction(src, cause)
|
overmind.blob_reagent_datum.death_reaction(src, cause)
|
||||||
qdel(src) //we dead now
|
qdel(src) //we dead now
|
||||||
return
|
|
||||||
return
|
|
||||||
|
|
||||||
/obj/effect/blob/update_icon() //Updates color based on overmind color if we have an overmind.
|
/obj/effect/blob/update_icon() //Updates color based on overmind color if we have an overmind.
|
||||||
if(overmind)
|
if(overmind)
|
||||||
color = overmind.blob_reagent_datum.color
|
color = overmind.blob_reagent_datum.color
|
||||||
else
|
else
|
||||||
color = null
|
color = null
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
/obj/effect/blob/process()
|
/obj/effect/blob/process()
|
||||||
Life()
|
Life()
|
||||||
return
|
|
||||||
|
|
||||||
/obj/effect/blob/proc/Life()
|
/obj/effect/blob/proc/Life()
|
||||||
return
|
return
|
||||||
|
|
||||||
/obj/effect/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
/obj/effect/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
||||||
src.Be_Pulsed()
|
src.Be_Pulsed()
|
||||||
if(claim_range)
|
var/expanded = FALSE
|
||||||
for(var/obj/effect/blob/B in urange(claim_range, src, 1))
|
if(prob(70) && expand())
|
||||||
if(!B.overmind && !istype(B, /obj/effect/blob/core) && prob(30))
|
expanded = TRUE
|
||||||
B.overmind = pulsing_overmind //reclaim unclaimed, non-core blobs.
|
var/list/blobs_to_affect = list()
|
||||||
B.update_icon()
|
for(var/obj/effect/blob/B in urange(claim_range, src, 1))
|
||||||
if(pulse_range)
|
blobs_to_affect += B
|
||||||
for(var/obj/effect/blob/B in orange(pulse_range, src))
|
shuffle(blobs_to_affect)
|
||||||
|
for(var/L in blobs_to_affect)
|
||||||
|
var/obj/effect/blob/B = L
|
||||||
|
if(!B.overmind && !istype(B, /obj/effect/blob/core) && prob(30))
|
||||||
|
B.overmind = pulsing_overmind //reclaim unclaimed, non-core blobs.
|
||||||
|
B.update_icon()
|
||||||
|
var/distance = get_dist(get_turf(src), get_turf(B))
|
||||||
|
var/expand_probablity = max(20 - distance * 8, 1)
|
||||||
|
if(B.Adjacent(src))
|
||||||
|
expand_probablity = 20
|
||||||
|
if(distance <= expand_range)
|
||||||
|
var/can_expand = TRUE
|
||||||
|
if(blobs_to_affect.len >= 120 && B.heal_timestamp > world.time)
|
||||||
|
can_expand = FALSE
|
||||||
|
if(can_expand && B.pulse_timestamp <= world.time && prob(expand_probablity))
|
||||||
|
var/obj/effect/blob/newB = B.expand(null, null, !expanded) //expansion falls off with range but is faster near the blob causing the expansion
|
||||||
|
if(newB)
|
||||||
|
if(expanded)
|
||||||
|
qdel(newB)
|
||||||
|
expanded = TRUE
|
||||||
|
if(distance <= pulse_range)
|
||||||
B.Be_Pulsed()
|
B.Be_Pulsed()
|
||||||
if(expand_range)
|
|
||||||
if(prob(85))
|
|
||||||
src.expand()
|
|
||||||
for(var/obj/effect/blob/B in orange(expand_range, src))
|
|
||||||
if(prob(max(13 - get_dist(get_turf(src), get_turf(B)) * 4, 1))) //expand falls off with range but is faster near the blob causing the expansion
|
|
||||||
B.expand()
|
|
||||||
return
|
|
||||||
|
|
||||||
/obj/effect/blob/proc/Be_Pulsed()
|
/obj/effect/blob/proc/Be_Pulsed()
|
||||||
if(pulse_timestamp <= world.time)
|
if(pulse_timestamp <= world.time)
|
||||||
ConsumeTile()
|
ConsumeTile()
|
||||||
health = min(maxhealth, health+health_regen)
|
if(heal_timestamp <= world.time)
|
||||||
|
health = min(maxhealth, health+health_regen)
|
||||||
|
heal_timestamp = world.time + 20
|
||||||
update_icon()
|
update_icon()
|
||||||
pulse_timestamp = world.time + 10
|
pulse_timestamp = world.time + 10
|
||||||
return 1 //we did it, we were pulsed!
|
return 1 //we did it, we were pulsed!
|
||||||
@@ -137,6 +148,7 @@
|
|||||||
|
|
||||||
/obj/effect/blob/proc/blob_attack_animation(atom/A = null, controller) //visually attacks an atom
|
/obj/effect/blob/proc/blob_attack_animation(atom/A = null, controller) //visually attacks an atom
|
||||||
var/obj/effect/overlay/temp/blob/O = PoolOrNew(/obj/effect/overlay/temp/blob, src.loc)
|
var/obj/effect/overlay/temp/blob/O = PoolOrNew(/obj/effect/overlay/temp/blob, src.loc)
|
||||||
|
O.setDir(dir)
|
||||||
if(controller)
|
if(controller)
|
||||||
var/mob/camera/blob/BO = controller
|
var/mob/camera/blob/BO = controller
|
||||||
O.color = BO.blob_reagent_datum.color
|
O.color = BO.blob_reagent_datum.color
|
||||||
@@ -311,6 +323,7 @@
|
|||||||
B.overmind = controller
|
B.overmind = controller
|
||||||
B.creation_action()
|
B.creation_action()
|
||||||
B.update_icon()
|
B.update_icon()
|
||||||
|
B.setDir(dir)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return B
|
return B
|
||||||
|
|
||||||
@@ -342,13 +355,13 @@
|
|||||||
brute_resist = 0.25
|
brute_resist = 0.25
|
||||||
|
|
||||||
/obj/effect/blob/normal/scannerreport()
|
/obj/effect/blob/normal/scannerreport()
|
||||||
if(health <= 10)
|
if(health <= 15)
|
||||||
return "Currently weak to brute damage."
|
return "Currently weak to brute damage."
|
||||||
return "N/A"
|
return "N/A"
|
||||||
|
|
||||||
/obj/effect/blob/normal/update_icon()
|
/obj/effect/blob/normal/update_icon()
|
||||||
..()
|
..()
|
||||||
if(health <= 10)
|
if(health <= 15)
|
||||||
icon_state = "blob_damaged"
|
icon_state = "blob_damaged"
|
||||||
name = "fragile blob"
|
name = "fragile blob"
|
||||||
desc = "A thin lattice of slightly twitching tendrils."
|
desc = "A thin lattice of slightly twitching tendrils."
|
||||||
|
|||||||
@@ -89,14 +89,6 @@
|
|||||||
open_machine()
|
open_machine()
|
||||||
..(severity)
|
..(severity)
|
||||||
|
|
||||||
/obj/machinery/sleeper/blob_act(obj/effect/blob/B)
|
|
||||||
if(prob(75))
|
|
||||||
var/turf/T = get_turf(src)
|
|
||||||
for(var/atom/movable/A in src)
|
|
||||||
A.forceMove(T)
|
|
||||||
A.blob_act(B)
|
|
||||||
qdel(src)
|
|
||||||
|
|
||||||
/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user)
|
/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user)
|
||||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
|
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -106,6 +106,10 @@
|
|||||||
..()
|
..()
|
||||||
|
|
||||||
|
|
||||||
|
/obj/machinery/camera/blob_act(obj/effect/blob/B)
|
||||||
|
if(B && B.loc == loc)
|
||||||
|
take_damage(health, BRUTE, 0)
|
||||||
|
|
||||||
/obj/machinery/camera/ex_act(severity, target)
|
/obj/machinery/camera/ex_act(severity, target)
|
||||||
if(src.invuln)
|
if(src.invuln)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ obj/machinery/door/proc/try_to_crowbar(obj/item/I, mob/user)
|
|||||||
|
|
||||||
|
|
||||||
/obj/machinery/door/blob_act(obj/effect/blob/B)
|
/obj/machinery/door/blob_act(obj/effect/blob/B)
|
||||||
if(prob(40))
|
if(prob(60))
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
/obj/machinery/door/emp_act(severity)
|
/obj/machinery/door/emp_act(severity)
|
||||||
|
|||||||
@@ -189,9 +189,7 @@ Class Procs:
|
|||||||
update_icon()
|
update_icon()
|
||||||
|
|
||||||
/obj/machinery/blob_act(obj/effect/blob/B)
|
/obj/machinery/blob_act(obj/effect/blob/B)
|
||||||
if(!density)
|
if(density && prob(75))
|
||||||
qdel(src)
|
|
||||||
if(prob(75))
|
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
/obj/machinery/proc/auto_use_power()
|
/obj/machinery/proc/auto_use_power()
|
||||||
|
|||||||
@@ -118,7 +118,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
|
|||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/obj/item/blob_act(obj/effect/blob/B)
|
/obj/item/blob_act(obj/effect/blob/B)
|
||||||
qdel(src)
|
if(B && B.loc == loc)
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
/obj/item/ex_act(severity, target)
|
/obj/item/ex_act(severity, target)
|
||||||
if(severity == 1 || target == src)
|
if(severity == 1 || target == src)
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
bang(get_turf(M), M)
|
bang(get_turf(M), M)
|
||||||
|
|
||||||
for(var/obj/effect/blob/B in get_hear(8,flashbang_turf)) //Blob damage here
|
for(var/obj/effect/blob/B in get_hear(8,flashbang_turf)) //Blob damage here
|
||||||
var/damage = round(40/(get_dist(B,get_turf(src))+1))
|
var/distance = get_dist(B, get_turf(src))
|
||||||
|
var/damage = round(100/(distance*distance)+1)
|
||||||
B.take_damage(damage, BURN)
|
B.take_damage(damage, BURN)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
|
|||||||
@@ -92,12 +92,12 @@
|
|||||||
user << "<span class='notice'>It feels [descriptive].</span>"
|
user << "<span class='notice'>It feels [descriptive].</span>"
|
||||||
|
|
||||||
/obj/item/weapon/tank/blob_act(obj/effect/blob/B)
|
/obj/item/weapon/tank/blob_act(obj/effect/blob/B)
|
||||||
if(prob(50))
|
if(B && B.loc == loc)
|
||||||
var/turf/location = src.loc
|
var/turf/location = get_turf(src)
|
||||||
if (!( istype(location, /turf) ))
|
if(!location)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
if(src.air_contents)
|
if(air_contents)
|
||||||
location.assume_air(air_contents)
|
location.assume_air(air_contents)
|
||||||
|
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|||||||
@@ -16,9 +16,7 @@
|
|||||||
cameranet.updateVisibility(src)
|
cameranet.updateVisibility(src)
|
||||||
|
|
||||||
/obj/structure/blob_act(obj/effect/blob/B)
|
/obj/structure/blob_act(obj/effect/blob/B)
|
||||||
if(!density)
|
if(density && prob(50))
|
||||||
qdel(src)
|
|
||||||
if(prob(50))
|
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
/obj/structure/Destroy()
|
/obj/structure/Destroy()
|
||||||
|
|||||||
@@ -208,10 +208,6 @@
|
|||||||
visible_message("<span class='danger'>[user] destroys \the [src].</span>")
|
visible_message("<span class='danger'>[user] destroys \the [src].</span>")
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
/obj/structure/closet/blob_act(obj/effect/blob/B)
|
|
||||||
if(prob(75))
|
|
||||||
qdel(src)
|
|
||||||
|
|
||||||
/obj/structure/closet/attackby(obj/item/weapon/W, mob/user, params)
|
/obj/structure/closet/attackby(obj/item/weapon/W, mob/user, params)
|
||||||
if(user in src)
|
if(user in src)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -49,10 +49,7 @@
|
|||||||
showpiece = null
|
showpiece = null
|
||||||
|
|
||||||
/obj/structure/displaycase/blob_act(obj/effect/blob/B)
|
/obj/structure/displaycase/blob_act(obj/effect/blob/B)
|
||||||
if (prob(75))
|
take_damage(30)
|
||||||
new /obj/item/weapon/shard( src.loc )
|
|
||||||
dump()
|
|
||||||
qdel(src)
|
|
||||||
|
|
||||||
/obj/structure/displaycase/hitby(atom/movable/AM)
|
/obj/structure/displaycase/hitby(atom/movable/AM)
|
||||||
..()
|
..()
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
|
|
||||||
/obj/structure/fireaxecabinet/blob_act(obj/effect/blob/B)
|
/obj/structure/fireaxecabinet/blob_act(obj/effect/blob/B)
|
||||||
if(fireaxe)
|
if(fireaxe)
|
||||||
fireaxe.loc = src.loc
|
fireaxe.forceMove(loc)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
/obj/structure/fireaxecabinet/attack_hand(mob/user)
|
/obj/structure/fireaxecabinet/attack_hand(mob/user)
|
||||||
|
|||||||
@@ -32,7 +32,8 @@
|
|||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
/obj/structure/grille/blob_act(obj/effect/blob/B)
|
/obj/structure/grille/blob_act(obj/effect/blob/B)
|
||||||
qdel(src)
|
if(!destroyed)
|
||||||
|
Break()
|
||||||
|
|
||||||
/obj/structure/grille/Bumped(atom/user)
|
/obj/structure/grille/Bumped(atom/user)
|
||||||
if(ismob(user))
|
if(ismob(user))
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
/obj/structure/sign/blob_act(obj/effect/blob/B)
|
/obj/structure/sign/blob_act(obj/effect/blob/B)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
|
||||||
|
|
||||||
/obj/structure/sign/attackby(obj/item/O, mob/user, params)
|
/obj/structure/sign/attackby(obj/item/O, mob/user, params)
|
||||||
if(istype(O, /obj/item/weapon/wrench))
|
if(istype(O, /obj/item/weapon/wrench))
|
||||||
|
|||||||
@@ -54,8 +54,7 @@
|
|||||||
take_damage(rand(40,80), BRUTE, 0)
|
take_damage(rand(40,80), BRUTE, 0)
|
||||||
|
|
||||||
/obj/structure/table/blob_act(obj/effect/blob/B)
|
/obj/structure/table/blob_act(obj/effect/blob/B)
|
||||||
if(prob(75))
|
take_damage(rand(75,150), BRUTE, 0)
|
||||||
qdel(src)
|
|
||||||
|
|
||||||
/obj/structure/table/narsie_act()
|
/obj/structure/table/narsie_act()
|
||||||
if(prob(20))
|
if(prob(20))
|
||||||
@@ -462,10 +461,7 @@
|
|||||||
take_damage(rand(5,25), BRUTE, 0)
|
take_damage(rand(5,25), BRUTE, 0)
|
||||||
|
|
||||||
/obj/structure/rack/blob_act(obj/effect/blob/B)
|
/obj/structure/rack/blob_act(obj/effect/blob/B)
|
||||||
if(prob(75))
|
rack_destroy()
|
||||||
qdel(src)
|
|
||||||
else
|
|
||||||
rack_destroy()
|
|
||||||
|
|
||||||
|
|
||||||
/obj/structure/rack/mech_melee_attack(obj/mecha/M)
|
/obj/structure/rack/mech_melee_attack(obj/mecha/M)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
take_damage(rand(25,75), BRUTE, 0)
|
take_damage(rand(25,75), BRUTE, 0)
|
||||||
|
|
||||||
/obj/structure/window/blob_act(obj/effect/blob/B)
|
/obj/structure/window/blob_act(obj/effect/blob/B)
|
||||||
shatter()
|
take_damage(rand(75,150), BRUTE, 0)
|
||||||
|
|
||||||
/obj/structure/window/narsie_act()
|
/obj/structure/window/narsie_act()
|
||||||
color = NARSIE_WINDOW_COLOUR
|
color = NARSIE_WINDOW_COLOUR
|
||||||
|
|||||||
@@ -92,10 +92,10 @@
|
|||||||
message_admins("[key_name_admin(usr)] tried to create a death squad. Unfortunately, there were not enough candidates available.")
|
message_admins("[key_name_admin(usr)] tried to create a death squad. Unfortunately, there were not enough candidates available.")
|
||||||
log_admin("[key_name(usr)] failed to create a death squad.")
|
log_admin("[key_name(usr)] failed to create a death squad.")
|
||||||
if("blob")
|
if("blob")
|
||||||
var/strength = input("Set Blob Strength (1=Weak, 2=Strong, 3=Full)","Set Strength",1) as num
|
var/strength = input("Set Blob Resource Gain Rate","Set Resource Rate",1) as num
|
||||||
message_admins("[key_name(usr)] spawned a blob with strength [strength].")
|
message_admins("[key_name(usr)] spawned a blob with base resource gain [strength].")
|
||||||
log_admin("[key_name(usr)] spawned a blob with strength [strength].")
|
log_admin("[key_name(usr)] spawned a blob with base resource gain [strength].")
|
||||||
new/datum/round_event/blob(strength)
|
new/datum/round_event/ghost_role/blob(TRUE, strength)
|
||||||
if("gangs")
|
if("gangs")
|
||||||
if(src.makeGangsters())
|
if(src.makeGangsters())
|
||||||
message_admins("[key_name(usr)] created gangs.")
|
message_admins("[key_name(usr)] created gangs.")
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
|||||||
log_admin("[key_name(src)] has blobized [M.key].")
|
log_admin("[key_name(src)] has blobized [M.key].")
|
||||||
var/mob/living/carbon/human/H = M
|
var/mob/living/carbon/human/H = M
|
||||||
spawn(0)
|
spawn(0)
|
||||||
var/mob/camera/blob/B = H.become_overmind()
|
var/mob/camera/blob/B = H.become_overmind(FALSE)
|
||||||
B.place_blob_core(B.base_point_rate, -1) //place them wherever they are
|
B.place_blob_core(B.base_point_rate, -1) //place them wherever they are
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/datum/round_event_control/blob
|
/datum/round_event_control/blob
|
||||||
name = "Blob"
|
name = "Blob"
|
||||||
typepath = /datum/round_event/blob
|
typepath = /datum/round_event/ghost_role/blob
|
||||||
weight = 5
|
weight = 5
|
||||||
max_occurrences = 1
|
max_occurrences = 1
|
||||||
|
|
||||||
@@ -9,22 +9,29 @@
|
|||||||
|
|
||||||
gamemode_blacklist = list("blob") //Just in case a blob survives that long
|
gamemode_blacklist = list("blob") //Just in case a blob survives that long
|
||||||
|
|
||||||
/datum/round_event/blob
|
/datum/round_event/ghost_role/blob
|
||||||
announceWhen = 12
|
announceWhen = 12
|
||||||
endWhen = 120
|
|
||||||
var/new_rate = 2
|
var/new_rate = 2
|
||||||
|
|
||||||
/datum/round_event/blob/New(var/strength)
|
/datum/round_event/ghost_role/blob/New(my_processing = TRUE, set_point_rate)
|
||||||
..()
|
..()
|
||||||
if(strength)
|
if(set_point_rate)
|
||||||
new_rate = strength
|
new_rate = set_point_rate
|
||||||
|
|
||||||
/datum/round_event/blob/announce()
|
/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')
|
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/blob/start()
|
/datum/round_event/ghost_role/blob/spawn_role()
|
||||||
var/turf/T = pick(blobstart)
|
if(!blobstart.len)
|
||||||
if(!T)
|
return MAP_ERROR
|
||||||
return kill()
|
var/list/candidates = get_candidates("blob", null, ROLE_BLOB)
|
||||||
new/obj/effect/blob/core(T, null, new_rate)
|
if(!candidates.len)
|
||||||
|
return NOT_ENOUGH_PLAYERS
|
||||||
|
var/mob/dead/observer/new_blob = pick(candidates)
|
||||||
|
var/obj/effect/blob/core/BC = new/obj/effect/blob/core(pick(blobstart), new_blob.client, new_rate)
|
||||||
|
BC.overmind.blob_points = min(20 + player_list.len, BC.overmind.max_blob_points)
|
||||||
|
spawned_mobs += BC.overmind
|
||||||
|
message_admins("[BC.overmind.key] has been made into a blob overmind by an event.")
|
||||||
|
log_game("[BC.overmind.key] was spawned as a blob overmind by an event.")
|
||||||
|
return SUCCESSFUL_SPAWN
|
||||||
|
|||||||
@@ -297,11 +297,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
|||||||
..()
|
..()
|
||||||
if(statpanel("Status"))
|
if(statpanel("Status"))
|
||||||
stat(null, "Station Time: [worldtime2text()]")
|
stat(null, "Station Time: [worldtime2text()]")
|
||||||
if(ticker)
|
if(ticker && ticker.mode)
|
||||||
if(ticker.mode)
|
for(var/datum/gang/G in ticker.mode.gangs)
|
||||||
for(var/datum/gang/G in ticker.mode.gangs)
|
if(G.is_dominating)
|
||||||
if(G.is_dominating)
|
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
if(istype(ticker.mode, /datum/game_mode/blob))
|
||||||
|
var/datum/game_mode/blob/B = ticker.mode
|
||||||
|
if(B.message_sent)
|
||||||
|
stat(null, "Blobs to Blob Win: [blobs_legit.len]/[B.blobwincount]")
|
||||||
|
|
||||||
/mob/dead/observer/verb/reenter_corpse()
|
/mob/dead/observer/verb/reenter_corpse()
|
||||||
set category = "Ghost"
|
set category = "Ghost"
|
||||||
|
|||||||
@@ -953,12 +953,16 @@ Sorry Giacom. Please don't be mad :(
|
|||||||
|
|
||||||
/mob/living/Stat()
|
/mob/living/Stat()
|
||||||
..()
|
..()
|
||||||
|
|
||||||
if(statpanel("Status"))
|
if(statpanel("Status"))
|
||||||
if(ticker)
|
if(ticker && ticker.mode)
|
||||||
if(ticker.mode)
|
for(var/datum/gang/G in ticker.mode.gangs)
|
||||||
for(var/datum/gang/G in ticker.mode.gangs)
|
if(G.is_dominating)
|
||||||
if(G.is_dominating)
|
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
if(istype(ticker.mode, /datum/game_mode/blob))
|
||||||
|
var/datum/game_mode/blob/B = ticker.mode
|
||||||
|
if(B.message_sent)
|
||||||
|
stat(null, "Blobs to Blob Win: [blobs_legit.len]/[B.blobwincount]")
|
||||||
|
|
||||||
/mob/living/cancel_camera()
|
/mob/living/cancel_camera()
|
||||||
..()
|
..()
|
||||||
|
|||||||
@@ -594,7 +594,7 @@ var/next_mob_id = 0
|
|||||||
|
|
||||||
if(statpanel("Status"))
|
if(statpanel("Status"))
|
||||||
stat(null, "Map: [MAP_NAME]")
|
stat(null, "Map: [MAP_NAME]")
|
||||||
if (nextmap && istype(nextmap))
|
if(nextmap && istype(nextmap))
|
||||||
stat(null, "Next Map: [nextmap.friendlyname]")
|
stat(null, "Next Map: [nextmap.friendlyname]")
|
||||||
stat(null, "Server Time: [time2text(world.realtime, "YYYY-MM-DD hh:mm")]")
|
stat(null, "Server Time: [time2text(world.realtime, "YYYY-MM-DD hh:mm")]")
|
||||||
if(SSshuttle.emergency)
|
if(SSshuttle.emergency)
|
||||||
|
|||||||
@@ -422,8 +422,8 @@
|
|||||||
. = new_slime
|
. = new_slime
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
/mob/proc/become_overmind(mode_made = 0)
|
/mob/proc/become_overmind(mode_made, starting_points = 60)
|
||||||
var/mob/camera/blob/B = new /mob/camera/blob(loc, 0, mode_made)
|
var/mob/camera/blob/B = new /mob/camera/blob(loc, 0, mode_made, starting_points)
|
||||||
if(mind)
|
if(mind)
|
||||||
mind.transfer_to(B)
|
mind.transfer_to(B)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -91,20 +91,6 @@
|
|||||||
/obj/machinery/am_shielding/emp_act()//Immune due to not really much in the way of electronics.
|
/obj/machinery/am_shielding/emp_act()//Immune due to not really much in the way of electronics.
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/am_shielding/blob_act()
|
|
||||||
stability -= 20
|
|
||||||
if(prob(100-stability))
|
|
||||||
if(prob(10))//Might create a node
|
|
||||||
new /obj/effect/blob/node(src.loc,150)
|
|
||||||
else
|
|
||||||
new /obj/effect/blob(src.loc,60)
|
|
||||||
qdel(src)
|
|
||||||
return
|
|
||||||
check_stability()
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/am_shielding/ex_act(severity, target)
|
/obj/machinery/am_shielding/ex_act(severity, target)
|
||||||
stability -= (80 - (severity * 20))
|
stability -= (80 - (severity * 20))
|
||||||
check_stability()
|
check_stability()
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ By design, d1 is the smallest direction and d2 is the highest
|
|||||||
cable_list -= src //remove it from global cable list
|
cable_list -= src //remove it from global cable list
|
||||||
return ..() // then go ahead and delete the cable
|
return ..() // then go ahead and delete the cable
|
||||||
|
|
||||||
|
/obj/structure/cable/blob_act(obj/effect/blob/B)
|
||||||
|
if(invisibility != INVISIBILITY_MAXIMUM)
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
/obj/structure/cable/Deconstruct()
|
/obj/structure/cable/Deconstruct()
|
||||||
var/turf/T = loc
|
var/turf/T = loc
|
||||||
stored.loc = T
|
stored.loc = T
|
||||||
|
|||||||
@@ -116,6 +116,10 @@
|
|||||||
return
|
return
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
|
/obj/machinery/light_construct/blob_act(obj/effect/blob/B)
|
||||||
|
if(B && B.loc == loc)
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/light_construct/small
|
/obj/machinery/light_construct/small
|
||||||
name = "small light fixture frame"
|
name = "small light fixture frame"
|
||||||
@@ -522,6 +526,15 @@
|
|||||||
if(prob(25))
|
if(prob(25))
|
||||||
broken()
|
broken()
|
||||||
|
|
||||||
|
/obj/machinery/light/blob_act(obj/effect/blob/B)
|
||||||
|
if(B && B.loc == loc)
|
||||||
|
broken()
|
||||||
|
qdel(src)
|
||||||
|
else if(prob(50))
|
||||||
|
broken()
|
||||||
|
else
|
||||||
|
flicker()
|
||||||
|
|
||||||
// called when area power state changes
|
// called when area power state changes
|
||||||
/obj/machinery/light/power_change()
|
/obj/machinery/light/power_change()
|
||||||
var/area/A = get_area(src)
|
var/area/A = get_area(src)
|
||||||
|
|||||||
@@ -5,12 +5,20 @@
|
|||||||
color = "#FFFFFF"
|
color = "#FFFFFF"
|
||||||
var/complementary_color = "#000000" //a color that's complementary to the normal blob color
|
var/complementary_color = "#000000" //a color that's complementary to the normal blob color
|
||||||
var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects
|
var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects
|
||||||
|
var/effectdesc = null //any long, blob-tile specific effects
|
||||||
var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp."
|
var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp."
|
||||||
var/analyzerdesceffect = "N/A"
|
var/analyzerdesceffect = "N/A"
|
||||||
var/blobbernaut_message = "slams" //blobbernaut attack verb
|
var/blobbernaut_message = "slams" //blobbernaut attack verb
|
||||||
var/message = "The blob strikes you" //message sent to any mob hit by the blob
|
var/message = "The blob strikes you" //message sent to any mob hit by the blob
|
||||||
var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt
|
var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt
|
||||||
|
|
||||||
|
/datum/reagent/blob/proc/send_message(mob/living/M)
|
||||||
|
var/totalmessage = message
|
||||||
|
if(message_living && !issilicon(M))
|
||||||
|
totalmessage += message_living
|
||||||
|
totalmessage += "!"
|
||||||
|
M << "<span class='userdanger'>[totalmessage]</span>"
|
||||||
|
|
||||||
/datum/reagent/blob/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
|
if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
|
||||||
return 0 //the dead, and blob mobs, don't cause reactions
|
return 0 //the dead, and blob mobs, don't cause reactions
|
||||||
@@ -34,44 +42,13 @@
|
|||||||
/datum/reagent/blob/proc/emp_reaction(obj/effect/blob/B, severity) //when the blob is hit with an emp, do this
|
/datum/reagent/blob/proc/emp_reaction(obj/effect/blob/B, severity) //when the blob is hit with an emp, do this
|
||||||
return
|
return
|
||||||
|
|
||||||
//does low toxin damage, but creates fragile spores when expanding or killed by weak attacks
|
|
||||||
/datum/reagent/blob/sporing_pods
|
|
||||||
name = "Sporing Pods"
|
|
||||||
id = "sporing_pods"
|
|
||||||
description = "will do very low toxin damage and produce fragile spores when killed or on expanding."
|
|
||||||
shortdesc = "will do very low toxin damage."
|
|
||||||
analyzerdescdamage = "Does very low toxin damage."
|
|
||||||
analyzerdesceffect = "Produces spores when expanding and when killed."
|
|
||||||
color = "#E88D5D"
|
|
||||||
complementary_color = "#5DB8E8"
|
|
||||||
message_living = ", and you feel sick"
|
|
||||||
|
|
||||||
/datum/reagent/blob/sporing_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
|
||||||
M.apply_damage(0.2*reac_volume, TOX)
|
|
||||||
|
|
||||||
/datum/reagent/blob/sporing_pods/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
|
||||||
if(!isnull(cause) && damage <= 20 && original_health - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 30% chance of a shitty spore.
|
|
||||||
B.visible_message("<span class='warning'><b>A spore floats free of the blob!</b></span>")
|
|
||||||
var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc)
|
|
||||||
BS.overmind = B.overmind
|
|
||||||
BS.update_icons()
|
|
||||||
B.overmind.blob_mobs.Add(BS)
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
/datum/reagent/blob/sporing_pods/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
|
|
||||||
if(prob(12))
|
|
||||||
var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(T)
|
|
||||||
BS.overmind = B.overmind
|
|
||||||
BS.update_icons()
|
|
||||||
newB.overmind.blob_mobs.Add(BS)
|
|
||||||
|
|
||||||
//does brute damage but can replicate when damaged and has a chance of expanding again
|
//does brute damage but can replicate when damaged and has a chance of expanding again
|
||||||
/datum/reagent/blob/replicating_foam
|
/datum/reagent/blob/replicating_foam
|
||||||
name = "Replicating Foam"
|
name = "Replicating Foam"
|
||||||
id = "replicating_foam"
|
id = "replicating_foam"
|
||||||
description = "will do medium brute damage, take increased brute damage, and expand when burned."
|
description = "will do medium brute damage and occasionally expand again when expanding."
|
||||||
shortdesc = "will do medium brute damage."
|
shortdesc = "will do medium brute damage."
|
||||||
|
effectdesc = "will also expand when attacked with burn damage, but takes more brute damage."
|
||||||
analyzerdescdamage = "Does medium brute damage."
|
analyzerdescdamage = "Does medium brute damage."
|
||||||
analyzerdesceffect = "Expands when attacked with burn damage, will occasionally expand again when expanding, and is fragile to brute damage."
|
analyzerdesceffect = "Expands when attacked with burn damage, will occasionally expand again when expanding, and is fragile to brute damage."
|
||||||
color = "#7B5A57"
|
color = "#7B5A57"
|
||||||
@@ -79,13 +56,13 @@
|
|||||||
|
|
||||||
/datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
reac_volume = ..()
|
reac_volume = ..()
|
||||||
M.apply_damage(0.5*reac_volume, BRUTE)
|
M.apply_damage(0.7*reac_volume, BRUTE)
|
||||||
|
|
||||||
/datum/reagent/blob/replicating_foam/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
/datum/reagent/blob/replicating_foam/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||||
var/effectivedamage = damage
|
var/effectivedamage = damage
|
||||||
if(damage_type == BRUTE)
|
if(damage_type == BRUTE)
|
||||||
effectivedamage = damage * 2
|
effectivedamage = damage * 2
|
||||||
if(damage_type == BURN && effectivedamage > 0 && original_health - effectivedamage > 0 && prob(75))
|
if(damage_type == BURN && effectivedamage > 0 && original_health - effectivedamage > 0 && prob(60))
|
||||||
var/obj/effect/blob/newB = B.expand(null, null, 0)
|
var/obj/effect/blob/newB = B.expand(null, null, 0)
|
||||||
if(newB)
|
if(newB)
|
||||||
newB.health = original_health - effectivedamage
|
newB.health = original_health - effectivedamage
|
||||||
@@ -95,14 +72,14 @@
|
|||||||
|
|
||||||
/datum/reagent/blob/replicating_foam/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
|
/datum/reagent/blob/replicating_foam/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
|
||||||
if(prob(30))
|
if(prob(30))
|
||||||
newB.expand() //do it again!
|
newB.expand(null, null, 0) //do it again!
|
||||||
|
|
||||||
//does brute damage, shifts away when damaged
|
//does brute damage, shifts away when damaged
|
||||||
/datum/reagent/blob/shifting_fragments
|
/datum/reagent/blob/shifting_fragments
|
||||||
name = "Shifting Fragments"
|
name = "Shifting Fragments"
|
||||||
id = "shifting_fragments"
|
id = "shifting_fragments"
|
||||||
description = "will do medium brute damage and shift away from damage."
|
description = "will do medium brute damage."
|
||||||
shortdesc = "will do medium brute damage."
|
effectdesc = "will also cause blob parts to shift away when attacked."
|
||||||
analyzerdescdamage = "Does medium brute damage."
|
analyzerdescdamage = "Does medium brute damage."
|
||||||
analyzerdesceffect = "When attacked, may shift away from the attacker."
|
analyzerdesceffect = "When attacked, may shift away from the attacker."
|
||||||
color = "#C8963C"
|
color = "#C8963C"
|
||||||
@@ -110,18 +87,18 @@
|
|||||||
|
|
||||||
/datum/reagent/blob/shifting_fragments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/shifting_fragments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
reac_volume = ..()
|
reac_volume = ..()
|
||||||
M.apply_damage(0.6*reac_volume, BRUTE)
|
M.apply_damage(0.7*reac_volume, BRUTE)
|
||||||
|
|
||||||
/datum/reagent/blob/shifting_fragments/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
|
/datum/reagent/blob/shifting_fragments/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
|
||||||
if(istype(B, /obj/effect/blob/normal) || (istype(B, /obj/effect/blob/shield) && prob(20)))
|
if(istype(B, /obj/effect/blob/normal) || (istype(B, /obj/effect/blob/shield) && prob(25)))
|
||||||
newB.forceMove(get_turf(B))
|
newB.forceMove(get_turf(B))
|
||||||
B.forceMove(T)
|
B.forceMove(T)
|
||||||
|
|
||||||
/datum/reagent/blob/shifting_fragments/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
/datum/reagent/blob/shifting_fragments/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||||
if(cause && damage > 0 && original_health - damage > 0 && prob(40))
|
if(cause && damage > 0 && original_health - damage > 0 && prob(60-damage))
|
||||||
var/list/blobstopick = list()
|
var/list/blobstopick = list()
|
||||||
for(var/obj/effect/blob/OB in orange(1, B))
|
for(var/obj/effect/blob/OB in orange(1, B))
|
||||||
if((istype(OB, /obj/effect/blob/normal) || istype(OB, /obj/effect/blob/shield)) && OB.overmind && OB.overmind.blob_reagent_datum.id == B.overmind.blob_reagent_datum.id)
|
if((istype(OB, /obj/effect/blob/normal) || (istype(OB, /obj/effect/blob/shield) && prob(25))) && OB.overmind && OB.overmind.blob_reagent_datum.id == B.overmind.blob_reagent_datum.id)
|
||||||
blobstopick += OB //as long as the blob picked is valid; ie, a normal or shield blob that has the same chemical as we do, we can swap with it
|
blobstopick += OB //as long as the blob picked is valid; ie, a normal or shield blob that has the same chemical as we do, we can swap with it
|
||||||
if(blobstopick.len)
|
if(blobstopick.len)
|
||||||
var/obj/effect/blob/targeted = pick(blobstopick) //randomize the blob chosen, because otherwise it'd tend to the lower left
|
var/obj/effect/blob/targeted = pick(blobstopick) //randomize the blob chosen, because otherwise it'd tend to the lower left
|
||||||
@@ -130,103 +107,57 @@
|
|||||||
B.forceMove(T) //swap the blobs
|
B.forceMove(T) //swap the blobs
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
//does low burn and a lot of stamina damage, immune to tesla bolts, weak to EMP
|
//sets you on fire, does burn damage, explodes into flame when burnt, weak to water
|
||||||
/datum/reagent/blob/energized_fibers
|
/datum/reagent/blob/blazing_oil
|
||||||
name = "Energized Fibers"
|
name = "Blazing Oil"
|
||||||
id = "energized_fibers"
|
id = "blazing_oil"
|
||||||
description = "will do low burn and high stamina damage and conduct electricity, but is weak to EMPs."
|
description = "will do medium burn damage and set targets on fire."
|
||||||
shortdesc = "will do low burn and high stamina damage."
|
effectdesc = "will also release bursts of flame when burnt, but takes damage from water."
|
||||||
analyzerdescdamage = "Does low burn damage and massively drains stamina."
|
|
||||||
analyzerdesceffect = "Is immune to electricity and will easily conduct it, but is weak to EMPs."
|
|
||||||
color = "#EFD65A"
|
|
||||||
complementary_color = "#5A73EF"
|
|
||||||
blobbernaut_message = "shocks"
|
|
||||||
message_living = ", and you feel a strong tingling sensation"
|
|
||||||
|
|
||||||
/datum/reagent/blob/energized_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
|
||||||
M.apply_damage(0.6*reac_volume, BURN)
|
|
||||||
if(M)
|
|
||||||
M.adjustStaminaLoss(0.6*reac_volume)
|
|
||||||
|
|
||||||
/datum/reagent/blob/energized_fibers/tesla_reaction(obj/effect/blob/B, power)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/reagent/blob/energized_fibers/emp_reaction(obj/effect/blob/B, severity)
|
|
||||||
var/damage = rand(30, 50) - severity * rand(10, 15)
|
|
||||||
B.take_damage(damage, BURN)
|
|
||||||
|
|
||||||
//sets you on fire, does burn damage, weak to water
|
|
||||||
/datum/reagent/blob/boiling_oil
|
|
||||||
name = "Boiling Oil"
|
|
||||||
id = "boiling_oil"
|
|
||||||
description = "will do medium burn damage and set targets on fire, but is weak to water."
|
|
||||||
shortdesc = "will do medium burn damage and set targets on fire."
|
|
||||||
analyzerdescdamage = "Does medium burn damage and sets targets on fire."
|
analyzerdescdamage = "Does medium burn damage and sets targets on fire."
|
||||||
analyzerdesceffect = "Takes damage from water and other extinguishing liquids."
|
analyzerdesceffect = "Releases fire when burnt, but takes damage from water and other extinguishing liquids."
|
||||||
color = "#B68D00"
|
color = "#B68D00"
|
||||||
complementary_color = "#0029B6"
|
complementary_color = "#BE5532"
|
||||||
blobbernaut_message = "splashes"
|
blobbernaut_message = "splashes"
|
||||||
message = "The blob splashes you with burning oil"
|
message = "The blob splashes you with burning oil"
|
||||||
message_living = ", and you feel your skin char and melt"
|
message_living = ", and you feel your skin char and melt"
|
||||||
|
|
||||||
/datum/reagent/blob/boiling_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/blazing_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
reac_volume = ..()
|
reac_volume = ..()
|
||||||
M.adjust_fire_stacks(round(reac_volume/10))
|
M.adjust_fire_stacks(round(reac_volume/10))
|
||||||
M.IgniteMob()
|
M.IgniteMob()
|
||||||
if(M)
|
if(M)
|
||||||
M.apply_damage(0.6*reac_volume, BURN)
|
M.apply_damage(0.8*reac_volume, BURN)
|
||||||
if(iscarbon(M))
|
if(iscarbon(M))
|
||||||
M.emote("scream")
|
M.emote("scream")
|
||||||
|
|
||||||
/datum/reagent/blob/boiling_oil/extinguish_reaction(obj/effect/blob/B)
|
/datum/reagent/blob/blazing_oil/extinguish_reaction(obj/effect/blob/B)
|
||||||
B.take_damage(rand(1, 3), BURN)
|
B.take_damage(rand(1, 3), BURN)
|
||||||
|
|
||||||
//does burn and toxin damage, explodes into flame when hit with burn damage
|
/datum/reagent/blob/blazing_oil/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||||
/datum/reagent/blob/flammable_goo
|
|
||||||
name = "Flammable Goo"
|
|
||||||
id = "flammable_goo"
|
|
||||||
description = "will do medium burn and toxin damage, make targets flammable, and ignite when burned."
|
|
||||||
shortdesc = "will do medium burn and toxin damage, and make targets flammable."
|
|
||||||
analyzerdescdamage = "Does medium burn damage, medium toxin damage, and makes targets flammable."
|
|
||||||
analyzerdesceffect = "Releases bursts of flame when attacked with burn damage, but takes additional burn damage."
|
|
||||||
color = "#BE5532"
|
|
||||||
complementary_color = "#329BBE"
|
|
||||||
blobbernaut_message = "splashes"
|
|
||||||
message = "The blob splashes you with a thin goo"
|
|
||||||
message_living = ", and you smell a faint, sweet scent"
|
|
||||||
|
|
||||||
/datum/reagent/blob/flammable_goo/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
|
||||||
M.adjust_fire_stacks(round(reac_volume/8)) //apply, but don't ignite
|
|
||||||
M.apply_damage(0.4*reac_volume, TOX)
|
|
||||||
if(M)
|
|
||||||
M.apply_damage(0.4*reac_volume, BURN)
|
|
||||||
|
|
||||||
/datum/reagent/blob/flammable_goo/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
|
||||||
if(cause && damage_type == BURN)
|
if(cause && damage_type == BURN)
|
||||||
for(var/turf/open/T in range(1, B))
|
for(var/turf/open/T in range(1, B))
|
||||||
var/obj/effect/blob/C = locate() in T
|
var/obj/effect/blob/C = locate() in T
|
||||||
if(!(C && C.overmind && C.overmind.blob_reagent_datum.id == B.overmind.blob_reagent_datum.id) && prob(80))
|
if(!(C && C.overmind && C.overmind.blob_reagent_datum.id == B.overmind.blob_reagent_datum.id) && prob(80))
|
||||||
PoolOrNew(/obj/effect/hotspot, T)
|
PoolOrNew(/obj/effect/hotspot, T)
|
||||||
return damage * 1.5
|
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
//does toxin damage, targets think they're not hurt at all
|
//does toxin damage, hallucination, targets think they're not hurt at all
|
||||||
/datum/reagent/blob/regenerative_materia
|
/datum/reagent/blob/regenerative_materia
|
||||||
name = "Regenerative Materia"
|
name = "Regenerative Materia"
|
||||||
id = "regenerative_materia"
|
id = "regenerative_materia"
|
||||||
description = "will do low toxin damage and cause targets to believe they are fully healed."
|
description = "will do toxin damage and cause targets to believe they are fully healed."
|
||||||
analyzerdescdamage = "Does low toxin damage and injects a toxin that causes the target to believe they are fully healed."
|
analyzerdescdamage = "Does toxin damage and injects a toxin that causes the target to believe they are fully healed."
|
||||||
color = "#C8A5DC"
|
color = "#C8A5DC"
|
||||||
complementary_color = "#B9DCA5"
|
complementary_color = "#CD7794"
|
||||||
message_living = ", and you feel <i>alive</i>"
|
message_living = ", and you feel <i>alive</i>"
|
||||||
|
|
||||||
/datum/reagent/blob/regenerative_materia/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/regenerative_materia/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
reac_volume = ..()
|
reac_volume = ..()
|
||||||
|
M.adjust_drugginess(reac_volume)
|
||||||
if(M.reagents)
|
if(M.reagents)
|
||||||
M.reagents.add_reagent("regenerative_materia", 0.2*reac_volume)
|
M.reagents.add_reagent("regenerative_materia", 0.2*reac_volume)
|
||||||
M.apply_damage(0.5*reac_volume, TOX)
|
M.reagents.add_reagent("spore", 0.2*reac_volume)
|
||||||
|
M.apply_damage(0.7*reac_volume, TOX)
|
||||||
|
|
||||||
/datum/reagent/blob/regenerative_materia/on_mob_life(mob/living/M)
|
/datum/reagent/blob/regenerative_materia/on_mob_life(mob/living/M)
|
||||||
M.adjustToxLoss(1*REM)
|
M.adjustToxLoss(1*REM)
|
||||||
@@ -241,149 +172,110 @@
|
|||||||
N.hal_screwyhud = 0
|
N.hal_screwyhud = 0
|
||||||
..()
|
..()
|
||||||
|
|
||||||
//toxin, hallucination, and some bonus spore toxin
|
//kills sleeping targets and turns them into blob zombies, produces fragile spores when killed or on expanding
|
||||||
/datum/reagent/blob/hallucinogenic_nectar
|
/datum/reagent/blob/zombifying_pods
|
||||||
name = "Hallucinogenic Nectar"
|
name = "Zombifying Pods"
|
||||||
id = "hallucinogenic_nectar"
|
id = "zombifying_pods"
|
||||||
description = "will do low toxin damage, vivid hallucinations, and inject targets with toxins."
|
description = "will do very low toxin damage and harvest sleeping targets for additional resources and a blob zombie."
|
||||||
analyzerdescdamage = "Does low toxin damage and injects a toxin that causes vivid hallucinations and blurried vision."
|
effectdesc = "will also produce fragile spores when killed and on expanding."
|
||||||
color = "#CD7794"
|
shortdesc = "will do very low toxin damage and harvest sleeping targets for additional resources(for your overmind) and a blob zombie."
|
||||||
complementary_color = "#77CDB0"
|
analyzerdescdamage = "Does very low toxin damage and kills unconscious humans, turning them into blob zombies."
|
||||||
blobbernaut_message = "splashes"
|
analyzerdesceffect = "Produces spores when expanding and when killed."
|
||||||
message = "The blob splashes you with sticky nectar"
|
color = "#E88D5D"
|
||||||
message_living = ", and you feel really good"
|
complementary_color = "#823ABB"
|
||||||
|
|
||||||
/datum/reagent/blob/hallucinogenic_nectar/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
|
||||||
M.hallucination += reac_volume
|
|
||||||
M.adjust_drugginess(reac_volume)
|
|
||||||
|
|
||||||
if(M.reagents)
|
|
||||||
M.reagents.add_reagent("spore", 0.2*reac_volume)
|
|
||||||
M.apply_damage(0.5*reac_volume, TOX)
|
|
||||||
|
|
||||||
//kills sleeping targets and turns them into blob zombies
|
|
||||||
/datum/reagent/blob/zombifying_feelers
|
|
||||||
name = "Zombifying Feelers"
|
|
||||||
id = "zombifying_feelers"
|
|
||||||
description = "will do low toxin damage and turn sleeping targets into blob zombies."
|
|
||||||
analyzerdescdamage = "Does low toxin damage and kills unconscious humans, turning them into blob zombies."
|
|
||||||
color = "#828264"
|
|
||||||
complementary_color = "#646482"
|
|
||||||
message_living = ", and you feel tired"
|
message_living = ", and you feel tired"
|
||||||
|
|
||||||
/datum/reagent/blob/zombifying_feelers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/zombifying_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
reac_volume = ..()
|
reac_volume = ..()
|
||||||
|
M.apply_damage(0.6*reac_volume, TOX)
|
||||||
if(O && ishuman(M) && M.stat == UNCONSCIOUS)
|
if(O && ishuman(M) && M.stat == UNCONSCIOUS)
|
||||||
M.death() //sleeping in a fight? bad plan.
|
M.death() //sleeping in a fight? bad plan.
|
||||||
|
var/points = rand(5, 10)
|
||||||
var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M))
|
var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M))
|
||||||
BS.overmind = O
|
BS.overmind = O
|
||||||
BS.update_icons()
|
BS.update_icons()
|
||||||
O.blob_mobs.Add(BS)
|
O.blob_mobs.Add(BS)
|
||||||
BS.Zombify(M)
|
BS.Zombify(M)
|
||||||
if(M)
|
O.add_points(points)
|
||||||
M.apply_damage(0.4*reac_volume, TOX)
|
O << "<span class='notice'>Gained [points] resources from the zombification of [M].</span>"
|
||||||
|
|
||||||
//toxin, stamina, and some bonus spore toxin
|
/datum/reagent/blob/zombifying_pods/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||||
/datum/reagent/blob/envenomed_filaments
|
if(!isnull(cause) && damage <= 20 && original_health - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 20% chance of a shitty spore.
|
||||||
name = "Envenomed Filaments"
|
B.visible_message("<span class='warning'><b>A spore floats free of the blob!</b></span>")
|
||||||
id = "envenomed_filaments"
|
var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc)
|
||||||
description = "will do medium toxin and stamina damage, and inject targets with toxins."
|
BS.overmind = B.overmind
|
||||||
analyzerdescdamage = "Does medium toxin damage, drains stamina, and injects a weak toxin."
|
BS.update_icons()
|
||||||
color = "#9ACD32"
|
B.overmind.blob_mobs.Add(BS)
|
||||||
complementary_color = "#6532CD"
|
return ..()
|
||||||
message_living = ", and you feel sick and nauseated"
|
|
||||||
|
|
||||||
/datum/reagent/blob/envenomed_filaments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/zombifying_pods/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
|
||||||
reac_volume = ..()
|
if(prob(10))
|
||||||
if(M.reagents)
|
var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(T)
|
||||||
M.reagents.add_reagent("spore", 0.2*reac_volume)
|
BS.overmind = B.overmind
|
||||||
M.apply_damage(0.4*reac_volume, TOX)
|
BS.update_icons()
|
||||||
if(M)
|
newB.overmind.blob_mobs.Add(BS)
|
||||||
M.adjustStaminaLoss(0.4*reac_volume)
|
|
||||||
|
|
||||||
//does brute, fire, and toxin over a few seconds
|
//does tons of oxygen damage and a little stamina, immune to tesla bolts, weak to EMP
|
||||||
/datum/reagent/blob/poisonous_strands
|
/datum/reagent/blob/energized_jelly
|
||||||
name = "Poisonous Strands"
|
name = "Energized Jelly"
|
||||||
id = "poisonous_strands"
|
id = "energized_jelly"
|
||||||
description = "will inject targets with poison."
|
description = "will cause low stamina and high oxygen damage, and cause targets to be unable to breathe."
|
||||||
analyzerdescdamage = "Injects a highly lethal poison that will gradually liquify the target's internal organs."
|
effectdesc = "will also conduct electricity, but takes damage from EMPs."
|
||||||
color = "#7D6EB4"
|
analyzerdescdamage = "Does low stamina damage, high oxygen damage, and prevents targets from breathing."
|
||||||
complementary_color = "#A5B46E"
|
analyzerdesceffect = "Is immune to electricity and will easily conduct it, but is weak to EMPs."
|
||||||
blobbernaut_message = "injects"
|
color = "#EFD65A"
|
||||||
message_living = ", and you feel like your insides are melting"
|
complementary_color = "#00E5B1"
|
||||||
|
message_living = ", and you feel a horrible tingling sensation"
|
||||||
|
var/datum/effect_system/spark_spread/spark_system = new/datum/effect_system/spark_spread()
|
||||||
|
|
||||||
/datum/reagent/blob/poisonous_strands/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/energized_jelly/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
reac_volume = ..()
|
|
||||||
if(M.reagents)
|
|
||||||
M.reagents.add_reagent("poisonous_strands", 0.12*reac_volume)
|
|
||||||
|
|
||||||
/datum/reagent/blob/poisonous_strands/on_mob_life(mob/living/M)
|
|
||||||
M.adjustBruteLoss(1.5*REM)
|
|
||||||
M.adjustFireLoss(1.5*REM)
|
|
||||||
M.adjustToxLoss(1.5*REM)
|
|
||||||
..()
|
|
||||||
|
|
||||||
//does oxygen damage, randomly pushes or pulls targets
|
|
||||||
/datum/reagent/blob/cyclonic_grid
|
|
||||||
name = "Cyclonic Grid"
|
|
||||||
id = "cyclonic_grid"
|
|
||||||
description = "will cause high oxygen damage and randomly throw targets to or from it."
|
|
||||||
analyzerdescdamage = "Does high oxygen damage and randomly throws targets at or away from it."
|
|
||||||
color = "#9BCD9B"
|
|
||||||
complementary_color = "#CD9BCD"
|
|
||||||
message = "The blob blasts you with a gust of air"
|
|
||||||
message_living = ", and you can't catch your breath"
|
|
||||||
|
|
||||||
/datum/reagent/blob/cyclonic_grid/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
|
||||||
reagent_vortex(M, rand(0, 1), reac_volume)
|
|
||||||
M.losebreath += round(0.05*reac_volume)
|
|
||||||
M.apply_damage(0.6*reac_volume, OXY)
|
|
||||||
|
|
||||||
//does tons of oxygen damage and a little brute
|
|
||||||
/datum/reagent/blob/lexorin_jelly
|
|
||||||
name = "Lexorin Jelly"
|
|
||||||
id = "lexorin_jelly"
|
|
||||||
description = "will cause low brute and high oxygen damage, and cause targets to be unable to breathe."
|
|
||||||
analyzerdescdamage = "Does low brute damage, high oxygen damage, and prevents targets from breathing."
|
|
||||||
color = "#00E5B1"
|
|
||||||
complementary_color = "#E50034"
|
|
||||||
message_living = ", and your lungs feel heavy and weak"
|
|
||||||
|
|
||||||
/datum/reagent/blob/lexorin_jelly/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
reac_volume = ..()
|
||||||
M.losebreath += round(0.2*reac_volume)
|
M.losebreath += round(0.2*reac_volume)
|
||||||
M.apply_damage(0.2*reac_volume, BRUTE)
|
M.adjustStaminaLoss(0.4*reac_volume)
|
||||||
if(M)
|
if(M)
|
||||||
M.apply_damage(0.6*reac_volume, OXY)
|
M.apply_damage(0.6*reac_volume, OXY)
|
||||||
|
|
||||||
|
/datum/reagent/blob/energized_jelly/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||||
|
if(!isnull(cause) && original_health - damage <= 0 && prob(10))
|
||||||
|
spark_system.set_up(rand(2, 4), 0, B)
|
||||||
|
spark_system.start()
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/reagent/blob/energized_jelly/tesla_reaction(obj/effect/blob/B, power)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
/datum/reagent/blob/energized_jelly/emp_reaction(obj/effect/blob/B, severity)
|
||||||
|
var/damage = rand(30, 50) - severity * rand(10, 15)
|
||||||
|
B.take_damage(damage, BURN)
|
||||||
|
|
||||||
//does aoe brute damage when hitting targets, is immune to explosions
|
//does aoe brute damage when hitting targets, is immune to explosions
|
||||||
/datum/reagent/blob/explosive_lattice
|
/datum/reagent/blob/explosive_lattice
|
||||||
name = "Explosive Lattice"
|
name = "Explosive Lattice"
|
||||||
id = "explosive_lattice"
|
id = "explosive_lattice"
|
||||||
description = "will do brute damage in an area around targets and is resistant to explosions."
|
description = "will do brute damage in an area around targets."
|
||||||
shortdesc = "will do brute damage in an area around targets."
|
effectdesc = "will also resist explosions, but takes increased damage from fire and other energy sources."
|
||||||
analyzerdescdamage = "Does medium brute damage and causes damage to everyone near its targets."
|
analyzerdescdamage = "Does medium brute damage and causes damage to everyone near its targets."
|
||||||
analyzerdesceffect = "Is highly resistant to explosions."
|
analyzerdesceffect = "Is highly resistant to explosions, but takes increased damage from fire and other energy sources."
|
||||||
color = "#8B2500"
|
color = "#8B2500"
|
||||||
complementary_color = "#00668B"
|
complementary_color = "#00668B"
|
||||||
blobbernaut_message = "blasts"
|
blobbernaut_message = "blasts"
|
||||||
message = "The blob blasts you"
|
message = "The blob blasts you"
|
||||||
|
|
||||||
/datum/reagent/blob/explosive_lattice/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/explosive_lattice/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
|
var/initial_volume = reac_volume
|
||||||
reac_volume = ..()
|
reac_volume = ..()
|
||||||
if(reac_volume >= 10) //if it's not a spore cloud, bad time incoming
|
if(reac_volume >= 10) //if it's not a spore cloud, bad time incoming
|
||||||
var/obj/effect/overlay/temp/explosion/E = PoolOrNew(/obj/effect/overlay/temp/explosion, get_turf(M))
|
var/obj/effect/overlay/temp/explosion/fast/E = PoolOrNew(/obj/effect/overlay/temp/explosion/fast, get_turf(M))
|
||||||
E.alpha = 150
|
E.alpha = 150
|
||||||
for(var/mob/living/L in orange(M, 1))
|
for(var/mob/living/L in orange(get_turf(M), 1))
|
||||||
if("blob" in L.faction) //no friendly fire
|
if("blob" in L.faction) //no friendly fire
|
||||||
continue
|
continue
|
||||||
L.apply_damage(0.6*reac_volume, BRUTE)
|
var/aoe_volume = ..(L, TOUCH, initial_volume, 0, L.get_permeability_protection(), O)
|
||||||
|
L.apply_damage(0.4*aoe_volume, BRUTE)
|
||||||
if(M)
|
if(M)
|
||||||
M.apply_damage(0.6*reac_volume, BRUTE)
|
M.apply_damage(0.6*reac_volume, BRUTE)
|
||||||
else
|
else
|
||||||
M.apply_damage(0.8*reac_volume, BRUTE)
|
M.apply_damage(0.6*reac_volume, BRUTE)
|
||||||
|
|
||||||
/datum/reagent/blob/explosive_lattice/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
/datum/reagent/blob/explosive_lattice/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||||
if(isnull(cause))
|
if(isnull(cause))
|
||||||
@@ -393,59 +285,39 @@
|
|||||||
return damage * 1.5 //take more from fire, tesla, and flashbangs
|
return damage * 1.5 //take more from fire, tesla, and flashbangs
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
//does semi-random brute damage and reacts to brute damage
|
//does brute, burn, and toxin damage, and cools targets down
|
||||||
/datum/reagent/blob/reactive_gelatin
|
/datum/reagent/blob/cryogenic_poison
|
||||||
name = "Reactive Gelatin"
|
name = "Cryogenic Poison"
|
||||||
id = "reactive_gelatin"
|
id = "cryogenic_poison"
|
||||||
description = "will do random brute damage and react to brute damage."
|
description = "will inject targets with a freezing poison that does high damage over time."
|
||||||
shortdesc = "will do random brute damage."
|
analyzerdescdamage = "Injects targets with a freezing poison that will gradually solidify the target's internal organs."
|
||||||
analyzerdescdamage = "Does random brute damage."
|
|
||||||
analyzerdesceffect = "When attacked with brute damage, will lash out, attacking everything near it."
|
|
||||||
color = "#FFA500"
|
|
||||||
complementary_color = "#005AFF"
|
|
||||||
blobbernaut_message = "pummels"
|
|
||||||
message = "The blob pummels you"
|
|
||||||
|
|
||||||
/datum/reagent/blob/reactive_gelatin/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
|
||||||
var/damage = rand(5, 35)/25
|
|
||||||
M.apply_damage(damage*reac_volume, BRUTE)
|
|
||||||
|
|
||||||
/datum/reagent/blob/reactive_gelatin/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
|
||||||
if(damage && damage_type == BRUTE && original_health - damage > 0) //is there any damage, is it brute, and will we be alive
|
|
||||||
if(isliving(cause))
|
|
||||||
B.visible_message("<span class='warning'><b>The blob retaliates, lashing out!</b></span>")
|
|
||||||
for(var/atom/A in range(1, B))
|
|
||||||
A.blob_act(B)
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
//does low burn damage and stamina damage and cools targets down
|
|
||||||
/datum/reagent/blob/cryogenic_liquid
|
|
||||||
name = "Cryogenic Liquid"
|
|
||||||
id = "cryogenic_liquid"
|
|
||||||
description = "will do low burn and stamina damage, and cause targets to freeze."
|
|
||||||
analyzerdescdamage = "Does low burn damage, drains stamina, and injects targets with a freezing liquid."
|
|
||||||
color = "#8BA6E9"
|
color = "#8BA6E9"
|
||||||
complementary_color = "#E9CE8B"
|
complementary_color = "#7D6EB4"
|
||||||
blobbernaut_message = "splashes"
|
blobbernaut_message = "injects"
|
||||||
message = "The blob splashes you with an icy liquid"
|
message = "The blob stabs you"
|
||||||
message_living = ", and you feel cold and tired"
|
message_living = ", and you feel like your insides are solidifying"
|
||||||
|
|
||||||
/datum/reagent/blob/cryogenic_liquid/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/cryogenic_poison/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
reac_volume = ..()
|
reac_volume = ..()
|
||||||
if(M.reagents)
|
if(M.reagents)
|
||||||
M.reagents.add_reagent("frostoil", 0.3*reac_volume)
|
M.reagents.add_reagent("frostoil", 0.3*reac_volume)
|
||||||
M.reagents.add_reagent("ice", 0.3*reac_volume)
|
M.reagents.add_reagent("ice", 0.3*reac_volume)
|
||||||
M.apply_damage(0.4*reac_volume, BURN)
|
M.reagents.add_reagent("cryogenic_poison", 0.3*reac_volume)
|
||||||
if(M)
|
M.apply_damage(0.2*reac_volume, BRUTE)
|
||||||
M.adjustStaminaLoss(0.3*reac_volume)
|
|
||||||
|
/datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/M)
|
||||||
|
M.adjustBruteLoss(0.3*REM, 0)
|
||||||
|
M.adjustFireLoss(0.3*REM, 0)
|
||||||
|
M.adjustToxLoss(0.3*REM, 0)
|
||||||
|
. = 1
|
||||||
|
..()
|
||||||
|
|
||||||
//does burn damage and EMPs, slightly fragile
|
//does burn damage and EMPs, slightly fragile
|
||||||
/datum/reagent/blob/electromagnetic_web
|
/datum/reagent/blob/electromagnetic_web
|
||||||
name = "Electromagnetic Web"
|
name = "Electromagnetic Web"
|
||||||
id = "electromagnetic_web"
|
id = "electromagnetic_web"
|
||||||
description = "will do low burn damage and EMP targets, but is very fragile."
|
description = "will do high burn damage and EMP targets."
|
||||||
shortdesc = "will do low burn damage and EMP targets."
|
effectdesc = "will also take massively increased damage and release an EMP when killed."
|
||||||
analyzerdescdamage = "Does low burn damage and EMPs targets."
|
analyzerdescdamage = "Does low burn damage and EMPs targets."
|
||||||
analyzerdesceffect = "Is fragile to all types of damage, but takes massive damage from brute. In addition, releases a small EMP when killed."
|
analyzerdesceffect = "Is fragile to all types of damage, but takes massive damage from brute. In addition, releases a small EMP when killed."
|
||||||
color = "#83ECEC"
|
color = "#83ECEC"
|
||||||
@@ -459,7 +331,7 @@
|
|||||||
if(prob(reac_volume*2))
|
if(prob(reac_volume*2))
|
||||||
M.emp_act(2)
|
M.emp_act(2)
|
||||||
if(M)
|
if(M)
|
||||||
M.apply_damage(0.6*reac_volume, BURN)
|
M.apply_damage(reac_volume, BURN)
|
||||||
|
|
||||||
/datum/reagent/blob/electromagnetic_web/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
/datum/reagent/blob/electromagnetic_web/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||||
if(damage_type == BRUTE) //take full brute
|
if(damage_type == BRUTE) //take full brute
|
||||||
@@ -480,8 +352,8 @@
|
|||||||
/datum/reagent/blob/synchronous_mesh
|
/datum/reagent/blob/synchronous_mesh
|
||||||
name = "Synchronous Mesh"
|
name = "Synchronous Mesh"
|
||||||
id = "synchronous_mesh"
|
id = "synchronous_mesh"
|
||||||
description = "will do brute damage for each nearby blob and spread damage between nearby blobs."
|
description = "will do massively increased brute damage for each blob near the target."
|
||||||
shortdesc = "will do brute damage for each nearby blob."
|
effectdesc = "will also spread damage between each blob near the attacked blob."
|
||||||
analyzerdescdamage = "Does brute damage, increasing for each blob near the target."
|
analyzerdescdamage = "Does brute damage, increasing for each blob near the target."
|
||||||
analyzerdesceffect = "When attacked, spreads damage between all blobs near the attacked blob."
|
analyzerdesceffect = "When attacked, spreads damage between all blobs near the attacked blob."
|
||||||
color = "#65ADA2"
|
color = "#65ADA2"
|
||||||
@@ -491,9 +363,9 @@
|
|||||||
|
|
||||||
/datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
reac_volume = ..()
|
reac_volume = ..()
|
||||||
M.apply_damage(0.1*reac_volume, BRUTE)
|
M.apply_damage(0.2*reac_volume, BRUTE)
|
||||||
if(M && reac_volume)
|
if(M && reac_volume)
|
||||||
for(var/obj/effect/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.5*reac_volume
|
for(var/obj/effect/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.6*reac_volume
|
||||||
if(M)
|
if(M)
|
||||||
B.blob_attack_animation(M) //show them they're getting a bad time
|
B.blob_attack_animation(M) //show them they're getting a bad time
|
||||||
M.apply_damage(0.3*reac_volume, BRUTE)
|
M.apply_damage(0.3*reac_volume, BRUTE)
|
||||||
@@ -512,47 +384,37 @@
|
|||||||
return damage * 1.25
|
return damage * 1.25
|
||||||
|
|
||||||
//does brute damage through armor and bio resistance
|
//does brute damage through armor and bio resistance
|
||||||
/datum/reagent/blob/penetrating_spines
|
/datum/reagent/blob/reactive_spines
|
||||||
name = "Penetrating Spines"
|
name = "Reactive Spines"
|
||||||
id = "penetrating_spines"
|
id = "reactive_spines"
|
||||||
description = "will do medium brute damage through armor and bio resistance."
|
description = "will do medium brute damage through armor and bio resistance."
|
||||||
|
effectdesc = "will also react when attacked with brute damage, attacking all near the attacked blob."
|
||||||
analyzerdescdamage = "Does medium brute damage, ignoring armor and bio resistance."
|
analyzerdescdamage = "Does medium brute damage, ignoring armor and bio resistance."
|
||||||
color = "#6E4664"
|
analyzerdesceffect = "When attacked with brute damage, will lash out, attacking everything near it."
|
||||||
complementary_color = "#466E50"
|
color = "#9ACD32"
|
||||||
|
complementary_color = "#FFA500"
|
||||||
blobbernaut_message = "stabs"
|
blobbernaut_message = "stabs"
|
||||||
message = "The blob stabs you"
|
message = "The blob stabs you"
|
||||||
|
|
||||||
/datum/reagent/blob/penetrating_spines/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
/datum/reagent/blob/reactive_spines/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||||
if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
|
if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
|
||||||
return 0 //the dead, and blob mobs, don't cause reactions
|
return 0 //the dead, and blob mobs, don't cause reactions
|
||||||
M.adjustBruteLoss(0.7*reac_volume)
|
M.adjustBruteLoss(0.8*reac_volume)
|
||||||
|
|
||||||
/datum/reagent/blob/adaptive_nexuses
|
/datum/reagent/blob/reactive_spines/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||||
name = "Adaptive Nexuses"
|
if(damage && damage_type == BRUTE && original_health - damage > 0) //is there any damage, is it brute, and will we be alive
|
||||||
id = "adaptive_nexuses"
|
if(isliving(cause))
|
||||||
description = "will do medium brute damage and kill unconscious targets, giving you bonus resources."
|
B.visible_message("<span class='boldwarning'>The blob retaliates, lashing out!</span>")
|
||||||
shortdesc = "will do medium brute damage and kill unconscious targets, giving your overmind bonus resources."
|
for(var/atom/A in range(1, B))
|
||||||
analyzerdescdamage = "Does medium brute damage and kills unconscious humans, reaping resources from them."
|
A.blob_act(B)
|
||||||
color = "#4A64C0"
|
return ..()
|
||||||
complementary_color = "#823ABB"
|
|
||||||
|
|
||||||
/datum/reagent/blob/adaptive_nexuses/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
|
||||||
if(O && ishuman(M) && M.stat == UNCONSCIOUS)
|
|
||||||
PoolOrNew(/obj/effect/overlay/temp/revenant, get_turf(M))
|
|
||||||
var/points = rand(5, 10)
|
|
||||||
O.add_points(points)
|
|
||||||
O << "<span class='notice'>Gained [points] resources from the death of [M].</span>"
|
|
||||||
M.death()
|
|
||||||
if(M)
|
|
||||||
M.apply_damage(0.5*reac_volume, BRUTE)
|
|
||||||
|
|
||||||
//does low brute damage, oxygen damage, and stamina damage and wets tiles when damaged
|
//does low brute damage, oxygen damage, and stamina damage and wets tiles when damaged
|
||||||
/datum/reagent/blob/pressurized_slime
|
/datum/reagent/blob/pressurized_slime
|
||||||
name = "Pressurized Slime"
|
name = "Pressurized Slime"
|
||||||
id = "pressurized_slime"
|
id = "pressurized_slime"
|
||||||
description = "will do low brute, oxygen, and stamina damage, and wet tiles when damaged or killed."
|
description = "will do low brute, oxygen, and stamina damage, and wet tiles under targets."
|
||||||
shortdesc = "will do low brute, oxygen, and stamina damage, and wet tiles under targets."
|
effectdesc = "will also wet tiles near blobs that are attacked or killed."
|
||||||
analyzerdescdamage = "Does low brute damage, low oxygen damage, drains stamina, and wets tiles under targets, extinguishing them."
|
analyzerdescdamage = "Does low brute damage, low oxygen damage, drains stamina, and wets tiles under targets, extinguishing them."
|
||||||
analyzerdesceffect = "When attacked or killed, wets nearby tiles, extinguishing anything on them."
|
analyzerdesceffect = "When attacked or killed, wets nearby tiles, extinguishing anything on them."
|
||||||
color = "#AAAABB"
|
color = "#AAAABB"
|
||||||
@@ -568,20 +430,21 @@
|
|||||||
T.MakeSlippery(min_wet_time = 10, wet_time_to_add = 5)
|
T.MakeSlippery(min_wet_time = 10, wet_time_to_add = 5)
|
||||||
M.adjust_fire_stacks(-(reac_volume / 10))
|
M.adjust_fire_stacks(-(reac_volume / 10))
|
||||||
M.ExtinguishMob()
|
M.ExtinguishMob()
|
||||||
M.apply_damage(0.1*reac_volume, BRUTE)
|
M.apply_damage(0.4*reac_volume, BRUTE)
|
||||||
if(M)
|
if(M)
|
||||||
M.apply_damage(0.3*reac_volume, OXY)
|
M.apply_damage(0.4*reac_volume, OXY)
|
||||||
if(M)
|
if(M)
|
||||||
M.adjustStaminaLoss(0.3*reac_volume)
|
M.adjustStaminaLoss(0.2*reac_volume)
|
||||||
|
|
||||||
/datum/reagent/blob/pressurized_slime/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
/datum/reagent/blob/pressurized_slime/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||||
extinguisharea(B, damage)
|
if(cause || damage_type != BURN)
|
||||||
|
extinguisharea(B, damage)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/datum/reagent/blob/pressurized_slime/death_reaction(obj/effect/blob/B, cause)
|
/datum/reagent/blob/pressurized_slime/death_reaction(obj/effect/blob/B, cause)
|
||||||
if(!isnull(cause))
|
if(!isnull(cause))
|
||||||
B.visible_message("<span class='warning'><b>The blob ruptures, spraying the area with liquid!</b></span>")
|
B.visible_message("<span class='boldwarning'>The blob ruptures, spraying the area with liquid!</span>")
|
||||||
extinguisharea(B, 50)
|
extinguisharea(B, 50)
|
||||||
|
|
||||||
/datum/reagent/blob/pressurized_slime/proc/extinguisharea(obj/effect/blob/B, probchance)
|
/datum/reagent/blob/pressurized_slime/proc/extinguisharea(obj/effect/blob/B, probchance)
|
||||||
for(var/turf/open/T in range(1, B))
|
for(var/turf/open/T in range(1, B))
|
||||||
@@ -592,75 +455,3 @@
|
|||||||
for(var/mob/living/L in T)
|
for(var/mob/living/L in T)
|
||||||
L.adjust_fire_stacks(-2.5)
|
L.adjust_fire_stacks(-2.5)
|
||||||
L.ExtinguishMob()
|
L.ExtinguishMob()
|
||||||
|
|
||||||
//does brute damage and throws or pulls nearby objects at the target
|
|
||||||
/datum/reagent/blob/dark_matter
|
|
||||||
name = "Dark Matter"
|
|
||||||
id = "dark_matter"
|
|
||||||
description = "will do medium brute damage and pull nearby objects and enemies at the target."
|
|
||||||
analyzerdescdamage = "Does medium brute damage and pulls nearby objects and creatures at the target."
|
|
||||||
color = "#61407E"
|
|
||||||
complementary_color = "#5D7E40"
|
|
||||||
message = "You feel a thrum as the blob strikes you, and everything flies at you"
|
|
||||||
|
|
||||||
/datum/reagent/blob/dark_matter/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
|
||||||
reagent_vortex(M, 0, reac_volume)
|
|
||||||
M.apply_damage(0.3*reac_volume, BRUTE)
|
|
||||||
|
|
||||||
//does brute damage and throws or pushes nearby objects away from the target
|
|
||||||
/datum/reagent/blob/b_sorium
|
|
||||||
name = "Sorium"
|
|
||||||
id = "b_sorium"
|
|
||||||
description = "will do medium brute damage and throw nearby objects and enemies away from the target."
|
|
||||||
analyzerdescdamage = "Does medium brute damage and pushes nearby objects and creatures away from the target."
|
|
||||||
color = "#808000"
|
|
||||||
complementary_color = "#000080"
|
|
||||||
message = "The blob slams into you and sends you flying"
|
|
||||||
|
|
||||||
/datum/reagent/blob/b_sorium/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
|
||||||
reac_volume = ..()
|
|
||||||
reagent_vortex(M, 1, reac_volume)
|
|
||||||
M.apply_damage(0.3*reac_volume, BRUTE)
|
|
||||||
|
|
||||||
/datum/reagent/blob/proc/reagent_vortex(mob/living/M, setting_type, reac_volume)
|
|
||||||
if(M && reac_volume)
|
|
||||||
var/turf/pull = get_turf(M)
|
|
||||||
var/range_power = Clamp(round(reac_volume/5, 1), 1, 5)
|
|
||||||
for(var/atom/movable/X in range(range_power,pull))
|
|
||||||
if(istype(X, /obj/effect))
|
|
||||||
continue
|
|
||||||
if(isliving(X))
|
|
||||||
var/mob/living/L = X
|
|
||||||
if("blob" in L.faction) //no friendly throwpulling
|
|
||||||
continue
|
|
||||||
if(!X.anchored)
|
|
||||||
var/distance = get_dist(X, pull)
|
|
||||||
var/moving_power = max(range_power - distance, 1)
|
|
||||||
if(moving_power > 2) //if the vortex is powerful and we're close, we get thrown
|
|
||||||
if(setting_type)
|
|
||||||
var/atom/throw_target = get_edge_target_turf(X, get_dir(X, get_step_away(X, pull)))
|
|
||||||
var/throw_range = 5 - distance
|
|
||||||
X.throw_at_fast(throw_target, throw_range, 1)
|
|
||||||
else
|
|
||||||
X.throw_at_fast(pull, distance, 1)
|
|
||||||
else
|
|
||||||
spawn(0)
|
|
||||||
if(setting_type)
|
|
||||||
for(var/i in 0 to moving_power-1)
|
|
||||||
sleep(2)
|
|
||||||
if(!step_away(X, pull))
|
|
||||||
break
|
|
||||||
else
|
|
||||||
for(var/i in 0 to moving_power-1)
|
|
||||||
sleep(2)
|
|
||||||
if(!step_towards(X, pull))
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
/datum/reagent/blob/proc/send_message(mob/living/M)
|
|
||||||
var/totalmessage = message
|
|
||||||
if(message_living && !issilicon(M))
|
|
||||||
totalmessage += message_living
|
|
||||||
totalmessage += "!"
|
|
||||||
M << "<span class='userdanger'>[totalmessage]</span>"
|
|
||||||
|
|||||||
@@ -130,15 +130,15 @@ As an Alien, you take double damage from all burn attacks, such as lasers, weldi
|
|||||||
As an Alien, resin floors not only regenerate your plasma supply, but also passively heal you. Fight on resin floors to gain a home turf advantage!
|
As an Alien, resin floors not only regenerate your plasma supply, but also passively heal you. Fight on resin floors to gain a home turf advantage!
|
||||||
As an Alien, the facehugger is by far your most powerful weapon because of its ability to instantly win a fight. Remember however that certain helmets, such as biohoods or space helmets will completely block facehugger attacks.
|
As an Alien, the facehugger is by far your most powerful weapon because of its ability to instantly win a fight. Remember however that certain helmets, such as biohoods or space helmets will completely block facehugger attacks.
|
||||||
As an Alien, you are unable to pick up or use any human items or machinery. Instead, you should focus on sabotaging APCs, computers, cameras and either stowing, spacing, or melting any weapons you find.
|
As an Alien, you are unable to pick up or use any human items or machinery. Instead, you should focus on sabotaging APCs, computers, cameras and either stowing, spacing, or melting any weapons you find.
|
||||||
When fighting the Blob, you can hit it with an analyzer to check its chemical effects and the type of blob analyzed. Examining it with a research scanner active will also reveal this information.
|
When fighting the Blob, you can hit it with an analyzer to check its chemical effects and the type of blob analyzed. Examining it with a research scanner or medical hud active will also reveal this information.
|
||||||
As the Blob, you can place your core at any clear, unobserved, spot you can move to after 3 minutes have passed. If you wait too long, you will be automatically placed at a random location. Use this wait time to coordinate with any other overminds.
|
As the Blob, you can place your core at any clear, unobserved, spot you can move to after 3 minutes have passed. If you wait too long, you will be automatically placed at a random location. Use this wait time to coordinate with any other overminds.
|
||||||
As the Blob, keep your core some distance from space, as it is both expensive to expand onto space, easy to be attacked from, and does not count towards your win condition. Emitter platforms built in space are especially dangerous.
|
As the Blob, keep your core some distance from space, as it is both expensive to expand onto space, easy to be attacked from, and does not count towards your win condition. Emitter platforms built in space are especially dangerous.
|
||||||
As the Blob, you can randomly repick your reagent type if the crew has adapted and protected themselves against your current one.
|
As the Blob, you can randomly repick your reagent type if the crew has adapted and protected themselves against your current one.
|
||||||
As the Blob, you fight a war of attrition: Take out medbay and fight in chokepoints to prevent continued assaults and coordinated burst damage attacks!
|
As the Blob, you fight a war of attrition: Take out medbay and fight in chokepoints to prevent continued assaults and coordinated burst damage attacks!
|
||||||
As the Blob, remember that you can only expand onto tiles from cardinal directions, while the crew can attack you diagonally. Fight in narrow corridors or expand and widen across the width of the hallway to force confrontations where you can hit them!
|
As the Blob, you can attack anything next to a blob, but can only expand in cardinal directions, and diagonal attacks are slightly weaker.
|
||||||
As the Blob, don't neglect the creation of factories. These create spores that carry your reagent and can chase crewmembers far further than you. Spores can also be rallied to swarm the crew and cause panic, and can even take over corpses to create much more dangerous blob zombies!
|
As the Blob, don't neglect the creation of factories. These create spores that carry your reagent and can chase crewmembers far further than you. Spores can also be rallied to swarm the crew and cause panic, and can even take over corpses to create much more dangerous blob zombies!
|
||||||
As the Blob, you can produce a Blobbernaut from a factory for 40 resources. Blobbernauts are smart, gradually regenerate near nodes, and apply your chemical when attacking, but die when too far from the blob or if their factory is killed. However, the factory used becomes fragile and stops spawning spores.
|
As the Blob, you can produce a Blobbernaut from a factory for 40 resources. Blobbernauts are smart, gradually regenerate near nodes, and apply your chemical when attacking, but die when too far from the blob or if their factory is killed. However, the factory used becomes fragile and stops spawning spores.
|
||||||
As the Blob, you can expand by clicking, create strong blobs with ctrl-click, rally spores with middle-click, and remove blobs with alt-click.
|
As the Blob, you can expand by clicking, create strong blobs with ctrl-click, rally spores with middle-click, and remove blobs with alt-click. You do not need to have your camera over the tile to do this.
|
||||||
As the Blob, removing strong blobs, resource nodes, factories, and nodes will give you 4, 15, 25, and 25 resources back, respectively.
|
As the Blob, removing strong blobs, resource nodes, factories, and nodes will give you 4, 15, 25, and 25 resources back, respectively.
|
||||||
As the Blob, talking will send a message to all other overminds and all Blobbernauts, allowing you to direct attacks and coordinate.
|
As the Blob, talking will send a message to all other overminds and all Blobbernauts, allowing you to direct attacks and coordinate.
|
||||||
As a Blobbernaut, you can communicate with overminds and other Blobbernauts via :b.
|
As a Blobbernaut, you can communicate with overminds and other Blobbernauts via :b.
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 445 KiB After Width: | Height: | Size: 552 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 477 KiB After Width: | Height: | Size: 1.2 MiB |
Reference in New Issue
Block a user