Skip to content

Commit

Permalink
egg morphers now generate facehuggers on their own
Browse files Browse the repository at this point in the history
  • Loading branch information
VileBeggar committed Sep 27, 2024
1 parent ee7bc49 commit 75bb9d5
Showing 1 changed file with 22 additions and 95 deletions.
117 changes: 22 additions & 95 deletions code/modules/cm_aliens/structures/special/egg_morpher.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,20 @@
//Eggmorpher - Basically a big reusable egg
/obj/effect/alien/resin/special/eggmorph
name = XENO_STRUCTURE_EGGMORPH
desc = "A disgusting, organic processor that reeks of rotting flesh. Capable of melting even bones into something far more useful."
desc = "A disgusting biomass generator that reeks of rotting flesh. Capable of producing facehuggers on its own."
icon_state = "eggmorph"
health = 300
var/last_spawned = 0
var/spawn_cooldown = 20 SECONDS
appearance_flags = KEEP_TOGETHER
layer = FACEHUGGER_LAYER

var/stored_huggers = 0
var/huggers_to_grow = 0
var/huggers_per_corpse = 6
var/huggers_to_grow_max = 12
var/huggers_reserved = 0
var/mob/captured_mob
var/datum/shape/range_bounds
var/spawn_cooldown_length = 30 SECONDS
COOLDOWN_DECLARE(spawn_cooldown)

appearance_flags = KEEP_TOGETHER
layer = FACEHUGGER_LAYER

/obj/effect/alien/resin/special/eggmorph/Initialize(mapload, hive_ref)
. = ..()
Expand All @@ -34,127 +33,55 @@
F = new(loc, linked_hive.hivenumber)
step_away(F,src,1)

vis_contents.Cut()
QDEL_NULL(captured_mob)
range_bounds = null

. = ..()

/obj/effect/alien/resin/special/eggmorph/get_examine_text(mob/user)
. = ..()
if(isxeno(user) || isobserver(user))
. += "It has [stored_huggers] facehuggers within, with [huggers_to_grow] more to grow (reserved: [huggers_reserved])."
. += "It has [stored_huggers] facehuggers within, with [huggers_to_grow_max - stored_huggers] more to grow (reserved: [huggers_reserved])."
if(stored_huggers < huggers_to_grow_max)
. += "It'll grow another facehugger in [COOLDOWN_SECONDSLEFT(src, spawn_cooldown)] seconds."
if(isobserver(user))
var/current_hugger_count = linked_hive.get_current_playable_facehugger_count();
. += "There are currently [SPAN_NOTICE("[current_hugger_count]")] facehuggers in the hive. The hive can support a total of [SPAN_NOTICE("[linked_hive.playable_hugger_limit]")] facehuggers at present."

