Skip to content

Commit

Permalink
TGS Test Merge (#8026)
Browse files Browse the repository at this point in the history
  • Loading branch information
cm13-github committed Feb 5, 2025
2 parents c97acce + 3c6c296 commit 2416cb9
Show file tree
Hide file tree
Showing 8 changed files with 238 additions and 72 deletions.
1 change: 1 addition & 0 deletions code/__DEFINES/client_prefs.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define BE_ALIEN_AFTER_DEATH (1<<0)
#define BE_AGENT (1<<1)
#define BE_KING (1<<2)

/// Determines how abilities are activated, whether they're activated via middle click, shift click or right click.
#define XENO_ABILITY_CLICK_MIDDLE 1
Expand Down
8 changes: 7 additions & 1 deletion code/modules/client/preferences_savefile.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#define SAVEFILE_VERSION_MIN 8
#define SAVEFILE_VERSION_MAX 29
#define SAVEFILE_VERSION_MAX 30

//handles converting savefiles to new formats
//MAKE SURE YOU KEEP THIS UP TO DATE!
Expand Down Expand Up @@ -192,6 +192,12 @@

S["hair_style_name"] << hair_style

if(savefile_version < 30)
var/be_special = 0
S["be_special"] >> be_special
be_special &= ~BE_KING
S["be_special"] << be_special

savefile_version = SAVEFILE_VERSION_MAX
return 1

Expand Down
1 change: 1 addition & 0 deletions code/modules/client/preferences_toggles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
var/list/be_special_flags = list(
"Xenomorph after unrevivable death" = BE_ALIEN_AFTER_DEATH,
"Agent" = BE_AGENT,
"Be King" = BE_KING,
)
var/role = tgui_input_list(usr, "Toggle which candidacy?", "Select role", be_special_flags)
if(!role)
Expand Down
151 changes: 106 additions & 45 deletions code/modules/cm_aliens/XenoStructures.dm
Original file line number Diff line number Diff line change
Expand Up @@ -884,12 +884,18 @@
var/hive_number = XENO_HIVE_NORMAL
/// Whether the cocoon has hatched
var/hatched = FALSE
/// Current running timer
var/timer
/// Is currently rolling candidates
var/rolling_candidates = FALSE
/// Voting for King
var/list/mob/living/carbon/xenomorph/votes = list()
/// Candidates
var/list/mob/living/carbon/xenomorph/candidates = list()
/// Time to hatch
var/time_to_hatch = 10 MINUTES
/// Announced that the hatchery was paused
var/announced_paused = FALSE
/// Stage of hatching
var/stage = 0

/obj/effect/alien/resin/king_cocoon/Destroy()
if(!hatched)
Expand All @@ -912,6 +918,7 @@

votes = null
chosen_candidate = null
candidates = null

. = ..()

Expand All @@ -930,8 +937,7 @@
var/obj/effect/build_blocker/blocker = new(turf_to_block, src)
blockers += blocker

timer = addtimer(CALLBACK(src, PROC_REF(start_growing)), 10 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME)
addtimer(CALLBACK(src, PROC_REF(check_pylons)), 10 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME|TIMER_LOOP)
START_PROCESSING(SSobj, src)

marine_announcement("ALERT.\n\nUNUSUAL ENERGY BUILDUP DETECTED IN [uppertext(get_area_name(loc))].\n\nESTIMATED TIME UNTIL COMPLETION - 10 MINUTES.", "[MAIN_AI_SYSTEM] Biological Scanner", 'sound/misc/notice1.ogg')
var/datum/hive_status/hive
Expand All @@ -944,18 +950,51 @@
else
xeno_announcement(SPAN_XENOANNOUNCE("Another hive's King is growing at [get_area_name(loc)]."), cur_hive_num, XENO_GENERAL_ANNOUNCE)

/// Callback for a repeating 10s timer to ensure both pylons are active (otherwise delete) and counts the number of marines groundside (would cause hatching to expedite).
/obj/effect/alien/resin/king_cocoon/proc/check_pylons()

#define STAGE_GROWING 1
#define STAGE_HALFWAY 2
#define STAGE_VOTE 3
#define STAGE_PICK 4
#define STAGE_BEFORE_HATCH 5
#define STAGE_HATCH 6

/obj/effect/alien/resin/king_cocoon/process(delta_time)
var/datum/hive_status/hive = GLOB.hive_datum[hive_number]

if(length(hive.active_endgame_pylons) < 2)
qdel(src)
if(!announced_paused)
marine_announcement("ALERT.\n\nUNUSUAL ENERGY BUILDUP IN [uppertext(get_area_name(loc))] HAS BEEN PAUSED.", "[MAIN_AI_SYSTEM] Biological Scanner", 'sound/misc/notice1.ogg')
for(var/cur_hive_num in GLOB.hive_datum)
hive = GLOB.hive_datum[cur_hive_num]
if(!length(hive.totalXenos))
continue
if(cur_hive_num == hive_number)
xeno_announcement(SPAN_XENOANNOUNCE("One of our pylons was destroyed, the hatchery has paused its progress!"), cur_hive_num, XENO_GENERAL_ANNOUNCE)
else
xeno_announcement(SPAN_XENOANNOUNCE("One of another hive's pylons was destroyed, the hatchery has paused its progress!"), cur_hive_num, XENO_GENERAL_ANNOUNCE)

announced_paused = TRUE
icon_state = "static"
return

if(chosen_candidate || rolling_candidates)
return

else if (length(hive.active_endgame_pylons) >= 2 && announced_paused)
for(var/cur_hive_num in GLOB.hive_datum)
hive = GLOB.hive_datum[cur_hive_num]
if(!length(hive.totalXenos))
continue
if(cur_hive_num == hive_number)
xeno_announcement(SPAN_XENOANNOUNCE("The hatchery's progress has resumed!"), cur_hive_num, XENO_GENERAL_ANNOUNCE)
else
xeno_announcement(SPAN_XENOANNOUNCE("Another hive's hatchery progress has resumed!"), cur_hive_num, XENO_GENERAL_ANNOUNCE)
marine_announcement("ALERT.\n\nUNUSUAL ENERGY BUILDUP IN [uppertext(get_area_name(loc))] HAS BEEN RESUMED.", "[MAIN_AI_SYSTEM] Biological Scanner", 'sound/misc/notice1.ogg')
announced_paused = FALSE
icon_state = "growing"

for(var/obj/effect/alien/resin/special/pylon/pylon as anything in hive.active_endgame_pylons)
pylon.protection_level = TURF_PROTECTION_OB
pylon.update_icon()

if(hatched)
STOP_PROCESSING(SSobj, src)
return

var/groundside_humans = 0
Expand All @@ -968,21 +1007,46 @@
groundside_humans += 1

if(groundside_humans > 12)
return
break

if(groundside_humans < 12)
// Too few marines are now groundside, hatch immediately
start_vote()
addtimer(CALLBACK(src, PROC_REF(roll_candidates)), 20 SECONDS)
addtimer(CALLBACK(src, PROC_REF(start_hatching), TRUE), 25 SECONDS)
STOP_PROCESSING(SSobj, src)
return

// Too few marines are now groundside, hatch immediately
deltimer(timer)
start_vote(expedite = TRUE)
time_to_hatch -= delta_time SECONDS

if(!stage && time_to_hatch < 10 MINUTES)
icon_state = "growing"
stage = STAGE_GROWING
else if (stage == STAGE_GROWING && time_to_hatch <= 5 MINUTES)
announce_halfway()
stage = STAGE_HALFWAY
else if (stage == STAGE_HALFWAY && time_to_hatch <= 1 MINUTES)
start_vote()
stage = STAGE_VOTE
else if (stage == STAGE_VOTE && time_to_hatch <= 40 SECONDS)
roll_candidates()
stage = STAGE_PICK
else if (stage == STAGE_PICK && time_to_hatch <= 20 SECONDS)
start_hatching()
stage = STAGE_BEFORE_HATCH
else if (stage == STAGE_BEFORE_HATCH && time_to_hatch <= 0)
animate_hatch_king()
STOP_PROCESSING(SSobj, src)

/// Causes the cocoon to change visually for growing and initiates the next timer.
/obj/effect/alien/resin/king_cocoon/proc/start_growing()
icon_state = "growing"
timer = addtimer(CALLBACK(src, PROC_REF(announce_halfway)), 5 MINUTES, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME)
#undef STAGE_GROWING
#undef STAGE_HALFWAY
#undef STAGE_VOTE
#undef STAGE_PICK
#undef STAGE_BEFORE_HATCH
#undef STAGE_HATCH

/// Causes the halfway announcements and initiates the next timer.
/obj/effect/alien/resin/king_cocoon/proc/announce_halfway()
timer = addtimer(CALLBACK(src, PROC_REF(start_vote)), 4 MINUTES, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME)

marine_announcement("ALERT.\n\nUNUSUAL ENERGY BUILDUP DETECTED IN [uppertext(get_area_name(loc))].\n\nESTIMATED TIME UNTIL COMPLETION - 5 MINUTES.", "[MAIN_AI_SYSTEM] Biological Scanner", 'sound/misc/notice1.ogg')
var/datum/hive_status/hive
for(var/cur_hive_num in GLOB.hive_datum)
Expand Down Expand Up @@ -1032,7 +1096,10 @@
if(!is_candidate_valid(hive, candidate, playtime_restricted))
return FALSE

return tgui_alert(candidate, "Would you like to become the King?", "Choice", list("Yes", "No"), 10 SECONDS) == "Yes"
if(!candidate.client)
return FALSE

return candidate.client.prefs.be_special & BE_KING

#undef KING_PLAYTIME_HOURS

Expand All @@ -1052,7 +1119,7 @@
votes[choice] = 1

/// Initiates a vote that will end in 20 seconds to vote for the King. Hatching will then begin in 1 minute unless expedited.
/obj/effect/alien/resin/king_cocoon/proc/start_vote(expedite = FALSE)
/obj/effect/alien/resin/king_cocoon/proc/start_vote()
rolling_candidates = TRUE
var/datum/hive_status/hive = GLOB.hive_datum[hive_number]

Expand All @@ -1066,7 +1133,8 @@
if(is_candidate_valid(hive, candidate, playtime_restricted = FALSE, skip_playtime = FALSE))
INVOKE_ASYNC(src, PROC_REF(cast_vote), candidate, voting_candidates)

addtimer(CALLBACK(src, PROC_REF(roll_candidates), voting_candidates, expedite), 20 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME)
candidates = voting_candidates


/**
* Finalizes the vote for King opting to use a series of fallbacks in case a candidate declines.
Expand All @@ -1077,12 +1145,8 @@
* Then all other living xenos not meeting the playtime requirement are asked.
* Then all other xeno observer candidates not meeting the playtime requirement are asked.
* Then finally if after all that, the search is given up and will ultimately result in a freed King mob.
*
* Arguments:
* * voting_candidates: A list of xenomorphs that are valid candidates to vote on.
* * expedite: Whether hatching should begin in a minute or immediately after a candidate is found.
*/
/obj/effect/alien/resin/king_cocoon/proc/roll_candidates(list/mob/living/carbon/xenomorph/voting_candidates, expedite = FALSE)
/obj/effect/alien/resin/king_cocoon/proc/roll_candidates()
var/datum/hive_status/hive = GLOB.hive_datum[hive_number]

var/primary_votes = 0
Expand All @@ -1103,70 +1167,67 @@
if(prob(50) && try_roll_candidate(hive, primary_candidate, playtime_restricted = TRUE))
chosen_candidate = primary_candidate.client
rolling_candidates = FALSE
start_hatching(expedite)
return

voting_candidates -= primary_candidate
candidates -= primary_candidate


if(try_roll_candidate(hive, secondary_candidate, playtime_restricted = TRUE))
chosen_candidate = secondary_candidate.client
rolling_candidates = FALSE
start_hatching(expedite)
return

voting_candidates -= secondary_candidate
candidates -= secondary_candidate

// Otherwise ask all the living xenos (minus the player(s) who got voted on earlier)
for(var/mob/living/carbon/xenomorph/candidate in shuffle(voting_candidates))
for(var/mob/living/carbon/xenomorph/candidate in shuffle(candidates))
if(try_roll_candidate(hive, candidate, playtime_restricted = TRUE))
chosen_candidate = candidate.client
rolling_candidates = FALSE
start_hatching(expedite)
return

// Then observers
var/list/observer_list_copy = shuffle(get_alien_candidates(hive))

for(var/mob/candidate in observer_list_copy)
if(try_roll_candidate(hive, candidate, playtime_restricted = TRUE))
chosen_candidate = candidate.client
rolling_candidates = FALSE
start_hatching(expedite)
return

// Lastly all of the above again, without playtime requirements
for(var/mob/living/carbon/xenomorph/candidate in shuffle(hive.totalXenos.Copy() - hive.living_xeno_queen))
if(try_roll_candidate(hive, candidate, playtime_restricted = FALSE))
chosen_candidate = candidate.client
rolling_candidates = FALSE
start_hatching(expedite)
return

for(var/mob/candidate in observer_list_copy)
if(try_roll_candidate(hive, candidate, playtime_restricted = FALSE))
chosen_candidate = candidate.client
rolling_candidates = FALSE
start_hatching(expedite)
return
message_admins("Failed to find a client for the King, releasing as freed mob.")
start_hatching(expedite)


/// Starts the hatching in one minute, otherwise immediately if expedited
/// Starts the hatching in twenty seconds, otherwise immediately if expedited
/obj/effect/alien/resin/king_cocoon/proc/start_hatching(expedite = FALSE)
votes = null
candidates = null
if(expedite)
animate_hatch_king()
return

marine_announcement("ALERT.\n\nUNUSUAL ENERGY BUILDUP DETECTED IN [get_area_name(loc)].\n\nESTIMATED TIME UNTIL COMPLETION - ONE MINUTE.", "[MAIN_AI_SYSTEM] Biological Scanner", 'sound/misc/notice1.ogg')
marine_announcement("ALERT.\n\nUNUSUAL ENERGY BUILDUP DETECTED IN [get_area_name(loc)].\n\nESTIMATED TIME UNTIL COMPLETION - 20 SECONDS.", "[MAIN_AI_SYSTEM] Biological Scanner", 'sound/misc/notice1.ogg')
var/datum/hive_status/hive
for(var/cur_hive_num in GLOB.hive_datum)
hive = GLOB.hive_datum[cur_hive_num]
if(!length(hive.totalXenos))
continue
if(cur_hive_num == hive_number)
xeno_announcement(SPAN_XENOANNOUNCE("The King will hatch in approximately one minute."), cur_hive_num, XENO_GENERAL_ANNOUNCE)
xeno_announcement(SPAN_XENOANNOUNCE("The King will hatch in approximately twenty seconds."), cur_hive_num, XENO_GENERAL_ANNOUNCE)
else
xeno_announcement(SPAN_XENOANNOUNCE("Another hive's King will hatch in approximately one minute."), cur_hive_num, XENO_GENERAL_ANNOUNCE)

timer = addtimer(CALLBACK(src, PROC_REF(animate_hatch_king)), 1 MINUTES, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME)
xeno_announcement(SPAN_XENOANNOUNCE("Another hive's King will hatch in approximately twenty seconds."), cur_hive_num, XENO_GENERAL_ANNOUNCE)

/// Causes the cocoon to change visually for hatching and initiates the next timer.
/obj/effect/alien/resin/king_cocoon/proc/animate_hatch_king()
Expand Down
Loading

0 comments on commit 2416cb9

Please sign in to comment.