Morph Gore (#10186)

This commit is contained in:
Geeves
2020-10-12 19:26:38 +02:00
committed by GitHub
parent d8f9f8ad53
commit 4aa4f9a60a
29 changed files with 486 additions and 280 deletions
@@ -20,6 +20,9 @@
var/drytime
var/dries = TRUE
/obj/effect/decal/cleanable/blood/no_dry
dries = FALSE
/obj/effect/decal/cleanable/blood/reveal_blood()
if(!fluorescent)
fluorescent = 1
@@ -1,62 +0,0 @@
/obj/structure/alien
name = "alien thing"
desc = "There's something alien about this."
icon = 'icons/mob/npc/alien.dmi'
layer = 4
var/health = 50
/obj/structure/alien/proc/healthcheck()
if(health <=0)
density = 0
qdel(src)
return
/obj/structure/alien/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
..()
healthcheck()
return
/obj/structure/alien/ex_act(severity)
switch(severity)
if(1.0)
health-=50
if(2.0)
health-=50
if(3.0)
if (prob(50))
health-=50
else
health-=25
healthcheck()
return
/obj/structure/alien/hitby(AM as mob|obj)
..()
visible_message("<span class='danger'>\The [src] was hit by \the [AM].</span>")
var/tforce = 0
if(ismob(AM))
tforce = 10
else
tforce = AM:throwforce
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
health = max(0, health - tforce)
healthcheck()
..()
return
/obj/structure/alien/attack_generic()
attack_hand(usr)
/obj/structure/alien/attackby(var/obj/item/W, var/mob/user)
health = max(0, health - W.force)
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
healthcheck()
..()
return
/obj/structure/alien/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group) return 0
if(istype(mover) && mover.checkpass(PASSGLASS))
return !opacity
return !density
-105
View File
@@ -1,105 +0,0 @@
#define NODERANGE 3
/obj/structure/alien/weeds
name = "weeds"
desc = "Weird purple weeds."
icon_state = "weeds"
anchored = 1
density = 0
health = 15
var/obj/structure/alien/weeds/node/linked_node = null
var/list/dirs_left
/obj/structure/alien/weeds/node
icon_state = "weednode"
name = "purple sac"
desc = "Weird purple octopus-like thing."
light_range = NODERANGE
var/node_range = NODERANGE
/obj/structure/alien/weeds/Destroy()
STOP_PROCESSING(SSprocessing, src)
return ..()
/obj/structure/alien/weeds/Initialize(pos, node)
. = ..()
if(istype(loc, /turf/space))
return INITIALIZE_HINT_QDEL
linked_node = node
if(icon_state == "weeds")icon_state = pick("weeds", "weeds1", "weeds2")
START_PROCESSING(SSprocessing, src)
dirs_left = cardinal.Copy()
/obj/structure/alien/weeds/process()
var/turf/U = get_turf(src)
if (istype(U, /turf/space))
qdel(src)
return PROCESS_KILL
if (!dirs_left.len || !linked_node || get_dist(linked_node, src) > linked_node.node_range)
return PROCESS_KILL
for (var/D in dirs_left)
var/turf/T = get_step(src, D)
if (!isturf(T) || T.is_hole || T.is_space() || locate(/obj/structure/alien/weeds, T))
dirs_left -= D
continue
if (T.density)
continue
var/spawn_new = TRUE
for (var/aa in T)
var/atom/A = aa
if (istype(/obj/structure/alien/weeds, A))
dirs_left -= D
spawn_new = FALSE
break
else if (A.density)
spawn_new = FALSE
if (spawn_new)
new /obj/structure/alien/weeds(T, linked_node)
/obj/structure/alien/weeds/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
if(2.0)
if (prob(50))
qdel(src)
if(3.0)
if (prob(5))
qdel(src)
return
/obj/structure/alien/weeds/attackby(var/obj/item/W, var/mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
visible_message("<span class='danger'>\The [src] have been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
var/damage = W.force / 4.0
if(W.iswelder())
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0, user))
damage = 15
playsound(loc, 'sound/items/welder.ogg', 100, 1)
health -= damage
healthcheck()
/obj/structure/alien/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300 + T0C)
health -= 5
healthcheck()
#undef NODERANGE
@@ -1,42 +0,0 @@
/obj/structure/alien/resin
name = "resin"
desc = "Looks like some kind of slimy growth."
icon_state = "resin"
density = 1
opacity = 1
anchored = 1
health = 200
/obj/structure/alien/resin/wall
name = "resin wall"
desc = "Purple slime solidified into a wall."
icon_state = "resinwall"
/obj/structure/alien/resin/membrane
name = "resin membrane"
desc = "Purple slime just thin enough to let light pass through."
icon_state = "resinmembrane"
opacity = 0
health = 120
/obj/structure/alien/resin/New()
..()
var/turf/T = get_turf(src)
T.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
/obj/structure/alien/resin/Destroy()
var/turf/T = get_turf(src)
T.thermal_conductivity = initial(T.thermal_conductivity)
return ..()
/obj/structure/alien/resin/attack_hand(var/mob/user)
if (HULK in user.mutations)
visible_message("<span class='danger'>\The [user] destroys \the [name]!</span>")
health = 0
else
visible_message("<span class='danger'>\The [user] claws at \the [src]!</span>")
// Todo check attack datums.
health -= rand(5,10)
healthcheck()
return
+83
View File
@@ -0,0 +1,83 @@
/obj/structure/gore
name = "alien thing"
desc = "There's something alien about this."
icon = 'icons/obj/gore_structures.dmi'
layer = ABOVE_CABLE_LAYER + 0.1
anchored = TRUE
density = FALSE
var/destroy_message = "THE STRUCTURE collapses in on itself!"
var/maxHealth = 50
var/health = 50
/obj/structure/gore/Initialize(mapload)
. = ..()
health = maxHealth
/obj/structure/gore/examine(mob/user)
if(..(user, 2))
var/health_div = health / maxHealth
if(health_div >= 0.9)
to_chat(user, SPAN_NOTICE("\The [src] appears completely intact."))
else if(health_div >= 0.7)
to_chat(user, SPAN_NOTICE("\The [src] is starting to tear somewhat."))
else if(health_div >= 0.4)
to_chat(user, SPAN_WARNING("\The [src] is starting to fall apart."))
else
to_chat(user, SPAN_WARNING("\The [src] is barely holding itself together!"))
/obj/structure/gore/proc/healthcheck()
if(health <= 0)
var/final_message = replacetext(destroy_message, "THE STRUCTURE", "\The [src]")
visible_message(SPAN_WARNING(final_message))
qdel(src)
/obj/structure/gore/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
healthcheck()
return ..()
/obj/structure/gore/ex_act(severity)
switch(severity)
if(1.0)
health -= 50
if(2.0)
health -= 50
if(3.0)
if(prob(50))
health -= 50
else
health -= 25
healthcheck()
/obj/structure/gore/hitby(atom/movable/AM)
. = ..()
visible_message(SPAN_WARNING("\The [src] was hit by \the [AM]."))
playsound(loc, 'sound/effects/attackblob.ogg', 100, TRUE)
var/throw_force = 0
if(isobj(AM))
var/obj/O = AM
throw_force = O.throwforce
else if(ismob(AM))
throw_force = 10
health -= throw_force
healthcheck()
/obj/structure/gore/attack_generic()
attack_hand(usr)
/obj/structure/gore/attackby(obj/item/W, mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(src, W)
var/force_damage = W.force
if(W.damtype == BURN)
force_damage *= 1.25
health -= force_damage
playsound(loc, 'sound/effects/attackblob.ogg', 80, TRUE)
healthcheck()
/obj/structure/gore/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group)
return FALSE
if(istype(mover) && mover.checkpass(PASSGLASS))
return !opacity
return !density
+65
View File
@@ -0,0 +1,65 @@
#define NEST_RESIST_TIME 1200
/obj/structure/bed/nest
name = "gore nest"
desc = "It's a gruesome pile of thick, sticky flesh shaped like a nest."
icon = 'icons/obj/gore_structures.dmi'
icon_state = "nest"
var/destroy_message = "THE STRUCTURE collapses in on itself!"
var/maxHealth = 100
var/health = 100
/obj/structure/bed/nest/Initialize(mapload, new_material, new_padding_material)
. = ..()
health = maxHealth
/obj/structure/bed/nest/examine(mob/user)
if(..(user, 2))
var/health_div = health / maxHealth
if(health_div >= 0.9)
to_chat(user, SPAN_NOTICE("\The [src] appears completely intact."))
else if(health_div >= 0.7)
to_chat(user, SPAN_NOTICE("\The [src] is starting to tear somewhat."))
else if(health_div >= 0.4)
to_chat(user, SPAN_WARNING("\The [src] is starting to fall apart."))
else
to_chat(user, SPAN_WARNING("\The [src] is barely holding itself together!"))
/obj/structure/bed/nest/update_icon()
return
/obj/structure/bed/nest/user_unbuckle_mob(mob/user)
if(buckled_mob?.buckled == src)
add_fingerprint(user)
if(buckled_mob != user)
buckled_mob.visible_message("<b>[user]</b> pulls [buckled_mob] free from the sticky flesh!", SPAN_NOTICE("[user] pulls you free from the gelatinous flesh."), SPAN_WARNING("You hear squelching..."))
unbuckle_buckled_mob(buckled_mob)
else
if(world.time <= buckled_mob.last_special + NEST_RESIST_TIME)
return
buckled_mob.last_special = world.time
buckled_mob.visible_message(SPAN_WARNING("[buckled_mob] starts struggling to break free of the sticky flesh..."), SPAN_WARNING("You struggle to break free from the gelatinous flesh..."), SPAN_WARNING("You hear squelching..."))
if(do_after(buckled_mob, NEST_RESIST_TIME, TRUE))
unbuckle_buckled_mob(buckled_mob)
/obj/structure/bed/nest/proc/unbuckle_buckled_mob(var/mob/buck)
if(buckled_mob == buck && buck.buckled == src)
buck.pixel_y = 0
buck.old_y = 0
unbuckle_mob()
/obj/structure/bed/nest/attackby(obj/item/W, mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(src, W)
var/force_damage = W.force
if(W.damtype == BURN)
force_damage *= 1.25
health -= force_damage
playsound(loc, 'sound/effects/attackblob.ogg', 80, TRUE)
healthcheck()
/obj/structure/bed/nest/proc/healthcheck()
if(health <= 0)
var/final_message = replacetext(destroy_message, "THE STRUCTURE", "\The [src]")
visible_message(SPAN_WARNING(final_message))
qdel(src)
@@ -0,0 +1,145 @@
#define NODERANGE 3
/obj/structure/gore/tendrils
name = "bloody tendrils"
desc = "Bloody, pulsating tendrils."
icon_state = "tendril"
maxHealth = 40
var/being_destroyed = FALSE
var/is_node = FALSE
var/obj/structure/gore/tendrils/node/linked_node = null
var/list/dirs_left
var/grow_speed = 5 SECONDS
var/last_grow = 0
/obj/structure/gore/tendrils/node
name = "flesh sac"
desc = "Clumped up flesh, pulsating in rhythm with the tendrils that surround it."
icon_state = "tendril_node"
density = TRUE
layer = ABOVE_CABLE_LAYER + 0.2
maxHealth = 150
light_range = NODERANGE
light_color = LIGHT_COLOR_EMERGENCY
is_node = TRUE
grow_speed = 3 SECONDS
var/node_range = NODERANGE
/obj/structure/gore/tendrils/node/CanPass(atom/movable/mover, turf/target, height, air_group)
. = ..()
if(!.)
if(istype(mover, /mob/living/simple_animal/hostile/morph))
return TRUE
if(ishuman(mover))
var/mob/living/carbon/human/H = mover
if(H.mind.changeling)
return TRUE
/obj/structure/gore/tendrils/Destroy()
var/turf/T = get_turf(src)
T.movement_cost = initial(T.movement_cost)
STOP_PROCESSING(SSprocessing, src)
being_destroyed = TRUE
update_neighbours()
return ..()
/obj/structure/gore/tendrils/Initialize(pos, node)
. = ..()
if(istype(loc, /turf/space) || isopenturf(loc))
return INITIALIZE_HINT_QDEL
var/turf/T = get_turf(src)
T.movement_cost += 2
if(!is_node)
linked_node = node
update_sprite()
update_neighbours()
else
linked_node = src
new /obj/structure/gore/tendrils(loc, linked_node)
new /obj/effect/decal/cleanable/blood/no_dry(loc)
START_PROCESSING(SSprocessing, src)
dirs_left = cardinal.Copy()
/obj/structure/gore/tendrils/proc/update_neighbours(turf/U)
if(!U)
U = loc
if(istype(U))
for(var/dirn in cardinal)
var/turf/T = get_step(U, dirn)
if(!istype(T))
continue
var/obj/structure/gore/tendrils/GT = locate() in T
if(GT)
GT.update_sprite()
/obj/structure/gore/tendrils/proc/update_sprite()
var/my_dir = 0
for(var/check_dir in cardinal)
var/turf/check = get_step(src, check_dir)
if(!istype(check))
continue
var/obj/structure/gore/tendrils/GT = locate() in check
if(GT && !GT.being_destroyed)
my_dir |= check_dir
if(my_dir == 15) //weeds in all four directions
icon_state = "tendril[rand(0, 15)]"
else if(my_dir == 0) //no weeds in any direction
icon_state = "tendril"
else
icon_state = "tendril_dir[my_dir]"
/obj/structure/gore/tendrils/node/update_sprite()
for(var/obj/structure/gore/tendrils/GT in loc)
if(GT == src)
continue
GT.update_sprite()
/obj/structure/gore/tendrils/process()
if(last_grow + grow_speed > world.time)
return
last_grow = world.time
var/turf/U = get_turf(src)
if(istype(U, /turf/space) || isopenturf(U))
qdel(src)
return PROCESS_KILL
if(!length(dirs_left) || !linked_node || get_dist(linked_node, U) > linked_node.node_range)
return PROCESS_KILL
var/D = pick(dirs_left)
var/turf/T = get_step(U, D)
var/obj/machinery/door/MD = locate() in T
if(MD?.density)
return
var/obj/structure/simple_door/SD = locate() in T
if(SD?.density)
return
if(!isturf(T) || T.is_hole || T.is_space() || T.density || locate(/obj/structure/gore/tendrils, T))
dirs_left -= D
return
dirs_left -= D
new /obj/structure/gore/tendrils(T, linked_node)
/obj/structure/gore/tendrils/ex_act(severity)
switch(severity)
if(1.0)
health = 0
if(2.0)
health -= maxHealth / 2
if(3.0)
health -= maxHealth / 5
healthcheck()
/obj/structure/gore/tendrils/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300 + T0C)
health -= 5
healthcheck()
#undef NODERANGE
+40
View File
@@ -0,0 +1,40 @@
/obj/structure/gore/floor
name = "flesh floor"
desc = "Looks like the floor was covered by some fleshlike growth."
icon_state = "flesh_floor"
maxHealth = 100
/obj/structure/gore/wall
name = "flesh wall"
desc = "Chunks of flesh sculpted to form an impassable wall."
icon_state = "flesh_wall"
opacity = TRUE
maxHealth = 200
/obj/structure/gore/wall/membrane
name = "flesh membrane"
desc = "Skin and muscle stretched just thin enough to let light pass through."
icon_state = "flesh_membrane"
opacity = FALSE
maxHealth = 120
/obj/structure/gore/wall/Initialize()
. = ..()
var/turf/T = get_turf(src)
T.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
/obj/structure/gore/wall/Destroy()
var/turf/T = get_turf(src)
T.thermal_conductivity = initial(T.thermal_conductivity)
return ..()
/obj/structure/gore/resin/attack_hand(var/mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(src, FIST_ATTACK_ANIMATION)
if(HULK in user.mutations)
visible_message(SPAN_DANGER("\The [user] destroys \the [src]!"))
health = 0
else
visible_message(SPAN_DANGER("\The [user] claws at \the [src]!"))
health -= rand(5, 10)
healthcheck()
@@ -1,54 +0,0 @@
//Alium nests. Essentially beds with an unbuckle delay that only aliums can buckle mobs to.
#define NEST_RESIST_TIME 1200
/obj/structure/bed/nest
name = "alien nest"
desc = "It's a gruesome pile of thick, sticky resin shaped like a nest."
icon = 'icons/mob/npc/alien.dmi'
icon_state = "nest"
var/health = 100
/obj/structure/bed/nest/update_icon()
return
/obj/structure/bed/nest/user_unbuckle_mob(mob/user as mob)
if(buckled_mob)
if(buckled_mob.buckled == src)
if(buckled_mob != user)
buckled_mob.visible_message(\
"<span class='notice'>[user.name] pulls [buckled_mob.name] free from the sticky nest!</span>",\
"<span class='notice'>[user.name] pulls you free from the gelatinous resin.</span>",\
"<span class='notice'>You hear squelching...</span>")
buckled_mob.pixel_y = 0
buckled_mob.old_y = 0
unbuckle_mob()
else
if(world.time <= buckled_mob.last_special+NEST_RESIST_TIME)
return
buckled_mob.last_special = world.time
buckled_mob.visible_message(\
"<span class='warning'>[buckled_mob.name] struggles to break free of the gelatinous resin...</span>",\
"<span class='warning'>You struggle to break free from the gelatinous resin...</span>",\
"<span class='notice'>You hear squelching...</span>")
spawn(NEST_RESIST_TIME)
if(user && buckled_mob && user.buckled == src)
buckled_mob.last_special = world.time
buckled_mob.pixel_y = 0
buckled_mob.old_y = 0
unbuckle_mob()
src.add_fingerprint(user)
return
/obj/structure/bed/nest/attackby(obj/item/W as obj, mob/user as mob)
var/aforce = W.force
health = max(0, health - aforce)
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
for(var/mob/M in viewers(src, 7))
M.show_message("<span class='warning'>[user] hits [src] with [W]!</span>", 1)
healthcheck()
/obj/structure/bed/nest/proc/healthcheck()
if(health <=0)
density = 0
qdel(src)
return