Skip to content

Commit

Permalink
Lesser drone changes (#4280)
Browse files Browse the repository at this point in the history
# 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
<details>
<summary>Screenshots & Videos</summary>

Put screenshots and videos here with an empty line between the
screenshots and the `<details>` tags.

</details>


# 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:
  • Loading branch information
morrowwolf committed Aug 30, 2023
1 parent f80c649 commit 9e36325
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 34 deletions.
32 changes: 25 additions & 7 deletions code/game/gamemodes/cm_initialize.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
63 changes: 45 additions & 18 deletions code/modules/cm_aliens/structures/special/pylon_core.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -42,13 +47,32 @@
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.
return XENO_NO_DELAY_ACTION
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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
. = ..()
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
31 changes: 22 additions & 9 deletions code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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])
Expand Down Expand Up @@ -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

Expand All @@ -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()
Expand All @@ -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: <b>[current_lesser_drone_count]/[lesser_drone_limit]</b>"))
return FALSE
Expand Down

0 comments on commit 9e36325

Please sign in to comment.