mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-17 05:03:28 +00:00
Removes a lot of copypaste of the checks for the blob verbs to create special blob structures. Blobs without an overmind will stop runtiming.
245 lines
6.4 KiB
Plaintext
245 lines
6.4 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'
|
|
luminosity = 3
|
|
desc = "Some blob creature thingy"
|
|
density = 0
|
|
opacity = 0
|
|
anchored = 1
|
|
var/health = 30
|
|
var/health_timestamp = 0
|
|
var/brute_resist = 4
|
|
var/fire_resist = 1
|
|
var/mob/camera/blob/overmind
|
|
|
|
|
|
/obj/effect/blob/New(loc)
|
|
blobs += src
|
|
src.dir = pick(1, 2, 4, 8)
|
|
src.update_icon()
|
|
..(loc)
|
|
for(var/atom/A in loc)
|
|
A.blob_act()
|
|
return
|
|
|
|
|
|
/obj/effect/blob/Destroy()
|
|
blobs -= src
|
|
if(isturf(loc)) //Necessary because Expand() is retarded and spawns a blob and then deletes it
|
|
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
|
|
..()
|
|
|
|
|
|
/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/effect/blob/process()
|
|
Life()
|
|
return
|
|
|
|
/obj/effect/blob/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
|
..()
|
|
var/damage = Clamp(0.01 * exposed_temperature, 0, 4)
|
|
take_damage(damage, BURN)
|
|
|
|
/obj/effect/blob/proc/Life()
|
|
return
|
|
|
|
/obj/effect/blob/proc/PulseAnimation()
|
|
if(!istype(src, /obj/effect/blob/core) || !istype(src, /obj/effect/blob/node))
|
|
flick("[icon_state]_glow", src)
|
|
return
|
|
|
|
/obj/effect/blob/proc/RegenHealth()
|
|
// All blobs heal over time when pulsed, but it has a cool down
|
|
if(health_timestamp > world.time)
|
|
return 0
|
|
if(health < initial(health))
|
|
health++
|
|
update_icon()
|
|
health_timestamp = world.time + 10 // 1 seconds
|
|
|
|
/obj/effect/blob/proc/pulseLoop(num)
|
|
var/a_color
|
|
if(overmind)
|
|
a_color = overmind.blob_reagent_datum.color
|
|
for(var/i = 1; i < 8; i += i)
|
|
Pulse(num, i, a_color)
|
|
|
|
/obj/effect/blob/proc/Pulse(pulse = 0, origin_dir = 0, a_color)//Todo: Fix spaceblob expand
|
|
|
|
set background = BACKGROUND_ENABLED
|
|
|
|
PulseAnimation()
|
|
|
|
RegenHealth()
|
|
|
|
if(run_action())//If we can do something here then we dont need to pulse more
|
|
return
|
|
|
|
if(pulse > 30)
|
|
return//Inf loop check
|
|
|
|
//Looking for another blob to pulse
|
|
var/list/dirs = list(1,2,4,8)
|
|
dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
|
|
for(var/i = 1 to 4)
|
|
if(!dirs.len) break
|
|
var/dirn = pick(dirs)
|
|
dirs.Remove(dirn)
|
|
var/turf/T = get_step(src, dirn)
|
|
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
|
|
if(!B)
|
|
expand(T,1,a_color)//No blob here so try and expand
|
|
return
|
|
B.adjustcolors(a_color)
|
|
|
|
B.Pulse((pulse+1),get_dir(src.loc,T), a_color)
|
|
return
|
|
return
|
|
|
|
|
|
/obj/effect/blob/proc/run_action()
|
|
return 0
|
|
|
|
|
|
/obj/effect/blob/proc/expand(turf/T = null, prob = 1, a_color)
|
|
if(prob && !prob(health)) return
|
|
if(istype(T, /turf/space) && prob(75)) return
|
|
if(!T)
|
|
var/list/dirs = list(1,2,4,8)
|
|
for(var/i = 1 to 4)
|
|
var/dirn = pick(dirs)
|
|
dirs.Remove(dirn)
|
|
T = get_step(src, dirn)
|
|
if(!(locate(/obj/effect/blob) in T)) break
|
|
else T = null
|
|
|
|
if(!T) return 0
|
|
var/obj/effect/blob/normal/B = new /obj/effect/blob/normal(src.loc, min(src.health, 30))
|
|
B.color = a_color
|
|
B.density = 1
|
|
if(T.Enter(B,src))//Attempt to move into the tile
|
|
B.density = initial(B.density)
|
|
B.loc = T
|
|
else
|
|
T.blob_act()//If we cant move in hit the turf
|
|
B.loc = null //So we don't play the splat sound, see Destroy()
|
|
qdel(B)
|
|
|
|
for(var/atom/A in T)//Hit everything in the turf
|
|
A.blob_act()
|
|
return 1
|
|
|
|
/obj/effect/blob/ex_act(severity, target)
|
|
..()
|
|
var/damage = 150 - 20 * severity
|
|
take_damage(damage, BRUTE)
|
|
|
|
/obj/effect/blob/bullet_act(var/obj/item/projectile/Proj)
|
|
..()
|
|
take_damage(Proj.damage, Proj.damage_type)
|
|
return 0
|
|
|
|
/obj/effect/blob/Crossed(mob/living/L)
|
|
..()
|
|
L.blob_act()
|
|
|
|
|
|
/obj/effect/blob/attackby(obj/item/weapon/W, mob/living/user, params)
|
|
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 [W]!</span>")
|
|
if(W.damtype == BURN)
|
|
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
|
|
take_damage(W.force, W.damtype)
|
|
|
|
/obj/effect/blob/attack_animal(mob/living/simple_animal/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'>\The [M] has attacked the [src.name]!</span>")
|
|
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
|
take_damage(damage, BRUTE)
|
|
return
|
|
|
|
/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)
|
|
return
|
|
|
|
/obj/effect/blob/proc/take_damage(damage, damage_type)
|
|
if(!damage || damage_type == STAMINA) // Avoid divide by zero errors
|
|
return
|
|
switch(damage_type)
|
|
if(BRUTE)
|
|
damage /= max(brute_resist, 1)
|
|
if(BURN)
|
|
damage /= max(fire_resist, 1)
|
|
health -= damage
|
|
update_icon()
|
|
|
|
/obj/effect/blob/proc/change_to(type)
|
|
if(!ispath(type))
|
|
throw EXCEPTION("change_to(): invalid type for blob")
|
|
return
|
|
var/obj/effect/blob/B = new type(src.loc)
|
|
if(!istype(type, /obj/effect/blob/core) || !istype(type, /obj/effect/blob/node))
|
|
B.color = color
|
|
else
|
|
B.adjustcolors(color)
|
|
qdel(src)
|
|
return B
|
|
|
|
/obj/effect/blob/proc/adjustcolors(a_color)
|
|
if(a_color)
|
|
color = a_color
|
|
return
|
|
|
|
/obj/effect/blob/examine(mob/user)
|
|
..()
|
|
user << "It looks like it's of a [get_chem_name()] kind."
|
|
return
|
|
|
|
/obj/effect/blob/proc/get_chem_name()
|
|
for(var/mob/camera/blob/B in mob_list)
|
|
if(lowertext(B.blob_reagent_datum.color) == lowertext(src.color)) // Goddamit why we use strings for these
|
|
return B.blob_reagent_datum.name
|
|
return "unknown"
|
|
|
|
/obj/effect/blob/normal
|
|
icon_state = "blob"
|
|
luminosity = 0
|
|
health = 21
|
|
|
|
/obj/effect/blob/normal/update_icon()
|
|
if(health <= 0)
|
|
qdel(src)
|
|
else if(health <= 15)
|
|
icon_state = "blob_damaged"
|
|
else
|
|
icon_state = "blob"
|
|
|
|
/* // Used to create the glow sprites. Remember to set the animate loop to 1, instead of infinite!
|
|
|
|
var/datum/blob_colour/B = new()
|
|
|
|
/datum/blob_colour/New()
|
|
..()
|
|
var/icon/I = 'icons/mob/blob.dmi'
|
|
I += rgb(35, 35, 0)
|
|
if(isfile("icons/mob/blob_result.dmi"))
|
|
fdel("icons/mob/blob_result.dmi")
|
|
fcopy(I, "icons/mob/blob_result.dmi")
|
|
|
|
*/
|