//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 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)) L.gib() if(health < maxHealth) health += rand(10,30) if(health > maxHealth) health = maxHealth continue L.visible_message("The blob absorbs \the [L]!", "The blob absorbs you!") 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")) if(!hangry) if(L.stat == DEAD) continue if(prob(40)) L.visible_message("The blob sucks \the [L] into itself!", "The blob sucks you in!") playsound(loc, 'sound/effects/attackblob.ogg', 50, 1) L.take_organ_damage(rand(5, 10)) L.forceMove(src.loc) else L.visible_message("The blob glomps \the [L]!", "The blob glomps you!") 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 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("The blob sucks \the [L] into itself!", "The blob sucks you in!") playsound(loc, 'sound/effects/attackblob.ogg', 50, 1) L.take_organ_damage(rand(5, 10)) L.forceMove(src.loc) else L.visible_message("The blob pulverizes \the [L]!", "The blob pulverizes you!") 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("\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]") 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("\The [W] gets caught in the gelatinous folds of \the [src]") 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 /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" opacity = 1 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