Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 31 additions & 18 deletions code/game/machinery/telecomms/presets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -313,15 +313,25 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)
/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/update_state()
..()
if(inoperable())
handle_xeno_acquisition(get_turf(src))
handle_xeno_acquisition()

/// Locates a nearby cluster from GLOB.all_xeno_pylon_cluster_nodes otherwise null
/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/proc/find_nearby_cluster()
for(var/obj/effect/alien/weeds/node/pylon/cluster/cluster as anything in GLOB.all_xeno_pylon_cluster_nodes)
if(cluster.is_in_range(src))
return cluster
return null

/// Handles xenos corrupting the tower when weeds touch the turf it is located on
/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/proc/handle_xeno_acquisition(turf/weeded_turf)
/// caller argument just used to simplify the need for calling find_nearby_cluster if needed
/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/proc/handle_xeno_acquisition(obj/effect/alien/weeds/signal_source, obj/effect/alien/weeds/node/pylon/invoking_pylon)
SIGNAL_HANDLER

if(corrupted)
return

var/turf/weeded_turf = get_turf(src)

if(!weeded_turf.weeds)
return

Expand All @@ -331,37 +341,43 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)
if(!weeded_turf.weeds.parent)
return

if(!istype(weeded_turf.weeds.parent, /obj/effect/alien/weeds/node/pylon/cluster))
return

if(SSticker.mode.is_in_endgame)
return

if(operable())
return

// This might not actually be a cluster node but we'll assert that in a moment
var/obj/effect/alien/weeds/node/pylon/cluster/effective_parent = weeded_turf.weeds.parent
if(!istype(effective_parent, /obj/effect/alien/weeds/node/pylon/cluster))
if(!istype(effective_parent, /obj/effect/alien/weeds/node/pylon/core))
return
// Core weeds can override cluster weeds so manually look for a cluster if not already passed in args
effective_parent = invoking_pylon || find_nearby_cluster()
if(!effective_parent)
return

if(ROUND_TIME < XENO_COMM_ACQUISITION_TIME)
addtimer(CALLBACK(src, PROC_REF(handle_xeno_acquisition), weeded_turf), (XENO_COMM_ACQUISITION_TIME - ROUND_TIME), TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_NO_HASH_WAIT)
addtimer(CALLBACK(src, PROC_REF(handle_xeno_acquisition)), (XENO_COMM_ACQUISITION_TIME - ROUND_TIME), TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_NO_HASH_WAIT)
return

if(!COOLDOWN_FINISHED(src, corruption_delay))
addtimer(CALLBACK(src, PROC_REF(handle_xeno_acquisition), weeded_turf), (COOLDOWN_TIMELEFT(src, corruption_delay)), TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_NO_HASH_WAIT)
addtimer(CALLBACK(src, PROC_REF(handle_xeno_acquisition)), (COOLDOWN_TIMELEFT(src, corruption_delay)), TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_NO_HASH_WAIT)
return

var/obj/effect/alien/weeds/node/pylon/cluster/parent_node = weeded_turf.weeds.parent

var/obj/effect/alien/resin/special/cluster/cluster_parent = parent_node.resin_parent

var/list/held_children_weeds = parent_node.children
// Prepare to upgrade the cluster
var/obj/effect/alien/resin/special/cluster/cluster_parent = effective_parent.resin_parent
var/list/held_children_weeds = effective_parent.children - effective_parent // why does it put itself into children...
var/cluster_loc = cluster_parent.loc
var/linked_hive = cluster_parent.linked_hive

parent_node.children = list()

// Delete the old (but don't touch our list)
effective_parent.children = list()
qdel(cluster_parent)

// Make a new endgame pylon
var/obj/effect/alien/resin/special/pylon/endgame/new_pylon = new(cluster_loc, linked_hive)
new_pylon.node.children = held_children_weeds
new_pylon.node.children += held_children_weeds

for(var/obj/effect/alien/weeds/weed in new_pylon.node.children)
weed.parent = new_pylon.node
Expand All @@ -388,9 +404,7 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)
SIGNAL_HANDLER

corrupted = FALSE

overlays -= corruption_image

