Revert "12/21 modernizations from TG live"

This commit is contained in:
LetterJay
2016-12-22 22:35:44 -06:00
committed by GitHub
parent cf59ac1c3d
commit ae40d4134e
2215 changed files with 86928 additions and 707332 deletions
+13 -17
View File
@@ -1,4 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
//Few global vars to track the blob
var/list/blobs = list() //complete list of all blobs made.
@@ -20,19 +20,13 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b
round_ends_with_antag_death = 1
announce_span = "green"
announce_text = "Dangerous gelatinous organisms are spreading throughout the station!\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."
var/message_sent = FALSE
var/burst = 0
var/cores_to_spawn = 1
var/players_per_core = 25
var/blob_point_rate = 3
var/blob_base_starting_points = 80
var/blobwincount = 250
var/blobwincount = 350
var/messagedelay_low = 2400 //in deciseconds
var/messagedelay_high = 3600 //blob report will be sent after a random value between these (minimum 4 minutes, maximum 6 minutes)
@@ -42,8 +36,7 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b
/datum/game_mode/blob/pre_setup()
cores_to_spawn = max(round(num_players()/players_per_core, 1), 1)
var/win_multiplier = 1 + (0.1 * cores_to_spawn)
blobwincount = initial(blobwincount) * cores_to_spawn * win_multiplier
blobwincount = initial(blobwincount) * cores_to_spawn
for(var/j = 0, j < cores_to_spawn, j++)
if (!antag_candidates.len)
@@ -68,6 +61,11 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b
candidates += player
return candidates
/datum/game_mode/blob/announce()
world << "<B>The current game mode is - <font color='green'>Blob</font>!</B>"
world << "<B>A dangerous alien organism is rapidly spreading throughout the station!</B>"
world << "You must kill it all while minimizing the damage to the station."
/datum/game_mode/blob/proc/show_message(message)
for(var/datum/mind/blob in blob_overminds)
blob.current << message
@@ -75,13 +73,12 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b
/datum/game_mode/blob/post_setup()
for(var/datum/mind/blob in blob_overminds)
var/mob/camera/blob/B = blob.current.become_overmind(TRUE, round(blob_base_starting_points/blob_overminds.len))
B.mind.name = B.name
var/mob/camera/blob/B = blob.current.become_overmind(1)
var/turf/T = pick(blobstart)
B.loc = T
B.base_point_rate = blob_point_rate
SSshuttle.registerHostileEnvironment(src)
SSshuttle.emergencyNoEscape = 1
// Disable the blob event for this round.
var/datum/round_event_control/blob/B = locate() in SSevent.control
@@ -94,10 +91,9 @@ var/list/blobs_legit = list() //used for win-score calculations, contains only b
sleep(message_delay)
send_intercept(1)
message_sent = TRUE
sleep(24000) //40 minutes, plus burst_delay*3(minimum of 6 minutes, maximum of 8)
if(!replacementmode)
send_intercept(2) //if the blob has been alive this long, it's time to bomb it
send_intercept(2) //if the blob has been alive this long, it's time to bomb it
return ..()
+10 -32
View File
@@ -1,16 +1,16 @@
/datum/game_mode/blob/check_finished()
if(blobwincount <= blobs_legit.len)//Blob took over
return 1
for(var/datum/mind/blob in blob_overminds)
if(isovermind(blob.current))
var/mob/camera/blob/B = blob.current
if(B.blob_core || !B.placed)
return 0
if(overminds.len)
return 0
if(!blob_cores.len) //blob is dead
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
SSshuttle.clearHostileEnvironment(src)
SSshuttle.emergencyNoEscape = 0
if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
SSshuttle.emergency.mode = SHUTTLE_DOCKED
SSshuttle.emergency.timer = world.time
priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
return ..()
return 1
return ..()
@@ -22,45 +22,23 @@
if(blobwincount <= blobs_legit.len)
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 << "<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.")
ticker.news_report = BLOB_WIN
else if(station_was_nuked)
feedback_set_details("round_end_result","halfwin - nuke")
world << "<FONT size = 3><B>Partial Win: The station has been destroyed!</B></FONT>"
world << "<B>Directive 7-12 has been successfully carried out, preventing the Blob from spreading.</B>"
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).")
ticker.news_report = BLOB_NUKE
else if(!blob_cores.len)
feedback_set_details("round_end_result","loss - blob eliminated")
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.")
ticker.news_report = BLOB_DESTROYED
..()
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()
if(istype(ticker.mode,/datum/game_mode/blob) )
var/datum/game_mode/blob/blob_mode = src
+9 -14
View File
@@ -1,4 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
/datum/game_mode/blob/send_intercept(report = 0)
var/intercepttext = ""
@@ -16,7 +16,7 @@
print_command_report(intercepttext,"Level 5-6 Biohazard Response Procedures")
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
if(2)
var/nukecode = random_nukecode()
var/nukecode = rand(10000, 99999)
for(var/obj/machinery/nuclearbomb/bomb in machines)
if(bomb && bomb.r_code)
if(bomb.z == ZLEVEL_STATION)
@@ -57,23 +57,20 @@
/datum/station_state/proc/count(count_territories)
for(var/turf/T in block(locate(1,1,1), locate(world.maxx,world.maxy,1)))
if(isfloorturf(T))
var/turf/open/floor/TF = T
if(!(TF.burnt))
if(istype(T,/turf/open/floor))
if(!(T:burnt))
src.floor += 12
else
src.floor += 1
if(iswallturf(T))
var/turf/closed/wall/TW = T
if(TW.intact)
if(istype(T, /turf/closed/wall))
if(T:intact)
src.wall += 2
else
src.wall += 1
if(istype(T, /turf/closed/wall/r_wall))
var/turf/closed/wall/r_wall/TRW = T
if(TRW.intact)
if(T:intact)
src.r_wall += 2
else
src.r_wall += 1
@@ -82,10 +79,8 @@
for(var/obj/O in T.contents)
if(istype(O, /obj/structure/window))
src.window += 1
else if(istype(O, /obj/structure/grille))
var/obj/structure/grille/GR = O
if(!GR.broken)
src.grille += 1
else if(istype(O, /obj/structure/grille) && (!O:destroyed))
src.grille += 1
else if(istype(O, /obj/machinery/door))
src.door += 1
else if(istype(O, /obj/machinery))
+24 -32
View File
@@ -14,22 +14,22 @@
minbodytemp = 0
maxbodytemp = 360
unique_name = 1
a_intent = INTENT_HARM
a_intent = "harm"
var/mob/camera/blob/overmind = null
var/obj/structure/blob/factory/factory = null
var/obj/effect/blob/factory/factory = null
/mob/living/simple_animal/hostile/blob/update_icons()
if(overmind)
add_atom_colour(overmind.blob_reagent_datum.color, FIXED_COLOUR_PRIORITY)
color = overmind.blob_reagent_datum.color
else
remove_atom_colour(FIXED_COLOUR_PRIORITY)
color = initial(color)
/mob/living/simple_animal/hostile/blob/Destroy()
if(overmind)
overmind.blob_mobs -= src
return ..()
/mob/living/simple_animal/hostile/blob/blob_act(obj/structure/blob/B)
/mob/living/simple_animal/hostile/blob/blob_act(obj/effect/blob/B)
if(stat != DEAD && health < maxHealth)
for(var/i in 1 to 2)
var/obj/effect/overlay/temp/heal/H = PoolOrNew(/obj/effect/overlay/temp/heal, get_turf(src)) //hello yes you are being healed
@@ -39,27 +39,24 @@
H.color = "#000000"
adjustHealth(-maxHealth*0.0125)
/mob/living/simple_animal/hostile/blob/fire_act(exposed_temperature, exposed_volume)
/mob/living/simple_animal/hostile/blob/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
if(exposed_temperature)
adjustFireLoss(Clamp(0.01 * exposed_temperature, 1, 5))
else
adjustFireLoss(5)
adjustFireLoss(Clamp(0.01 * exposed_temperature, 1, 5))
/mob/living/simple_animal/hostile/blob/CanPass(atom/movable/mover, turf/target, height = 0)
if(istype(mover, /obj/structure/blob))
if(istype(mover, /obj/effect/blob))
return 1
return ..()
/mob/living/simple_animal/hostile/blob/Process_Spacemove(movement_dir = 0)
for(var/obj/structure/blob/B in range(1, src))
for(var/obj/effect/blob/B in range(1, src))
return 1
return ..()
/mob/living/simple_animal/hostile/blob/handle_inherent_channels(message, message_mode)
if(message_mode == MODE_BINARY)
blob_chat(message)
return 1
return ITALICS | REDUCE_RANGE
else
..()
@@ -82,19 +79,17 @@
desc = "A floating, fragile spore."
icon_state = "blobpod"
icon_living = "blobpod"
health = 30
maxHealth = 30
health = 40
maxHealth = 40
verb_say = "psychically pulses"
verb_ask = "psychically probes"
verb_exclaim = "psychically yells"
verb_yell = "psychically screams"
melee_damage_lower = 2
melee_damage_upper = 4
obj_damage = 20
environment_smash = 1
attacktext = "hits"
attack_sound = 'sound/weapons/genhit1.ogg'
movement_type = FLYING
flying = 1
del_on_death = 1
deathmessage = "explodes into a cloud of gas!"
var/death_cloud_size = 1 //size of cloud produced from a dying spore
@@ -102,7 +97,7 @@
var/is_zombie = 0
gold_core_spawnable = 1
/mob/living/simple_animal/hostile/blob/blobspore/New(loc, var/obj/structure/blob/factory/linked_node)
/mob/living/simple_animal/hostile/blob/blobspore/New(loc, var/obj/effect/blob/factory/linked_node)
if(istype(linked_node))
factory = linked_node
factory.spores += src
@@ -130,7 +125,7 @@
desc = "A shambling corpse animated by the blob."
melee_damage_lower += 8
melee_damage_upper += 11
movement_type = GROUND
flying = 0
death_cloud_size = 0
icon = H.icon
icon_state = "zombie_s"
@@ -173,23 +168,20 @@
return ..()
/mob/living/simple_animal/hostile/blob/blobspore/update_icons()
if(overmind)
add_atom_colour(overmind.blob_reagent_datum.complementary_color, FIXED_COLOUR_PRIORITY)
else
remove_atom_colour(FIXED_COLOUR_PRIORITY)
..()
if(is_zombie)
cut_overlays()
overlays = human_overlays
var/image/I = image('icons/mob/blob.dmi', icon_state = "blob_head")
if(overmind)
I.color = overmind.blob_reagent_datum.complementary_color
I.color = overmind.blob_reagent_datum.color
color = initial(color)//looks better.
add_overlay(I)
/mob/living/simple_animal/hostile/blob/blobspore/weak
name = "fragile blob spore"
health = 15
maxHealth = 15
health = 20
maxHealth = 20
melee_damage_lower = 1
melee_damage_upper = 2
death_cloud_size = 0
@@ -207,9 +199,9 @@
health = 200
maxHealth = 200
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_upper = 20
obj_damage = 60
attacktext = "slams"
attack_sound = 'sound/effects/blobattack.ogg'
verb_say = "gurgles"
@@ -217,7 +209,7 @@
verb_exclaim = "roars"
verb_yell = "bellows"
force_threshold = 10
pressure_resistance = 50
pressure_resistance = 40
mob_size = MOB_SIZE_LARGE
see_invisible = SEE_INVISIBLE_MINIMUM
see_in_dark = 8
@@ -233,13 +225,13 @@
if(independent)
return // strong independent blobbernaut that don't need no blob
var/damagesources = 0
if(!(locate(/obj/structure/blob) in range(2, src)))
if(!(locate(/obj/effect/blob) in range(2, src)))
damagesources++
if(!factory)
damagesources++
if(damagesources)
for(var/i in 1 to damagesources)
adjustHealth(maxHealth*0.025) //take 2.5% of max health as damage when not near the blob or if the naut has no factory, 5% if both
adjustHealth(maxHealth*0.025) //take 2.5% maxhealth as damage when not near the blob or if the naut has no factory, 5% if both
var/list/viewing = list()
for(var/mob/M in viewers(src))
if(M.client)
@@ -282,7 +274,7 @@
..(gibbed)
if(factory)
factory.naut = null //remove this naut from its factory
factory.max_integrity = initial(factory.max_integrity)
factory.maxhealth = initial(factory.maxhealth)
flick("blobbernaut_death", src)
/mob/living/simple_animal/hostile/blob/blobbernaut/independent
+23 -23
View File
@@ -1,13 +1,13 @@
/obj/structure/blob/core
/obj/effect/blob/core
name = "blob core"
icon = 'icons/mob/blob.dmi'
icon_state = "blank_blob"
desc = "A huge, pulsating yellow mass."
obj_integrity = 400
max_integrity = 400
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 75, acid = 90)
health = 400
maxhealth = 400
explosion_block = 6
point_return = -1
atmosblock = 1
health_regen = 0 //we regen in Life() instead of when pulsed
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
@@ -15,7 +15,7 @@
var/point_rate = 2
/obj/structure/blob/core/New(loc, client/new_overmind = null, new_rate = 2, placed = 0)
/obj/effect/blob/core/New(loc, client/new_overmind = null, new_rate = 2, placed = 0)
blob_cores += src
START_PROCESSING(SSobj, src)
poi_list |= src
@@ -27,10 +27,10 @@
point_rate = new_rate
..()
/obj/structure/blob/core/scannerreport()
/obj/effect/blob/core/scannerreport()
return "Directs the blob's expansion, gradually expands, and sustains nearby blob spores and blobbernauts."
/obj/structure/blob/core/update_icon()
/obj/effect/blob/core/update_icon()
cut_overlays()
color = null
var/image/I = new('icons/mob/blob.dmi', "blob")
@@ -40,7 +40,7 @@
var/image/C = new('icons/mob/blob.dmi', "blob_core_overlay")
add_overlay(C)
/obj/structure/blob/core/Destroy()
/obj/effect/blob/core/Destroy()
blob_cores -= src
if(overmind)
overmind.blob_core = null
@@ -49,36 +49,36 @@
poi_list -= src
return ..()
/obj/structure/blob/core/ex_act(severity, target)
/obj/effect/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
/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
take_damage(damage, BRUTE, "bomb", 0)
take_damage(damage, BRUTE)
/obj/structure/blob/core/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, overmind_reagent_trigger = 1)
. = ..()
if(obj_integrity > 0)
if(overmind) //we should have an overmind, but...
overmind.update_health_hud()
/obj/effect/blob/core/check_health()
..()
if(overmind) //we should have an overmind, but...
overmind.update_health_hud()
/obj/structure/blob/core/Life()
if(qdeleted(src))
return
/obj/effect/blob/core/Life()
if(!overmind)
create_overmind()
else
if(resource_delay <= world.time)
resource_delay = world.time + 10 // 1 second
overmind.add_points(point_rate)
obj_integrity = min(max_integrity, obj_integrity+core_regen)
health = min(maxhealth, health+core_regen)
if(overmind)
overmind.update_health_hud()
Pulse_Area(overmind, 12, 4, 3)
for(var/obj/structure/blob/normal/B in range(1, src))
for(var/obj/effect/blob/normal/B in range(1, src))
if(prob(5))
B.change_to(/obj/structure/blob/shield/core, overmind)
B.change_to(/obj/effect/blob/shield/core, overmind)
..()
/obj/structure/blob/core/proc/create_overmind(client/new_overmind, override_delay)
/obj/effect/blob/core/proc/create_overmind(client/new_overmind, override_delay)
if(overmind_get_delay > world.time && !override_delay)
return
@@ -91,7 +91,7 @@
var/list/candidates = list()
if(!new_overmind)
candidates = pollCandidatesForMob("Do you want to play as a blob overmind?", ROLE_BLOB, null, ROLE_BLOB, 50, src) //we're technically not a mob but behave similarly
candidates = get_candidates(ROLE_BLOB)
if(candidates.len)
C = pick(candidates)
else
+6 -6
View File
@@ -1,10 +1,10 @@
/obj/structure/blob/factory
/obj/effect/blob/factory
name = "factory blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_factory"
desc = "A thick spire of tendrils."
obj_integrity = 200
max_integrity = 200
health = 200
maxhealth = 200
health_regen = 1
point_return = 25
var/list/spores = list()
@@ -14,12 +14,12 @@
var/spore_cooldown = 80 //8 seconds between spores and after spore death
/obj/structure/blob/factory/scannerreport()
/obj/effect/blob/factory/scannerreport()
if(naut)
return "It is currently sustaining a blobbernaut, making it fragile and unable to produce blob spores."
return "Will produce a blob spore every few seconds."
/obj/structure/blob/factory/Destroy()
/obj/effect/blob/factory/Destroy()
for(var/mob/living/simple_animal/hostile/blob/blobspore/spore in spores)
if(spore.factory == src)
spore.factory = null
@@ -30,7 +30,7 @@
spores = null
return ..()
/obj/structure/blob/factory/Be_Pulsed()
/obj/effect/blob/factory/Be_Pulsed()
. = ..()
if(naut)
return
+16 -13
View File
@@ -1,38 +1,41 @@
/obj/structure/blob/node
/obj/effect/blob/node
name = "blob node"
icon = 'icons/mob/blob.dmi'
icon_state = "blank_blob"
desc = "A large, pulsating yellow mass."
obj_integrity = 200
max_integrity = 200
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 65, acid = 90)
health = 200
maxhealth = 200
health_regen = 3
point_return = 25
atmosblock = 1
/obj/structure/blob/node/New(loc)
/obj/effect/blob/node/New(loc, var/h = 100)
blob_nodes += src
START_PROCESSING(SSobj, src)
..()
..(loc, h)
/obj/structure/blob/node/scannerreport()
/obj/effect/blob/node/scannerreport()
return "Gradually expands and sustains nearby blob spores and blobbernauts."
/obj/structure/blob/node/update_icon()
/obj/effect/blob/node/update_icon()
cut_overlays()
color = null
var/image/I = new('icons/mob/blob.dmi', "blob")
if(overmind)
I.color = overmind.blob_reagent_datum.color
add_overlay(I)
src.add_overlay(I)
var/image/C = new('icons/mob/blob.dmi', "blob_node_overlay")
add_overlay(C)
src.add_overlay(C)
/obj/structure/blob/node/Destroy()
/obj/effect/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
/obj/effect/blob/node/Destroy()
blob_nodes -= src
STOP_PROCESSING(SSobj, src)
return ..()
/obj/structure/blob/node/Life()
/obj/effect/blob/node/Life()
Pulse_Area(overmind, 10, 3, 2)
color = null
+7 -7
View File
@@ -1,26 +1,26 @@
/obj/structure/blob/resource
/obj/effect/blob/resource
name = "resource blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_resource"
desc = "A thin spire of slightly swaying tendrils."
obj_integrity = 60
max_integrity = 60
health = 60
maxhealth = 60
point_return = 15
var/resource_delay = 0
/obj/structure/blob/resource/scannerreport()
/obj/effect/blob/resource/scannerreport()
return "Gradually supplies the blob with resources, increasing the rate of expansion."
/obj/structure/blob/resource/creation_action()
/obj/effect/blob/resource/creation_action()
if(overmind)
overmind.resource_blobs += src
/obj/structure/blob/resource/Destroy()
/obj/effect/blob/resource/Destroy()
if(overmind)
overmind.resource_blobs -= src
return ..()
/obj/structure/blob/resource/Be_Pulsed()
/obj/effect/blob/resource/Be_Pulsed()
. = ..()
if(resource_delay > world.time)
return
+10 -25
View File
@@ -1,36 +1,21 @@
/obj/structure/blob/shield
/obj/effect/blob/shield
name = "strong blob"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_shield"
icon_state = "blob_idle"
desc = "A solid wall of slightly twitching tendrils."
obj_integrity = 150
max_integrity = 150
brute_resist = 0.25
health = 150
maxhealth = 150
brute_resist = 0.1
explosion_block = 3
point_return = 4
atmosblock = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 90, acid = 90)
/obj/effect/blob/shield/scannerreport()
return "Will prevent the spread of atmospheric changes."
/obj/structure/blob/shield/scannerreport()
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)
return
/obj/structure/blob/shield/core
/obj/effect/blob/shield/core
point_return = 0
/obj/structure/blob/shield/update_icon()
..()
if(obj_integrity <= 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)
+24 -35
View File
@@ -1,20 +1,17 @@
/mob/camera/blob
name = "Blob Overmind"
real_name = "Blob Overmind"
desc = "The overmind. It controls the blob."
icon = 'icons/mob/blob.dmi'
icon_state = "marker"
mouse_opacity = 1
move_on_shuttle = 1
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
invisibility = INVISIBILITY_OBSERVER
layer = FLY_LAYER
pass_flags = PASSBLOB
faction = list("blob")
var/obj/structure/blob/core/blob_core = null // The blob overmind's core
var/obj/effect/blob/core/blob_core = null // The blob overmind's core
var/blob_points = 0
var/max_blob_points = 100
var/last_attack = 0
@@ -29,8 +26,7 @@
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
/mob/camera/blob/New(loc, pre_placed = 0, mode_made = 0, starting_points = 60)
blob_points = starting_points
/mob/camera/blob/New(loc, pre_placed = 0, mode_made = 0)
if(pre_placed) //we already have a core!
manualplace_min_time = 0
autoplace_max_time = 0
@@ -46,9 +42,10 @@
name = new_name
real_name = new_name
last_attack = world.time
var/datum/reagent/blob/BC = pick((subtypesof(/datum/reagent/blob)))
blob_reagent_datum = new BC
color = blob_reagent_datum.complementary_color
var/list/possible_reagents = list()
for(var/type in (subtypesof(/datum/reagent/blob)))
possible_reagents.Add(new type)
blob_reagent_datum = pick(possible_reagents)
if(blob_core)
blob_core.update_icon()
@@ -72,20 +69,19 @@
/mob/camera/blob/Destroy()
for(var/BL in blobs)
var/obj/structure/blob/B = BL
if(B && B.overmind == src)
var/obj/effect/blob/B = BL
if(B.overmind == src)
B.overmind = null
B.update_icon() //reset anything that was ours
for(var/BLO in blob_mobs)
var/mob/living/simple_animal/hostile/blob/BM = BLO
if(BM)
BM.overmind = null
BM.update_icons()
BM.overmind = null
BM.update_icons()
overminds -= src
if(ghostimage)
ghost_darkness_images -= ghostimage
qdel(ghostimage)
ghostimage = null
ghostimage = null;
updateallghostimages()
return ..()
@@ -95,23 +91,18 @@
src << "<span class='notice'>You are the overmind!</span>"
blob_help()
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()
if(blob_core)
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#e36600'>[round(blob_core.obj_integrity)]</font></div>"
hud_used.healths.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#e36600'>[round(blob_core.health)]</font></div>"
for(var/mob/living/simple_animal/hostile/blob/blobbernaut/B in blob_mobs)
if(B.hud_used && B.hud_used.blobpwrdisplay)
B.hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_core.obj_integrity)]</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)
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>"
if(points != 0)
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(src.blob_points)]</font></div>"
/mob/camera/blob/say(message)
if (!message)
@@ -150,20 +141,15 @@
/mob/camera/blob/emote(act,m_type=1,message = null)
return
/mob/camera/blob/blob_act(obj/structure/blob/B)
/mob/camera/blob/blob_act(obj/effect/blob/B)
return
/mob/camera/blob/Stat()
..()
if(statpanel("Status"))
if(blob_core)
stat(null, "Core Health: [blob_core.obj_integrity]")
stat(null, "Core Health: [blob_core.health]")
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)
stat(null, "You have [free_chem_rerolls] Free Chemical Reroll\s Remaining")
if(!placed)
@@ -173,14 +159,17 @@
/mob/camera/blob/Move(NewLoc, Dir = 0)
if(placed)
var/obj/structure/blob/B = locate() in range("3x3", NewLoc)
var/obj/effect/blob/B = locate() in range("3x3", NewLoc)
if(B)
loc = NewLoc
else
return 0
else
var/area/A = get_area(NewLoc)
if(isspaceturf(NewLoc) || istype(A, /area/shuttle)) //if unplaced, can't go on shuttles or space tiles
if(istype(NewLoc, /turf/open/space) || istype(A, /area/shuttle)) //if unplaced, can't go on shuttles or space tiles
return 0
loc = NewLoc
return 1
/mob/camera/blob/proc/can_attack()
return (world.time > (last_attack + CLICK_CD_RANGE))
+46 -83
View File
@@ -28,13 +28,13 @@
src << "<span class='warning'>This spot is too dense to place a blob core on!</span>"
return 0
for(var/obj/O in T)
if(istype(O, /obj/structure/blob))
if(istype(O, /obj/structure/blob/normal))
if(istype(O, /obj/effect/blob))
if(istype(O, /obj/effect/blob/normal))
qdel(O)
else
src << "<span class='warning'>There is already a blob here!</span>"
return 0
else if(O.density)
if(O.density)
src << "<span class='warning'>This spot is too dense to place a blob core on!</span>"
return 0
if(world.time <= manualplace_min_time && world.time <= autoplace_max_time)
@@ -46,7 +46,7 @@
if(placed && blob_core)
blob_core.forceMove(loc)
else
var/obj/structure/blob/core/core = new(get_turf(src), null, point_rate, 1)
var/obj/effect/blob/core/core = new(get_turf(src), null, point_rate, 1)
core.overmind = src
blob_core = core
core.update_icon()
@@ -67,36 +67,35 @@
set desc = "Move your camera to a selected node."
if(blob_nodes.len)
var/list/nodes = list()
for(var/i in 1 to blob_nodes.len)
var/obj/structure/blob/node/B = blob_nodes[i]
nodes["Blob Node #[i] ([B.overmind ? "[B.overmind.blob_reagent_datum.name]":"No Chemical"])"] = B
for(var/i = 1; i <= blob_nodes.len; i++)
nodes["Blob Node #[i]"] = blob_nodes[i]
var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes
var/obj/structure/blob/node/chosen_node = nodes[node_name]
var/obj/effect/blob/node/chosen_node = nodes[node_name]
if(chosen_node)
loc = chosen_node.loc
src.loc = chosen_node.loc
/mob/camera/blob/proc/createSpecial(price, blobType, nearEquals, needsNode, turf/T)
if(!T)
T = get_turf(src)
var/obj/structure/blob/B = (locate(/obj/structure/blob) in T)
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
if(!B)
src << "<span class='warning'>There is no blob here!</span>"
return
if(!istype(B, /obj/structure/blob/normal))
if(!istype(B, /obj/effect/blob/normal))
src << "<span class='warning'>Unable to use this blob, find a normal one.</span>"
return
if(needsNode && nodes_required)
if(!(locate(/obj/structure/blob/node) in orange(3, T)) && !(locate(/obj/structure/blob/core) in orange(4, T)))
if(!(locate(/obj/effect/blob/node) in orange(3, T)) && !(locate(/obj/effect/blob/core) in orange(4, T)))
src << "<span class='warning'>You need to place this blob closer to a node or core!</span>"
return //handholdotron 2000
if(nearEquals)
for(var/obj/structure/blob/L in orange(nearEquals, T))
for(var/obj/effect/blob/L in orange(nearEquals, T))
if(L.type == blobType)
src << "<span class='warning'>There is a similar blob nearby, move more than [nearEquals] tiles away from it!</span>"
return
if(!can_buy(price))
return
var/obj/structure/blob/N = B.change_to(blobType, src)
var/obj/effect/blob/N = B.change_to(blobType, src)
return N
/mob/camera/blob/verb/toggle_node_req()
@@ -111,51 +110,50 @@
/mob/camera/blob/verb/create_shield_power()
set category = "Blob"
set name = "Create Shield Blob (15)"
set name = "Create Shield Blob (10)"
set desc = "Create a shield blob, which will block fire and is hard to kill."
create_shield()
/mob/camera/blob/proc/create_shield(turf/T)
createSpecial(15, /obj/structure/blob/shield, 0, 0, T)
createSpecial(10, /obj/effect/blob/shield, 0, 0, T)
/mob/camera/blob/verb/create_resource()
set category = "Blob"
set name = "Create Resource Blob (40)"
set desc = "Create a resource tower which will generate resources for you."
createSpecial(40, /obj/structure/blob/resource, 4, 1)
createSpecial(40, /obj/effect/blob/resource, 4, 1)
/mob/camera/blob/verb/create_node()
set category = "Blob"
set name = "Create Node Blob (50)"
set name = "Create Node Blob (60)"
set desc = "Create a node, which will power nearby factory and resource blobs."
createSpecial(50, /obj/structure/blob/node, 5, 0)
createSpecial(60, /obj/effect/blob/node, 5, 0)
/mob/camera/blob/verb/create_factory()
set category = "Blob"
set name = "Create Factory Blob (60)"
set desc = "Create a spore tower that will spawn spores to harass your enemies."
createSpecial(60, /obj/structure/blob/factory, 7, 1)
createSpecial(60, /obj/effect/blob/factory, 7, 1)
/mob/camera/blob/verb/create_blobbernaut()
set category = "Blob"
set name = "Create Blobbernaut (40)"
set desc = "Create a powerful blobbernaut which is mildly smart and will attack enemies."
var/turf/T = get_turf(src)
var/obj/structure/blob/factory/B = locate(/obj/structure/blob/factory) in T
var/obj/effect/blob/factory/B = locate(/obj/effect/blob/factory) in T
if(!B)
src << "<span class='warning'>You must be on a factory blob!</span>"
return
if(B.naut) //if it already made a blobbernaut, it can't do it again
src << "<span class='warning'>This factory blob is already sustaining a blobbernaut.</span>"
return
if(B.obj_integrity < B.max_integrity * 0.5)
if(B.health < B.maxhealth * 0.5)
src << "<span class='warning'>This factory blob is too damaged to sustain a blobbernaut.</span>"
return
if(!can_buy(40))
return
B.max_integrity = initial(B.max_integrity) * 0.25 //factories that produced a blobbernaut have much lower health
B.obj_integrity = min(B.obj_integrity, B.max_integrity)
B.update_icon()
B.maxhealth = initial(B.maxhealth) * 0.25 //factories that produced a blobbernaut have much lower health
B.check_health()
B.visible_message("<span class='warning'><b>The blobbernaut [pick("rips", "tears", "shreds")] its way out of the factory blob!</b></span>")
playsound(B.loc, 'sound/effects/splat.ogg', 50, 1)
var/mob/living/simple_animal/hostile/blob/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blob/blobbernaut(get_turf(B))
@@ -167,9 +165,11 @@
blobber.notransform = 1 //stop the naut from moving around
blobber.adjustHealth(blobber.maxHealth * 0.5)
blob_mobs += blobber
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50, blobber) //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.
var/client/C = pick(candidates)
C = pick(candidates)
blobber.notransform = 0
blobber.key = C.key
blobber << 'sound/effects/blobattack.ogg'
blobber << 'sound/effects/attackblob.ogg'
@@ -178,33 +178,23 @@
blobber << "You can communicate with other blobbernauts and overminds via <b>:b</b>"
blobber << "Your overmind's blob reagent is: <b><font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</b></font>!"
blobber << "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]"]"
if(blobber)
blobber.notransform = 0
else
blobber.notransform = 0 //otherwise, just let it move
/mob/camera/blob/verb/relocate_core()
set category = "Blob"
set name = "Relocate Core (80)"
set desc = "Swaps the locations of your core and the selected node."
var/turf/T = get_turf(src)
var/obj/structure/blob/node/B = locate(/obj/structure/blob/node) in T
var/obj/effect/blob/node/B = locate(/obj/effect/blob/node) in T
if(!B)
src << "<span class='warning'>You must be on a blob node!</span>"
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(isspaceturf(T) || A && !A.blob_allowed)
src << "<span class='warning'>You cannot relocate your core here!</span>"
return
if(!can_buy(80))
return
var/turf/old_turf = get_turf(blob_core)
var/olddir = blob_core.dir
blob_core.forceMove(T)
blob_core.setDir(B.dir)
B.forceMove(old_turf)
B.setDir(olddir)
var/turf/old_turf = blob_core.loc
blob_core.loc = T
B.loc = old_turf
/mob/camera/blob/verb/revert()
set category = "Blob"
@@ -214,7 +204,7 @@
remove_blob(T)
/mob/camera/blob/proc/remove_blob(turf/T)
var/obj/structure/blob/B = locate() in T
var/obj/effect/blob/B = locate() in T
if(!B)
src << "<span class='warning'>There is no blob there!</span>"
return
@@ -231,22 +221,21 @@
/mob/camera/blob/verb/expand_blob_power()
set category = "Blob"
set name = "Expand/Attack Blob (4)"
set name = "Expand/Attack Blob (5)"
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)
expand_blob(T)
/mob/camera/blob/proc/expand_blob(turf/T)
if(world.time < last_attack)
if(!can_attack())
return
var/list/possibleblobs = list()
for(var/obj/structure/blob/AB in range(T, 1))
possibleblobs += AB
if(!possibleblobs.len)
var/obj/effect/blob/OB = locate() in circlerange(T, 1)
if(!OB)
src << "<span class='warning'>There is no blob adjacent to the target tile!</span>"
return
if(can_buy(4))
if(can_buy(5))
var/attacksuccess = FALSE
last_attack = world.time
for(var/mob/living/L in T)
if("blob" in L.faction) //no friendly/dead fire
continue
@@ -255,37 +244,16 @@
var/mob_protection = L.get_permeability_protection()
blob_reagent_datum.reaction_mob(L, VAPOR, 25, 1, mob_protection, src)
blob_reagent_datum.send_message(L)
var/obj/structure/blob/B = locate() in T
var/obj/effect/blob/B = locate() in T
if(B)
if(attacksuccess) //if we successfully attacked a turf with a blob on it, don't refund shit
B.blob_attack_animation(T, src)
else
src << "<span class='warning'>There is a blob there!</span>"
add_points(4) //otherwise, refund all of the cost
add_points(5) //otherwise, refund all of the cost
return
else
var/list/cardinalblobs = list()
var/list/diagonalblobs = list()
for(var/I in possibleblobs)
var/obj/structure/blob/IB = I
if(get_dir(IB, T) in cardinal)
cardinalblobs += IB
else
diagonalblobs += IB
var/obj/structure/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
OB.expand(T, src)
/mob/camera/blob/verb/rally_spores_power()
set category = "Blob"
@@ -330,9 +298,8 @@
/mob/camera/blob/proc/set_chemical()
var/datum/reagent/blob/BC = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type))
blob_reagent_datum = new BC
color = blob_reagent_datum.complementary_color
for(var/BL in blobs)
var/obj/structure/blob/B = BL
var/obj/effect/blob/B = BL
B.update_icon()
for(var/BLO in blob_mobs)
var/mob/living/simple_animal/hostile/blob/BM = BLO
@@ -341,8 +308,6 @@
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 << "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()
set category = "Blob"
@@ -351,8 +316,6 @@
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 << "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 << "<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>"
@@ -366,4 +329,4 @@
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)
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 Place Blob Core 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 button in the bottom right corner of the screen.</font></span>"
+143 -133
View File
@@ -1,5 +1,5 @@
//I will need to recode parts of this but I am way too tired atm //I don't know who left this comment but they never did come back
/obj/structure/blob
/obj/effect/blob
name = "blob"
icon = 'icons/mob/blob.dmi'
luminosity = 1
@@ -7,37 +7,35 @@
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
anchored = 1
layer = BELOW_MOB_LAYER
explosion_block = 1
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.
obj_integrity = 30
max_integrity = 30
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 80, acid = 70)
var/health = 30
var/maxhealth = 30
var/health_regen = 2 //how much health this blob regens when pulsed
var/pulse_timestamp = 0 //we got pulsed when?
var/heal_timestamp = 0 //we got healed when?
var/pulse_timestamp = 0 //we got pulsed/healed when?
var/brute_resist = 0.5 //multiplies brute damage by this
var/fire_resist = 1 //multiplies burn damage by this
var/atmosblock = 0 //if the blob blocks atmos and heat spread
var/mob/camera/blob/overmind
/obj/structure/blob/New(loc)
/obj/effect/blob/New(loc)
var/area/Ablob = get_area(loc)
if(Ablob.blob_allowed) //Is this area allowed for winning as blob?
blobs_legit += src
blobs += src //Keep track of the blob in the normal list either way
setDir(pick(cardinal))
update_icon()
..()
src.setDir(pick(1, 2, 4, 8))
src.update_icon()
..(loc)
ConsumeTile()
if(atmosblock)
CanAtmosPass = ATMOS_PASS_NO
air_update_turf(1)
/obj/structure/blob/proc/creation_action() //When it's created by the overmind, do this.
return
/obj/structure/blob/Destroy()
/obj/effect/blob/proc/creation_action() //When it's created by the overmind, do this.
return
/obj/effect/blob/Destroy()
if(atmosblock)
atmosblock = 0
air_update_turf(1)
@@ -46,10 +44,8 @@
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Expand() is no longer broken, no check necessary.
return ..()
/obj/structure/blob/blob_act()
return
/obj/structure/blob/Adjacent(var/atom/neighbour)
/obj/effect/blob/Adjacent(var/atom/neighbour)
. = ..()
if(.)
var/result = 0
@@ -58,90 +54,89 @@
for(var/A in dirs)
if(direction == text2num(A))
for(var/B in dirs[A])
var/C = locate(/obj/structure/blob) in get_step(src, B)
var/C = locate(/obj/effect/blob) in get_step(src, B)
if(C)
result++
. -= result - 1
/obj/structure/blob/BlockSuperconductivity()
/obj/effect/blob/CanAtmosPass(turf/T)
return !atmosblock
/obj/effect/blob/BlockSuperconductivity()
return atmosblock
/obj/structure/blob/CanPass(atom/movable/mover, turf/target, height=0)
/obj/effect/blob/CanPass(atom/movable/mover, turf/target, height=0)
if(height==0)
return 1
if(istype(mover) && mover.checkpass(PASSBLOB))
return 1
return 0
/obj/structure/blob/CanAStarPass(ID, dir, caller)
/obj/effect/blob/CanAStarPass(ID, dir, caller)
. = 0
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSBLOB)
/obj/structure/blob/update_icon() //Updates color based on overmind color if we have an overmind.
if(overmind)
add_atom_colour(overmind.blob_reagent_datum.color, FIXED_COLOUR_PRIORITY)
else
remove_atom_colour(FIXED_COLOUR_PRIORITY)
/obj/structure/blob/process()
Life()
/obj/structure/blob/proc/Life()
/obj/effect/blob/proc/check_health(cause)
health = Clamp(health, 0, maxhealth)
if(health <= 0)
if(overmind)
overmind.blob_reagent_datum.death_reaction(src, cause)
qdel(src) //we dead now
return
return
/obj/structure/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
src.Be_Pulsed()
var/expanded = FALSE
if(prob(70) && expand())
expanded = TRUE
var/list/blobs_to_affect = list()
for(var/obj/structure/blob/B in urange(claim_range, src, 1))
blobs_to_affect += B
shuffle(blobs_to_affect)
for(var/L in blobs_to_affect)
var/obj/structure/blob/B = L
if(!B.overmind && !istype(B, /obj/structure/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/structure/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()
/obj/effect/blob/update_icon() //Updates color based on overmind color if we have an overmind.
if(overmind)
color = overmind.blob_reagent_datum.color
else
color = null
return
/obj/structure/blob/proc/Be_Pulsed()
/obj/effect/blob/process()
Life()
return
/obj/effect/blob/proc/Life()
return
/obj/effect/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
src.Be_Pulsed()
if(claim_range)
for(var/obj/effect/blob/B in urange(claim_range, src, 1))
if(!B.overmind && !istype(B, /obj/effect/blob/core) && prob(30))
B.overmind = pulsing_overmind //reclaim unclaimed, non-core blobs.
B.update_icon()
if(pulse_range)
for(var/obj/effect/blob/B in orange(pulse_range, src))
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()
if(pulse_timestamp <= world.time)
ConsumeTile()
if(heal_timestamp <= world.time)
obj_integrity = min(max_integrity, obj_integrity+health_regen)
heal_timestamp = world.time + 20
health = min(maxhealth, health+health_regen)
update_icon()
pulse_timestamp = world.time + 10
return 1 //we did it, we were pulsed!
return 0 //oh no we failed
/obj/structure/blob/proc/ConsumeTile()
/obj/effect/blob/proc/ConsumeTile()
for(var/atom/A in loc)
A.blob_act(src)
if(iswallturf(loc))
if(istype(loc, /turf/closed/wall))
loc.blob_act(src) //don't ask how a wall got on top of the core, just eat it
/obj/structure/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)
O.setDir(dir)
if(controller)
var/mob/camera/blob/BO = controller
O.color = BO.blob_reagent_datum.color
@@ -152,14 +147,14 @@
O.do_attack_animation(A) //visually attack the whatever
return O //just in case you want to do something to the animation.
/obj/structure/blob/proc/expand(turf/T = null, controller = null, expand_reaction = 1)
/obj/effect/blob/proc/expand(turf/T = null, controller = null, expand_reaction = 1)
if(!T)
var/list/dirs = list(1,2,4,8)
for(var/i = 1 to 4)
var/dirn = pick(dirs)
dirs.Remove(dirn)
T = get_step(src, dirn)
if(!(locate(/obj/structure/blob) in T))
if(!(locate(/obj/effect/blob) in T))
break
else
T = null
@@ -167,7 +162,7 @@
return 0
var/make_blob = TRUE //can we make a blob?
if(isspaceturf(T) && !(locate(/obj/structure/lattice) in T) && prob(80))
if(istype(T, /turf/open/space) && !(locate(/obj/structure/lattice) in T) && prob(80))
make_blob = FALSE
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Let's give some feedback that we DID try to spawn in space, since players are used to it
@@ -181,7 +176,7 @@
A.blob_act(src) //also hit everything in the turf
if(make_blob) //well, can we?
var/obj/structure/blob/B = new /obj/structure/blob/normal(src.loc)
var/obj/effect/blob/B = new /obj/effect/blob/normal(src.loc)
if(controller)
B.overmind = controller
else
@@ -192,7 +187,7 @@
B.loc = T
B.update_icon()
if(B.overmind && expand_reaction)
B.overmind.blob_reagent_datum.expand_reaction(src, B, T, controller)
B.overmind.blob_reagent_datum.expand_reaction(src, B, T)
return B
else
blob_attack_animation(T, controller)
@@ -203,30 +198,43 @@
blob_attack_animation(T, controller) //if we can't, animate that we attacked
return null
/obj/structure/blob/emp_act(severity)
/obj/effect/blob/ex_act(severity, target)
..()
var/damage = 150 - 20 * severity
take_damage(damage, BRUTE)
/obj/effect/blob/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
var/damage = Clamp(0.01 * exposed_temperature, 0, 4)
take_damage(damage, BURN)
/obj/effect/blob/emp_act(severity)
if(severity > 0)
if(overmind)
overmind.blob_reagent_datum.emp_reaction(src, severity)
if(prob(100 - severity * 30))
PoolOrNew(/obj/effect/overlay/temp/emp, get_turf(src))
/obj/structure/blob/tesla_act(power)
/obj/effect/blob/tesla_act(power)
..()
if(overmind)
if(overmind.blob_reagent_datum.tesla_reaction(src, power))
take_damage(power/400, BURN, "energy")
take_damage(power/400, BURN)
else
take_damage(power/400, BURN, "energy")
take_damage(power/400, BURN)
/obj/structure/blob/extinguish()
/obj/effect/blob/extinguish()
..()
if(overmind)
overmind.blob_reagent_datum.extinguish_reaction(src)
/obj/structure/blob/hulk_damage()
return 15
/obj/effect/blob/bullet_act(var/obj/item/projectile/Proj)
..()
take_damage(Proj.damage, Proj.damage_type, Proj)
return 0
/obj/structure/blob/attackby(obj/item/I, mob/user, params)
/obj/effect/blob/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/device/analyzer))
user.changeNext_move(CLICK_CD_MELEE)
user << "<b>The analyzer beeps once, then reports:</b><br>"
@@ -236,7 +244,7 @@
else
return ..()
/obj/structure/blob/proc/chemeffectreport(mob/user)
/obj/effect/blob/proc/chemeffectreport(mob/user)
if(overmind)
user << "<b>Material: <font color=\"[overmind.blob_reagent_datum.color]\">[overmind.blob_reagent_datum.name]</font><span class='notice'>.</span></b>"
user << "<b>Material Effects:</b> <span class='notice'>[overmind.blob_reagent_datum.analyzerdescdamage]</span>"
@@ -244,67 +252,69 @@
else
user << "<b>No Material Detected!</b><br>"
/obj/structure/blob/proc/typereport(mob/user)
/obj/effect/blob/proc/typereport(mob/user)
user << "<b>Blob Type:</b> <span class='notice'>[uppertext(initial(name))]</span>"
user << "<b>Health:</b> <span class='notice'>[obj_integrity]/[max_integrity]</span>"
user << "<b>Health:</b> <span class='notice'>[health]/[maxhealth]</span>"
user << "<b>Effects:</b> <span class='notice'>[scannerreport()]</span>"
/obj/structure/blob/attack_animal(mob/living/simple_animal/M)
/obj/effect/blob/attacked_by(obj/item/I, mob/living/user)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
visible_message("<span class='danger'>[user] has attacked the [src.name] with \the [I]!</span>")
if(I.damtype == BURN)
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
take_damage(I.force, I.damtype, user)
/obj/effect/blob/attack_animal(mob/living/simple_animal/M)
if("blob" in M.faction) //sorry, but you can't kill the blob as a blobbernaut
return
..()
M.changeNext_move(CLICK_CD_MELEE)
M.do_attack_animation(src)
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
visible_message("<span class='danger'>\The [M] has attacked the [src.name]!</span>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
take_damage(damage, M.melee_damage_type, M)
return
/obj/structure/blob/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
if(damage_amount)
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
else
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
/obj/effect/blob/attack_alien(mob/living/carbon/alien/humanoid/M)
M.changeNext_move(CLICK_CD_MELEE)
M.do_attack_animation(src)
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
visible_message("<span class='danger'>[M] has slashed the [src.name]!</span>")
var/damage = rand(15, 30)
take_damage(damage, BRUTE, M)
return
/obj/structure/blob/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
switch(damage_type)
/obj/effect/blob/proc/take_damage(damage, damage_type, cause = null, overmind_reagent_trigger = 1)
switch(damage_type) //blobs only take brute and burn damage
if(BRUTE)
damage_amount *= brute_resist
damage = max(damage * brute_resist, 0)
if(BURN)
damage_amount *= fire_resist
if(CLONE)
damage = max(damage * fire_resist, 0)
if(CLONE) //this is basically a marker for 'don't modify the damage'
else
return 0
var/armor_protection = 0
if(damage_flag)
armor_protection = armor[damage_flag]
damage_amount = round(damage_amount * (100 - armor_protection)*0.01, 0.1)
if(overmind && damage_flag)
damage_amount = overmind.blob_reagent_datum.damage_reaction(src, damage_amount, damage_type, damage_flag)
return damage_amount
damage = 0
if(overmind && overmind_reagent_trigger)
damage = overmind.blob_reagent_datum.damage_reaction(src, health, damage, damage_type, cause) //pass the blob, its health before damage, the damage being done, the type of damage being done, and the cause.
health -= damage
update_icon()
check_health(cause)
/obj/structure/blob/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(. && obj_integrity > 0)
update_icon()
/obj/structure/blob/obj_destruction(damage_flag)
if(overmind)
overmind.blob_reagent_datum.death_reaction(src, damage_flag)
..()
/obj/structure/blob/proc/change_to(type, controller)
/obj/effect/blob/proc/change_to(type, controller)
if(!ispath(type))
throw EXCEPTION("change_to(): invalid type for blob")
return
var/obj/structure/blob/B = new type(src.loc)
var/obj/effect/blob/B = new type(src.loc)
if(controller)
B.overmind = controller
B.creation_action()
B.update_icon()
B.setDir(dir)
qdel(src)
return B
/obj/structure/blob/examine(mob/user)
/obj/effect/blob/examine(mob/user)
..()
var/datum/atom_hud/hud_to_check = huds[DATA_HUD_MEDICAL_ADVANCED]
if(user.research_scanner || (user in hud_to_check.hudusers))
@@ -314,31 +324,31 @@
else
user << "It seems to be made of [get_chem_name()]."
/obj/structure/blob/proc/scannerreport()
/obj/effect/blob/proc/scannerreport()
return "A generic blob. Looks like someone forgot to override this proc, adminhelp this."
/obj/structure/blob/proc/get_chem_name()
/obj/effect/blob/proc/get_chem_name()
if(overmind)
return overmind.blob_reagent_datum.name
return "an unknown variant"
/obj/structure/blob/normal
/obj/effect/blob/normal
name = "normal blob"
icon_state = "blob"
luminosity = 0
obj_integrity = 21
max_integrity = 25
health = 21
maxhealth = 25
health_regen = 1
brute_resist = 0.25
/obj/structure/blob/normal/scannerreport()
if(obj_integrity <= 15)
/obj/effect/blob/normal/scannerreport()
if(health <= 10)
return "Currently weak to brute damage."
return "N/A"
/obj/structure/blob/normal/update_icon()
/obj/effect/blob/normal/update_icon()
..()
if(obj_integrity <= 15)
if(health <= 10)
icon_state = "blob_damaged"
name = "fragile blob"
desc = "A thin lattice of slightly twitching tendrils."