From 9e363259b3d26420628b78c5f8e0e41467747236 Mon Sep 17 00:00:00 2001 From: morrowwolf Date: Wed, 30 Aug 2023 16:49:16 -0400 Subject: [PATCH] Lesser drone changes (#4280) # About the pull request This PR: Allows lesser drones to spawn at pylons and core. Creates a pool of lesser drones at cores and pylons that regenerate over time. It takes about 10 seconds to get one more when queen is on ovi and about 120 seconds when queen is off. Lesser drones and facehuggers no longer count towards the lesser drone count but lesser drones are still capped at 1/3rd of the hive with a minimum of 3. Facehuggers have also been changed to not count lesser drones and themselves for max calculations. # Explain why it's good for the game While fun, the infinite and immediate respawn of lesser drones from hive core while queen is on ovi is a bit much. This should help with this problem while also keeping lesser drones as free and horde-like components of the xeno force. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Morrow add: Allowed lesser drones to spawn at pylons and core. add: Created a pool of lesser drones at cores and pylons that regenerate over time. It takes about 10 seconds to get one more when queen is on ovi and about 120 seconds when queen is off. balance: Lesser drones and facehuggers no longer count towards the lesser drone count but lesser drones are still capped at 1/3rd of the hive with a minimum of 3. balance: Facehuggers have also been changed to not count lesser drones and themselves for max calculations. /:cl: --- code/game/gamemodes/cm_initialize.dm | 32 +++++++--- .../structures/special/pylon_core.dm | 63 +++++++++++++------ .../living/carbon/xenomorph/xeno_defines.dm | 31 ++++++--- 3 files changed, 92 insertions(+), 34 deletions(-) diff --git a/code/game/gamemodes/cm_initialize.dm b/code/game/gamemodes/cm_initialize.dm index becee89adb6d..bc6adc026b6e 100644 --- a/code/game/gamemodes/cm_initialize.dm +++ b/code/game/gamemodes/cm_initialize.dm @@ -567,21 +567,39 @@ Additional game mode variables. var/hive_picked = tgui_input_list(xeno_candidate, "Select which Hive to attempt joining.", "Hive Choice", active_hives, theme="hive_status") if(!hive_picked) to_chat(xeno_candidate, SPAN_ALERT("Hive choice error. Aborting.")) - return + return FALSE hive = GLOB.hive_datum[active_hives[hive_picked]] else hive = GLOB.hive_datum[last_active_hive] - if(!hive.hive_location) - to_chat(xeno_candidate, SPAN_WARNING("The selected hive does not have a hive core to spawn from!")) - return - for(var/mob_name in hive.banished_ckeys) if(hive.banished_ckeys[mob_name] == xeno_candidate.ckey) to_chat(xeno_candidate, SPAN_WARNING("You are banished from the [hive], you may not rejoin unless the Queen re-admits you or dies.")) - return + return FALSE + + var/list/selection_list = list() + var/list/selection_list_structure = list() + + if(hive.hive_location?.lesser_drone_spawns >= 1) + selection_list += "hive core" + selection_list_structure += hive.hive_location + + for(var/obj/effect/alien/resin/special/pylon/cycled_pylon as anything in hive.hive_structures[XENO_STRUCTURE_PYLON]) + if(cycled_pylon.lesser_drone_spawns >= 1) + selection_list += "[cycled_pylon.name] at [get_area(cycled_pylon)]" + selection_list_structure += cycled_pylon + + if(!length(selection_list)) + to_chat(xeno_candidate, SPAN_WARNING("The selected hive does not have enough power for a lesser drone at any hive core or pylon!")) + return FALSE + + var/prompt = tgui_input_list(xeno_candidate, "Select spawn?", "Spawnpoint Selection", selection_list) + if(!prompt) + return FALSE + + var/obj/effect/alien/resin/special/pylon/selected_structure = selection_list_structure[selection_list.Find(prompt)] - hive.hive_location.spawn_lesser_drone(xeno_candidate) + selected_structure.spawn_lesser_drone(xeno_candidate) return TRUE diff --git a/code/modules/cm_aliens/structures/special/pylon_core.dm b/code/modules/cm_aliens/structures/special/pylon_core.dm index 65d4a1c9168e..e8b95f7e1aae 100644 --- a/code/modules/cm_aliens/structures/special/pylon_core.dm +++ b/code/modules/cm_aliens/structures/special/pylon_core.dm @@ -21,6 +21,11 @@ var/protection_level = TURF_PROTECTION_CAS + /// How many lesser drone spawns this pylon is able to spawn currently + var/lesser_drone_spawns = 0 + /// The maximum amount of lesser drone spawns this pylon can hold + var/lesser_drone_spawn_limit = 5 + plane = FLOOR_PLANE /obj/effect/alien/resin/special/pylon/Initialize(mapload, hive_ref) @@ -42,6 +47,11 @@ QDEL_NULL(node) . = ..() +/obj/effect/alien/resin/special/pylon/process(delta_time) + if(lesser_drone_spawns < lesser_drone_spawn_limit) + // One every 10 seconds while on ovi, one every 120-ish seconds while off ovi + lesser_drone_spawns = min(lesser_drone_spawns + ((linked_hive.living_xeno_queen?.ovipositor ? 0.1 : 0.008) * delta_time), lesser_drone_spawn_limit) + /obj/effect/alien/resin/special/pylon/attack_alien(mob/living/carbon/xenomorph/M) if(isxeno_builder(M) && M.a_intent == INTENT_HELP && M.hivenumber == linked_hive.hivenumber) do_repair(M) //This handles the delay itself. @@ -49,6 +59,20 @@ else return ..() +/obj/effect/alien/resin/special/pylon/get_examine_text(mob/user) + . = ..() + + var/lesser_count = 0 + for(var/mob/living/carbon/xenomorph/lesser_drone in linked_hive.totalXenos) + lesser_count++ + + . += "Currently holding [SPAN_NOTICE("[Floor(lesser_drone_spawns)]")]/[SPAN_NOTICE("[lesser_drone_spawn_limit]")] lesser drones." + . += "There are currently [SPAN_NOTICE("[lesser_count]")] lesser drones in the hive. The hive can support [SPAN_NOTICE("[linked_hive.lesser_drone_limit]")] lesser drones." + +/obj/effect/alien/resin/special/pylon/attack_ghost(mob/dead/observer/user) + . = ..() + spawn_lesser_drone(user) + /obj/effect/alien/resin/special/pylon/proc/do_repair(mob/living/carbon/xenomorph/xeno) if(!istype(xeno)) return @@ -94,6 +118,25 @@ pylon_node.resin_parent = src return pylon_node +/obj/effect/alien/resin/special/pylon/proc/spawn_lesser_drone(mob/xeno_candidate) + if(!linked_hive.can_spawn_as_lesser_drone(xeno_candidate, src)) + return FALSE + + if(tgui_alert(xeno_candidate, "Are you sure you want to become a lesser drone?", "Confirmation", list("Yes", "No")) != "Yes") + return FALSE + + if(!linked_hive.can_spawn_as_lesser_drone(xeno_candidate, src)) + return FALSE + + var/mob/living/carbon/xenomorph/lesser_drone/new_drone = new(loc, null, linked_hive.hivenumber) + xeno_candidate.mind.transfer_to(new_drone, TRUE) + lesser_drone_spawns -= 1 + new_drone.visible_message(SPAN_XENODANGER("A lesser drone emerges out of [src]!"), SPAN_XENODANGER("You emerge out of [src] and awaken from your slumber. For the Hive!")) + playsound(new_drone, 'sound/effects/xeno_newlarva.ogg', 25, TRUE) + new_drone.generate_name() + + return TRUE + /obj/effect/alien/resin/special/pylon/endgame cover_range = WEED_RANGE_CORE var/activated = FALSE @@ -189,6 +232,7 @@ protection_level = TURF_PROTECTION_OB + lesser_drone_spawn_limit = 10 /obj/effect/alien/resin/special/pylon/core/Initialize(mapload, datum/hive_status/hive_ref) . = ..() @@ -205,6 +249,7 @@ SSminimaps.add_marker(src, z, MINIMAP_FLAG_XENO, "core[health < (initial(health) * 0.5) ? "_warn" : "_passive"]") /obj/effect/alien/resin/special/pylon/core/process() + . = ..() update_minimap_icon() // Handle spawning larva if core is connected to a hive @@ -243,7 +288,6 @@ linked_hive.hijack_burrowed_surge = FALSE xeno_message(SPAN_XENOANNOUNCE("The hive's power wanes. You will no longer gain pooled larva over time."), 3, linked_hive.hivenumber) - // Hive core can repair itself over time if(health < maxhealth && last_healed <= world.time) health += min(heal_amount, maxhealth-health) @@ -400,22 +444,5 @@ // Tell admins that this condition is reached so they know what has happened if it fails somehow return -/obj/effect/alien/resin/special/pylon/core/proc/spawn_lesser_drone(mob/xeno_candidate) - if(!linked_hive.can_spawn_as_lesser_drone(xeno_candidate)) - return FALSE - - var/mob/living/carbon/xenomorph/lesser_drone/new_drone = new /mob/living/carbon/xenomorph/lesser_drone(loc, null, linked_hive.hivenumber) - xeno_candidate.mind.transfer_to(new_drone, TRUE) - new_drone.visible_message(SPAN_XENODANGER("A lesser drone emerges out of [src]!"), SPAN_XENODANGER("You emerge out of [src] and awaken from your slumber. For the Hive!")) - playsound(new_drone, 'sound/effects/xeno_newlarva.ogg', 25, TRUE) - new_drone.generate_name() - - return TRUE - -/obj/effect/alien/resin/special/pylon/core/attack_ghost(mob/dead/observer/user) - . = ..() - if(SSticker.mode.check_xeno_late_join(user)) - SSticker.mode.attempt_to_join_as_lesser_drone(user) - #undef PYLON_REPAIR_TIME #undef PYLON_WEEDS_REGROWTH_TIME diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm index c2bf91edde6e..1de164fccc85 100644 --- a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm +++ b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm @@ -351,11 +351,17 @@ var/hugger_timelock = 15 MINUTES /// How many huggers can the hive support var/playable_hugger_limit = 0 + /// Minimum number of huggers available at any hive size + var/playable_hugger_minimum = 2 + /// This number divides the total xenos counted for slots to give the max number of facehuggers + var/playable_hugger_max_divisor = 4 /// How many lesser drones the hive can support var/lesser_drone_limit = 0 /// Slots available for lesser drones will never go below this number - var/lesser_drone_minimum = 3 + var/lesser_drone_minimum = 2 + /// This number divides the total xenos counted for slots to give the max number of lesser drones + var/playable_lesser_drones_max_divisor = 3 var/datum/tacmap/xeno/tacmap var/minimap_type = MINIMAP_FLAG_XENO @@ -1035,7 +1041,12 @@ return TRUE /datum/hive_status/proc/update_hugger_limit() - playable_hugger_limit = 2 + Ceiling(totalXenos.len / 4) + var/countable_xeno_iterator = 0 + for(var/mob/living/carbon/xenomorph/cycled_xeno as anything in totalXenos) + if(cycled_xeno.counts_for_slots) + countable_xeno_iterator++ + + playable_hugger_limit = max(Floor(countable_xeno_iterator / playable_hugger_max_divisor), playable_hugger_minimum) /datum/hive_status/proc/can_spawn_as_hugger(mob/dead/observer/user) if(!GLOB.hive_datum || ! GLOB.hive_datum[hivenumber]) @@ -1086,9 +1097,14 @@ hugger.timeofdeath = user.timeofdeath // Keep old death time /datum/hive_status/proc/update_lesser_drone_limit() - lesser_drone_limit = lesser_drone_minimum + Ceiling(length(totalXenos) / 3) + var/countable_xeno_iterator = 0 + for(var/mob/living/carbon/xenomorph/cycled_xeno as anything in totalXenos) + if(cycled_xeno.counts_for_slots) + countable_xeno_iterator++ + + lesser_drone_limit = max(Floor(countable_xeno_iterator / playable_lesser_drones_max_divisor), lesser_drone_minimum) -/datum/hive_status/proc/can_spawn_as_lesser_drone(mob/dead/observer/user) +/datum/hive_status/proc/can_spawn_as_lesser_drone(mob/dead/observer/user, obj/effect/alien/resin/special/pylon/spawning_pylon) if(!GLOB.hive_datum || ! GLOB.hive_datum[hivenumber]) return FALSE @@ -1109,8 +1125,8 @@ to_chat(user, SPAN_WARNING("The selected hive does not have a Queen!")) return FALSE - if(!living_xeno_queen.ovipositor && !SSticker.mode.is_in_endgame) - to_chat(user, SPAN_WARNING("The selected hive does not have a Queen on Ovipositor!")) + if(spawning_pylon.lesser_drone_spawns < 1) + to_chat(user, SPAN_WARNING("The selected core or pylon does not have enough power for a lesser drone!")) return FALSE update_lesser_drone_limit() @@ -1120,9 +1136,6 @@ if(islesserdrone(mob)) current_lesser_drone_count++ - if(tgui_alert(user, "Are you sure you want to become a lesser drone?", "Confirmation", list("Yes", "No")) != "Yes") - return FALSE - if(lesser_drone_limit <= current_lesser_drone_count) to_chat(user, SPAN_WARNING("[GLOB.hive_datum[hivenumber]] cannot support more lesser drones! Limit: [current_lesser_drone_count]/[lesser_drone_limit]")) return FALSE