COOLDOWN_START(src, corruption_delay, XENO_PYLON_DESTRUCTION_DELAY)

/// Handles moving the overlay from growing to idle
Expand All @@ -399,7 +413,6 @@ GLOBAL_LIST_EMPTY(all_static_telecomms_towers)
return

corruption_image = image(icon, icon_state = "resin_idle")

overlays += corruption_image

/obj/structure/machinery/telecomms/relay/preset/telecomms
Expand Down
53 changes: 39 additions & 14 deletions code/modules/cm_aliens/weeds.dm
Original file line number Diff line number Diff line change
Expand Up @@ -579,10 +579,9 @@
/obj/effect/alien/weeds/node/Destroy()
// When the node is removed, weeds should start dying out
// Make all the children look for a new parent node
for(var/X in children)
var/obj/effect/alien/weeds/W = X
remove_child(W)
addtimer(CALLBACK(W, PROC_REF(avoid_orphanage)), WEED_BASE_DECAY_SPEED + rand(0, 1 SECONDS)) // Slight variation whilst decaying
for(var/obj/effect/alien/weeds/child as anything in children)
remove_child(child)
addtimer(CALLBACK(child, PROC_REF(avoid_orphanage)), WEED_BASE_DECAY_SPEED + rand(0, 1 SECONDS)) // Slight variation whilst decaying

. = ..()

Expand All @@ -595,6 +594,13 @@
))
health = NODE_HEALTH_STANDARD

/obj/effect/alien/weeds/node/proc/is_in_range(atom/thing)
if(!thing?.loc)
return FALSE
var/x_diff = abs(thing.x - x)
var/y_diff = abs(thing.y - y)
return (x_diff <= node_range && y_diff < node_range) || (x_diff < node_range && y_diff <= node_range)

/obj/effect/alien/weeds/node/alpha
hivenumber = XENO_HIVE_ALPHA

Expand All @@ -618,16 +624,6 @@
spread_on_semiweedable = TRUE
var/obj/effect/alien/resin/special/resin_parent

/obj/effect/alien/weeds/node/pylon/proc/set_parent_damaged()
if(!resin_parent)
return

var/obj/effect/alien/resin/special/pylon/parent_pylon = resin_parent
parent_pylon.damaged = TRUE

/obj/effect/alien/weeds/node/pylon/core
node_range = WEED_RANGE_CORE

/obj/effect/alien/weeds/node/pylon/Destroy()
resin_parent = null
return ..()
Expand All @@ -647,12 +643,41 @@
/obj/effect/alien/weeds/node/pylon/acid_spray_act()
return

/obj/effect/alien/weeds/node/pylon/proc/set_parent_damaged()
if(!resin_parent)
return

var/obj/effect/alien/resin/special/pylon/parent_pylon = resin_parent
parent_pylon.damaged = TRUE

/obj/effect/alien/weeds/node/pylon/core
node_range = WEED_RANGE_CORE

/obj/effect/alien/weeds/node/pylon/hunted
hivenumber = XENO_HIVE_HUNTED

GLOBAL_LIST_EMPTY(all_xeno_pylon_cluster_nodes)

/obj/effect/alien/weeds/node/pylon/cluster
spread_on_semiweedable = TRUE

/obj/effect/alien/weeds/node/pylon/cluster/Initialize(mapload, obj/effect/alien/weeds/node/node, mob/living/carbon/xenomorph/xeno, datum/hive_status/hive)
GLOB.all_xeno_pylon_cluster_nodes += src
return ..()

/obj/effect/alien/weeds/node/pylon/cluster/Destroy()
GLOB.all_xeno_pylon_cluster_nodes -= src
return ..()

/obj/effect/alien/weeds/node/pylon/cluster/complete_growth()
. = ..()

if(length(children) != 1)
return
for(var/obj/structure/machinery/telecomms/relay/preset/tower/mapcomms/tower in GLOB.all_static_telecomms_towers)
if(is_in_range(tower))
tower.handle_xeno_acquisition(invoking_pylon=src)

/obj/effect/alien/weeds/node/pylon/cluster/set_parent_damaged()
if(!resin_parent)
return
Expand Down