/obj/effect/alien/resin/special/eggmorph/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/grab))
if(!isxeno(user)) return
var/obj/item/grab/G = I
if(iscarbon(G.grabbed_thing))
var/mob/living/carbon/M = G.grabbed_thing
if(M.buckled)
to_chat(user, SPAN_XENOWARNING("Unbuckle first!"))
return
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.is_revivable())
to_chat(user, SPAN_XENOWARNING("This one is not suitable yet!"))
return
if(isxeno(M))
return
if(M == captured_mob)
to_chat(user, SPAN_XENOWARNING("[src] is already digesting [M]!"))
return
if(huggers_to_grow + stored_huggers >= huggers_to_grow_max)
to_chat(user, SPAN_XENOWARNING("\The [src] is already full! Using this one now would be a waste..."))
return
if(!do_after(user, 10, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_GENERIC))
return
visible_message(SPAN_DANGER("\The [src] churns as it begins digest \the [M], spitting out foul-smelling fumes!"))
playsound(src, "alien_drool", 25)
if(captured_mob)
//Get rid of what we have there, we're overwriting it
qdel(captured_mob)
captured_mob = M
captured_mob.setDir(SOUTH)
captured_mob.moveToNullspace()
var/matrix/MX = matrix()
captured_mob.apply_transform(MX)
captured_mob.pixel_x = 16
captured_mob.pixel_y = 16
vis_contents += captured_mob
user.stop_pulling() // Automatically remove the grab
huggers_to_grow += huggers_per_corpse
update_icon()
/obj/effect/alien/resin/special/eggmorph/attackby(obj/item/item, mob/user)
if(!isxeno(user))
return
if(istype(I, /obj/item/clothing/mask/facehugger))
var/obj/item/clothing/mask/facehugger/F = I
if(F.stat != DEAD)
if(istype(item, /obj/item/clothing/mask/facehugger))
var/obj/item/clothing/mask/facehugger/hugger = item
if(hugger.stat != DEAD)
if(stored_huggers >= huggers_to_grow_max)
to_chat(user, SPAN_XENOWARNING("\The [src] is full of children."))
return
if(user)
visible_message(SPAN_XENOWARNING("[user] slides [F] back into \the [src]."), \
visible_message(SPAN_XENOWARNING("[user] slides [hugger] back into \the [src]."), \
SPAN_XENONOTICE("You place the child back into \the [src]."))
user.temp_drop_inv_item(F)
user.temp_drop_inv_item(hugger)
else
visible_message(SPAN_XENOWARNING("[F] crawls back into \the [src]!"))
visible_message(SPAN_XENOWARNING("[hugger] crawls back into \the [src]!"))
stored_huggers = min(huggers_to_grow_max, stored_huggers + 1)
qdel(F)
qdel(hugger)
else to_chat(user, SPAN_XENOWARNING("This child is dead."))
return
//refill egg morpher from an egg
if(istype(I, /obj/item/xeno_egg))
var/obj/item/xeno_egg/egg = I
if(stored_huggers >= huggers_to_grow_max)
to_chat(user, SPAN_XENOWARNING("\The [src] is full of children."))
return
if(user)
visible_message(SPAN_XENOWARNING("[user] slides a facehugger out of \the [egg] into \the [src]."), \
SPAN_XENONOTICE("You place the child from an egg into \the [src]."))
user.temp_drop_inv_item(egg)
stored_huggers = min(huggers_to_grow_max, stored_huggers + 1)
playsound(src.loc, "sound/effects/alien_egg_move.ogg", 25)
qdel(egg)
return
return ..(I, user)
return ..(item, user)

/obj/effect/alien/resin/special/eggmorph/update_icon()
..()
appearance_flags |= KEEP_TOGETHER
overlays.Cut()
underlays.Cut()
if(captured_mob)
var/image/J = new(icon = icon, icon_state = "[icon_state]", layer = captured_mob.layer + 0.1)
overlays += J
var/image/I = new(icon = icon, icon_state = "[icon_state]_overlay", layer = captured_mob.layer + 0.2)
overlays += I
underlays += "[icon_state]_underlay"

/obj/effect/alien/resin/special/eggmorph/process()
check_facehugger_target()

if(!linked_hive || !captured_mob || world.time < (last_spawned + spawn_cooldown))
if(!linked_hive || !COOLDOWN_FINISHED(src, spawn_cooldown) || stored_huggers < huggers_to_grow_max)
return
last_spawned = world.time
if(huggers_to_grow > 0)
huggers_to_grow--
COOLDOWN_START(src, spawn_cooldown, spawn_cooldown_length)
if(stored_huggers < huggers_to_grow_max)
stored_huggers = min(huggers_to_grow_max, stored_huggers + 1)
if(huggers_to_grow <= 0)
visible_message(SPAN_DANGER("\The [src] groans as its contents are reduced to nothing!"))
vis_contents.Cut()

for(var/atom/movable/A in captured_mob.contents_recursive()) // Get rid of any intel objects so we don't delete them
if(isitem(A))
var/obj/item/item = A
if(item.is_objective && item.unacidable)
item.forceMove(get_step(loc, pick(GLOB.alldirs)))
item.mouse_opacity = initial(item.mouse_opacity)

QDEL_NULL(captured_mob)
update_icon()

/obj/effect/alien/resin/special/eggmorph/proc/check_facehugger_target()
if(!range_bounds)
Expand Down

0 comments on commit 75bb9d5

Please sign in to comment.