mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-19 22:51:20 +00:00
Nerfs blob rollercoaster of death by making it so that blobs cannot interact with the mobs inside of other blobs. Replaces blob's gibbing mobs with husking humans, merely killing borgs, and gibbing everything else. Makes flamethrowers modestly more effective versus blobs - a consistent source of minor AoE damage. Makes blobs more aesthetically pleasing. Distinguishes the main core from the aux cores slightly more. Fixes #1426 Fixes #1427 Fixes #1432 Fixes #1461 Fixes #1464 Fixes #1471 Modifies BFG's to be more like actual BFG's. Fixes Industrial IPCs being able to select Baseline IPC screens. Fixes several baycode company names to fit ours in guns. Changes several of our guns to fit Baycode's naming paradigm.
321 lines
8.9 KiB
Plaintext
321 lines
8.9 KiB
Plaintext
//I will need to recode parts of this but I am way too tired atm
|
|
/obj/effect/blob
|
|
name = "blob"
|
|
icon = 'icons/mob/blob.dmi'
|
|
icon_state = "blob"
|
|
light_range = 3
|
|
light_color = "#b5ff5b"
|
|
desc = "Some blob creature thingy"
|
|
density = 1
|
|
opacity = 0
|
|
anchored = 1
|
|
mouse_opacity = 2
|
|
layer = 4
|
|
|
|
var/maxHealth = 30
|
|
var/health
|
|
var/regen_rate = 5
|
|
var/brute_resist = 4
|
|
var/laser_resist = 4 // Special resist for laser based weapons - Emitters or handheld energy weaponry. Damage is divided by this and THEN by fire_resist.
|
|
var/fire_resist = 1
|
|
var/secondary_core_growth_chance = 10.0 //% chance to grow a secondary blob core instead of whatever was suposed to grown. Secondary cores are considerably weaker, but still nasty.
|
|
var/expandType = /obj/effect/blob
|
|
var/obj/effect/blob/core/parent_core = null
|
|
var/growth_range = 0
|
|
var/blob_may_process = 1
|
|
var/hangry = 0 //if the blob will attack or not.
|
|
|
|
/obj/effect/blob/New(loc)
|
|
processing_objects.Add(src)
|
|
health = maxHealth
|
|
var/matrix/M = matrix()
|
|
M.Turn(90 * pick(0,1,2,3))
|
|
src.transform = M
|
|
update_icon()
|
|
return ..(loc)
|
|
|
|
/obj/effect/blob/Destroy()
|
|
processing_objects.Remove(src)
|
|
..()
|
|
|
|
/obj/effect/blob/process()
|
|
if(!parent_core)
|
|
src.take_damage(5)
|
|
src.regen_rate = -5
|
|
src.growth_range = 0
|
|
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
|
return
|
|
|
|
if(prob(70))
|
|
for(var/mob/living/L in src.loc)
|
|
if(L.stat == DEAD)
|
|
if(prob(10))
|
|
if(istype(L, /mob/living/carbon/human))
|
|
var/mob/living/carbon/human/H = L
|
|
H.ChangeToHusk()
|
|
else if(istype(L, /mob/living/silicon))
|
|
continue
|
|
else
|
|
L.gib()
|
|
if(health < maxHealth)
|
|
health += rand(10,30)
|
|
if(health > maxHealth)
|
|
health = maxHealth
|
|
continue
|
|
L.visible_message("<span class='danger'>The blob absorbs \the [L]!</span>", "<span class='danger'>The blob absorbs you!</span>")
|
|
playsound(loc, 'sound/effects/attackblob.ogg', 50, 1)
|
|
L.take_organ_damage(rand(5, 10))
|
|
if(health < maxHealth)
|
|
health += rand(1,10)
|
|
if(health > maxHealth)
|
|
health = maxHealth
|
|
hangry += 16
|
|
|
|
for(var/mob/living/L in range(src,"3x3"))
|
|
var/obj/effect/blob/B = (locate() in get_turf(L))
|
|
if(!B)
|
|
if(!hangry)
|
|
if(L.stat == DEAD)
|
|
continue
|
|
if(prob(40))
|
|
L.visible_message("<span class='danger'>The blob sucks \the [L] into itself!</span>", "<span class='danger'>The blob sucks you in!</span>")
|
|
playsound(loc, 'sound/effects/attackblob.ogg', 50, 1)
|
|
L.take_organ_damage(rand(5, 10))
|
|
L.forceMove(src.loc)
|
|
else
|
|
L.visible_message("<span class='danger'>The blob glomps \the [L]!</span>", "<span class='danger'>The blob glomps you!</span>")
|
|
playsound(loc, 'sound/effects/attackblob.ogg', 50, 1)
|
|
L.take_organ_damage(rand(5, 20))
|
|
if(health < maxHealth)
|
|
health += rand(1,10)
|
|
if(health > maxHealth)
|
|
health = maxHealth
|
|
hangry += 4
|
|
|
|
for(var/obj/fire/F in range(src,"3x3")) //very snowflake, but much better than actually coding complex thermodynamics for these fuckers
|
|
if(prob(50))
|
|
src.visible_message("<span class='danger'>The blob melts away under the heat of the flames!</span>")
|
|
src.take_damage(5,10)
|
|
hangry -= 1
|
|
if(hangry < 0)
|
|
hangry = 0
|
|
|
|
/obj/effect/blob/CanPass(var/atom/movable/mover, vra/turf/target, var/height = 0, var/air_group = 0)
|
|
if(air_group || height == 0)
|
|
return 1
|
|
return 0
|
|
|
|
/obj/effect/blob/ex_act(var/severity)
|
|
switch(severity)
|
|
if(1)
|
|
take_damage(rand(100, 120) / brute_resist)
|
|
if(2)
|
|
take_damage(rand(60, 100) / brute_resist)
|
|
if(3)
|
|
take_damage(rand(20, 60) / brute_resist)
|
|
|
|
/obj/effect/blob/update_icon()
|
|
if(health > maxHealth / 2)
|
|
icon_state = "blob"
|
|
else
|
|
icon_state = "blob_damaged"
|
|
|
|
/obj/effect/blob/proc/take_damage(var/damage)
|
|
health -= damage
|
|
if(health < 0)
|
|
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
|
qdel(src)
|
|
else
|
|
update_icon()
|
|
|
|
/obj/effect/blob/proc/regen()
|
|
health = min(health + regen_rate, maxHealth)
|
|
update_icon()
|
|
|
|
/obj/effect/blob/proc/expand(var/turf/T)
|
|
if(istype(T, /turf/unsimulated/) || istype(T, /turf/space) || (istype(T, /turf/simulated/mineral) && T.density))
|
|
return
|
|
if(istype(T, /turf/simulated/wall))
|
|
var/turf/simulated/wall/SW = T
|
|
SW.ex_act(2)
|
|
return
|
|
|
|
for(var/obj/O in T)
|
|
if(O.density)
|
|
O.ex_act(2)
|
|
return
|
|
|
|
// Above things, we destroy completely and thus can use locate. Mobs are different.
|
|
for(var/mob/living/L in T)
|
|
if(L.stat == DEAD)
|
|
continue
|
|
if(prob(30))
|
|
L.visible_message("<span class='danger'>The blob sucks \the [L] into itself!</span>", "<span class='danger'>The blob sucks you in!</span>")
|
|
playsound(loc, 'sound/effects/attackblob.ogg', 50, 1)
|
|
L.take_organ_damage(rand(5, 10))
|
|
L.forceMove(src.loc)
|
|
else
|
|
L.visible_message("<span class='danger'>The blob pulverizes \the [L]!</span>", "<span class='danger'>The blob pulverizes you!</span>")
|
|
playsound(loc, 'sound/effects/attackblob.ogg', 50, 1)
|
|
L.take_organ_damage(rand(30, 40))
|
|
if(health < maxHealth)
|
|
health += rand(1,10)
|
|
if(health > maxHealth)
|
|
health = maxHealth
|
|
return
|
|
|
|
if(parent_core)
|
|
if(get_dist(T,src) <= parent_core.growth_range)
|
|
if(!(locate(/obj/effect/blob/core/) in range(T, 2)) && prob(secondary_core_growth_chance) && (parent_core.core_count < parent_core.core_limit))
|
|
var/obj/effect/blob/core/secondary/S = new /obj/effect/blob/core/secondary(T)
|
|
S.parent_core = src.parent_core
|
|
src.parent_core.core_count += 1
|
|
else
|
|
var/obj/effect/blob/C = new expandType(T)
|
|
C.parent_core = src.parent_core
|
|
|
|
/obj/effect/blob/proc/pulse(var/forceLeft, var/list/dirs)
|
|
regen()
|
|
sleep(4)
|
|
var/pushDir = pick(dirs)
|
|
var/turf/T = get_step(src, pushDir)
|
|
var/obj/effect/blob/B = (locate() in T)
|
|
if(!B)
|
|
if(prob(health+60))
|
|
expand(T)
|
|
return
|
|
if(forceLeft)
|
|
B.pulse(forceLeft - 1, dirs)
|
|
|
|
/obj/effect/blob/bullet_act(var/obj/item/projectile/Proj)
|
|
if(!Proj)
|
|
return
|
|
|
|
switch(Proj.damage_type)
|
|
if(BRUTE)
|
|
take_damage(Proj.damage / brute_resist)
|
|
if(BURN)
|
|
take_damage((Proj.damage / laser_resist) / fire_resist)
|
|
return 0
|
|
|
|
/obj/effect/blob/attackby(var/obj/item/weapon/W, var/mob/user)
|
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
user.do_attack_animation(src)
|
|
playsound(loc, 'sound/effects/attackblob.ogg', 50, 1)
|
|
visible_message("<span class='danger'>\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
|
|
var/damage = 0
|
|
switch(W.damtype)
|
|
if("fire")
|
|
damage = (W.force / fire_resist)
|
|
if(istype(W, /obj/item/weapon/weldingtool))
|
|
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
|
|
if("brute")
|
|
if(prob(30))
|
|
visible_message("<span class='danger'>\The [W] gets caught in the gelatinous folds of \the [src]</span>")
|
|
user.drop_from_inventory(W)
|
|
W.forceMove(src.loc)
|
|
return
|
|
damage = (W.force / brute_resist)
|
|
|
|
take_damage(damage)
|
|
return
|
|
|
|
/obj/effect/blob/core
|
|
name = "blob core"
|
|
icon = 'icons/mob/blob.dmi'
|
|
icon_state = "blob_core"
|
|
light_range = 1
|
|
light_power = 2
|
|
light_color = "#F3D203"
|
|
maxHealth = 200
|
|
brute_resist = 2
|
|
laser_resist = 7
|
|
regen_rate = 2
|
|
fire_resist = 2
|
|
var/core_count //amount of secondary cores
|
|
var/core_limit = 4 //for if a badmin ever wants the station to die, they can set this higher
|
|
|
|
expandType = /obj/effect/blob/shield
|
|
growth_range = 10 // Maximal distance for new blob pieces from this core.
|
|
|
|
/obj/effect/blob/core/New()
|
|
if(!parent_core)
|
|
parent_core = src
|
|
..()
|
|
|
|
/obj/effect/blob/core/update_icon()
|
|
var/health_percent = (health / maxHealth) * 100
|
|
switch(health_percent)
|
|
if(66 to INFINITY)
|
|
icon_state = "blob_core"
|
|
if(33 to 66)
|
|
icon_state = "blob_node"
|
|
if(-INFINITY to 33)
|
|
icon_state = "blob_factory"
|
|
|
|
/obj/effect/blob/core/process()
|
|
set waitfor = 0
|
|
..()
|
|
if(!blob_may_process)
|
|
return
|
|
blob_may_process = 0
|
|
sleep(0)
|
|
pulse(20, list(NORTH, EAST))
|
|
pulse(20, list(NORTH, WEST))
|
|
pulse(20, list(SOUTH, EAST))
|
|
pulse(20, list(SOUTH, WEST))
|
|
blob_may_process = 1
|
|
|
|
// Half the stats of a normal core. Blob has a very small probability of growing these when spreading. These will spread the blob further.
|
|
/obj/effect/blob/core/secondary
|
|
name = "small blob core"
|
|
icon = 'icons/mob/blob.dmi'
|
|
icon_state = "blob_core"
|
|
maxHealth = 100
|
|
brute_resist = 1
|
|
fire_resist = 1
|
|
laser_resist = 4
|
|
regen_rate = 1
|
|
growth_range = 3
|
|
expandType = /obj/effect/blob
|
|
|
|
/obj/effect/blob/core/secondary/New()
|
|
processing_objects.Add(src)
|
|
health = maxHealth
|
|
update_icon()
|
|
return ..(loc)
|
|
|
|
/obj/effect/blob/core/secondary/Destroy()
|
|
if(parent_core)
|
|
parent_core.core_count -= 1
|
|
..()
|
|
|
|
/obj/effect/blob/shield
|
|
name = "strong blob"
|
|
icon = 'icons/mob/blob.dmi'
|
|
icon_state = "blob_idle"
|
|
maxHealth = 60
|
|
brute_resist = 1
|
|
fire_resist = 2
|
|
laser_resist = 5
|
|
|
|
/obj/effect/blob/shield/New()
|
|
update_nearby_tiles()
|
|
..()
|
|
|
|
/obj/effect/blob/shield/Destroy()
|
|
density = 0
|
|
update_nearby_tiles()
|
|
..()
|
|
|
|
/obj/effect/blob/shield/update_icon()
|
|
if(health > maxHealth * 2 / 3)
|
|
icon_state = "blob_idle"
|
|
else if(health > maxHealth / 3)
|
|
icon_state = "blob"
|
|
else
|
|
icon_state = "blob_damaged"
|
|
|
|
/obj/effect/blob/shield/CanPass(var/atom/movable/mover, var/turf/target, var/height = 0, var/air_group = 0)
|
|
return !density
|