Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
AmoryBlaine committed Aug 5, 2024
1 parent 72548b8 commit 4362009
Show file tree
Hide file tree
Showing 2 changed files with 289 additions and 0 deletions.
288 changes: 288 additions & 0 deletions code/game/gamemodes/colonialmarines/xenovsxeno.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
#define is_hive_living(hive) (!hive.hardcore || hive.living_xeno_queen)

/datum/game_mode/xenovs
name = GAMEMODE_HIVE_WARS
config_tag = GAMEMODE_HIVE_WARS
required_players = 4 //Need at least 4 players
xeno_required_num = 4 //Need at least four xenos.
monkey_amount = 0.2 // Amount of monkeys per player
flags_round_type = MODE_NO_SPAWN|MODE_NO_LATEJOIN|MODE_XVX|MODE_RANDOM_HIVE

var/list/structures_to_delete = list(/obj/effect/alien/weeds, /turf/closed/wall/resin, /obj/structure/mineral_door/resin, /obj/structure/bed/nest, /obj/item, /obj/structure/tunnel, /obj/structure/machinery/computer/shuttle_control, /obj/structure/machinery/defenses/sentry/premade)
var/list/hives = list()
var/list/hive_cores = list()

var/sudden_death = FALSE
var/time_until_sd = 90 MINUTES

var/list/current_hives = list()

var/hive_larva_interval_gain = 5 MINUTES

var/round_time_larva_interval = 0
var/round_time_sd = 0
votable = FALSE // broken

/* Pre-pre-startup */
/datum/game_mode/xenovs/can_start()
for(var/hivename in SSmapping.configs[GROUND_MAP].xvx_hives)
if(readied_players > SSmapping.configs[GROUND_MAP].xvx_hives[hivename])
hives += hivename
xeno_starting_num = readied_players
if(!initialize_starting_xenomorph_list(hives, TRUE))
hives.Cut()
return
return TRUE

/datum/game_mode/xenovs/announce()
to_chat_spaced(world, type = MESSAGE_TYPE_SYSTEM, html = SPAN_ROUNDHEADER("The current map is - [SSmapping.configs[GROUND_MAP].map_name]!"))

/datum/game_mode/xenovs/get_roles_list()
return ROLES_XENO

/* Pre-setup */
/datum/game_mode/xenovs/pre_setup()
monkey_types = SSmapping.configs[GROUND_MAP].monkey_types
if(monkey_amount)
if(monkey_types.len)
for(var/i = min(round(monkey_amount*GLOB.clients.len), GLOB.monkey_spawns.len), i > 0, i--)

var/turf/T = get_turf(pick_n_take(GLOB.monkey_spawns))
var/monkey_to_spawn = pick(monkey_types)
new monkey_to_spawn(T)


for(var/atom/A in world)
for(var/type in structures_to_delete)
if(istype(A, type))
if(istype(A, /turf))
var/turf/T = A
T.ScrapeAway()
else
qdel(A)

round_time_sd = (time_until_sd + world.time)

update_controllers()

..()
return TRUE

/datum/game_mode/xenovs/proc/update_controllers()
//Update controllers while we're on this mode
if(SSitem_cleanup)
//Cleaning stuff more aggressively
SSitem_cleanup.start_processing_time = 0
SSitem_cleanup.percentage_of_garbage_to_delete = 1
SSitem_cleanup.wait = 1 MINUTES
SSitem_cleanup.next_fire = 1 MINUTES
spawn(0)
//Deleting Almayer, for performance!
SSitem_cleanup.delete_almayer()

////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////

/* Post-setup */
//This happens after create_character, so our mob SHOULD be valid and built by now, but without job data.
//We move it later with transform_survivor but they might flicker at any start_loc spawn landmark effects then disappear.
//Xenos and survivors should not spawn anywhere until we transform them.
/datum/game_mode/xenovs/post_setup()
initialize_post_xenomorph_list(GLOB.xeno_hive_spawns)

round_time_lobby = world.time
for(var/area/A in all_areas)
if(!(A.is_resin_allowed))
A.is_resin_allowed = TRUE

open_podlocks("map_lockdown")

..()

/datum/game_mode/xenovs/proc/initialize_post_xenomorph_list(list/hive_spawns = GLOB.xeno_spawns)
var/list/hive_spots = list()
for(var/hive in hives)
var/turf/spot = get_turf(pick(hive_spawns))
hive_spots[GLOB.hive_datum[hive]] = spot
hive_spawns -= spot

current_hives += GLOB.hive_datum[hive].name

for(var/datum/hive_status/hive in xenomorphs) //Build and move the xenos.
for(var/datum/mind/ghost_mind in xenomorphs[hive])
transform_xeno(ghost_mind, hive_spots[hive], hive.hivenumber, FALSE)
ghost_mind.current.close_spawn_windows()

// Have to spawn the queen last or the mind will be added to xenomorphs and double spawned
for(var/datum/hive_status/hive in picked_queens)
transform_queen(picked_queens[hive], hive_spots[hive], hive.hivenumber)
var/datum/mind/M = picked_queens[hive]
M.current.close_spawn_windows()

for(var/datum/hive_status/hive in hive_spots)
var/obj/effect/alien/resin/special/pylon/core/C = new(hive_spots[hive], hive)
C.hardcore = TRUE // This'll make losing the hive core more detrimental than losing a Queen
hive_cores += C

/datum/game_mode/xenovs/proc/transform_xeno(datum/mind/ghost_mind, turf/xeno_turf, hivenumber = XENO_HIVE_NORMAL, should_spawn_nest = TRUE)
if(should_spawn_nest)
var/mob/living/carbon/human/original = ghost_mind.current

original.first_xeno = TRUE
original.set_stat(UNCONSCIOUS)
original.spawned_corpse = TRUE

for(var/obj/item/device/radio/radio in original.contents_recursive())
radio.listening = FALSE

var/obj/structure/bed/nest/start_nest = new /obj/structure/bed/nest(original.loc) //Create a new nest for the host
original.statistic_exempt = TRUE
original.buckled = start_nest
original.setDir(start_nest.dir)
start_nest.buckled_mob = original
start_nest.afterbuckle(original)

var/obj/item/alien_embryo/embryo = new /obj/item/alien_embryo(original) //Put the initial larva in a host
embryo.stage = 5 //Give the embryo a head-start (make the larva burst instantly)
embryo.hivenumber = hivenumber

if(original && !original.first_xeno)
qdel(original)
else
var/mob/living/carbon/xenomorph/larva/L = new(xeno_turf, null, hivenumber)
ghost_mind.transfer_to(L)

/datum/game_mode/xenovs/pick_queen_spawn(datum/mind/ghost_mind, hivenumber = XENO_HIVE_NORMAL)
. = ..()
if(!.) return
// Spawn additional hive structures
var/turf/T = .
var/area/AR = get_area(T)
if(!AR) return
for(var/obj/effect/landmark/structure_spawner/xvx_hive/SS in AR)
SS.apply()
qdel(SS)

////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////

//This is processed each tick, but check_win is only checked 5 ticks, so we don't go crazy with scanning for mobs.
/datum/game_mode/xenovs/process()
. = ..()
if(--round_started > 0)
return FALSE //Initial countdown, just to be safe, so that everyone has a chance to spawn before we check anything.



if(!round_finished)
if(++round_checkwin >= 5) //Only check win conditions every 5 ticks.
if(world.time > round_time_larva_interval)
for(var/hive in hives)
GLOB.hive_datum[hive].stored_larva++
GLOB.hive_datum[hive].hive_ui.update_burrowed_larva()

round_time_larva_interval = world.time + hive_larva_interval_gain

if(!sudden_death && world.time > round_time_sd)
sudden_death = TRUE
xeno_announcement("The hives have entered sudden death mode. No more respawns, no more Queens", "everything", HIGHER_FORCE_ANNOUNCE)
for(var/obj/effect/alien/resin/special/pylon/core/C in hive_cores)
qdel(C)
hive_cores = list()

if(round_should_check_for_win)
check_win()
round_checkwin = 0


/datum/game_mode/xenovs/proc/get_xenos_hive(list/z_levels = SSmapping.levels_by_any_trait(list(ZTRAIT_GROUND, ZTRAIT_RESERVED, ZTRAIT_MARINE_MAIN_SHIP)))
var/list/list/hivenumbers = list()
var/datum/hive_status/HS
for(var/hivenumber in GLOB.hive_datum)
HS = GLOB.hive_datum[hivenumber]
hivenumbers += list(HS.name = list())

for(var/mob/M in GLOB.player_list)
if(M.z && (M.z in z_levels) && M.stat != DEAD && !istype(M.loc, /turf/open/space)) //If they have a z var, they are on a turf.
var/mob/living/carbon/xenomorph/X = M
var/datum/hive_status/hive = GLOB.hive_datum[X.hivenumber]
if(!hive)
continue

if(istype(X) && is_hive_living(hive))
hivenumbers[hive.name].Add(X)


return hivenumbers

///////////////////////////
//Checks to see who won///
//////////////////////////
/datum/game_mode/xenovs/check_win()
if(SSticker.current_state != GAME_STATE_PLAYING)
return

var/list/living_player_list = get_xenos_hive()

var/last_living_hive
var/living_hives = 0

for(var/H in living_player_list)
if(length(living_player_list[H]) > 0)
living_hives++
last_living_hive = H
else if (H in current_hives)
xeno_announcement("\The [H] has been eliminated from the world", "everything", HIGHER_FORCE_ANNOUNCE)
current_hives -= H


if(!living_hives)
round_finished = "No one has won."
else if (living_hives == 1)
round_finished = "The [last_living_hive] has won."


///////////////////////////////
//Checks if the round is over//
///////////////////////////////
/datum/game_mode/xenovs/check_finished()
if(round_finished)
return TRUE

//////////////////////////////////////////////////////////////////////
//Announces the end of the game with all relevant information stated//
//////////////////////////////////////////////////////////////////////
/datum/game_mode/xenovs/declare_completion()
announce_ending()
var/musical_track
musical_track = pick('sound/theme/neutral_melancholy1.ogg', 'sound/theme/neutral_melancholy2.ogg')

var/sound/S = sound(musical_track, channel = SOUND_CHANNEL_LOBBY)
S.status = SOUND_STREAM
sound_to(world, S)
if(round_statistics)
round_statistics.game_mode = name
round_statistics.round_length = world.time
round_statistics.end_round_player_population = GLOB.clients.len

round_statistics.log_round_statistics()

declare_completion_announce_xenomorphs()
calculate_end_statistics()
declare_fun_facts()


return TRUE

/datum/game_mode/xenovs/announce_ending()
if(round_statistics)
round_statistics.track_round_end()
log_game("Round end result: [round_finished]")
to_chat_spaced(world, margin_top = 2, type = MESSAGE_TYPE_SYSTEM, html = SPAN_ROUNDHEADER("|Round Complete|"))
to_chat_spaced(world, type = MESSAGE_TYPE_SYSTEM, html = SPAN_ROUNDBODY("Thus ends the story of the battling hives on [SSmapping.configs[GROUND_MAP].map_name]. [round_finished]\nThe game-mode was: [master_mode]!\n[CONFIG_GET(string/endofroundblurb)]"))

// for the toolbox
/datum/game_mode/xenovs/end_round_message()
if(round_finished)
return "Hive Wars Round has ended. [round_finished]"
return "Hive Wars Round has ended. No one has won"
1 change: 1 addition & 0 deletions colonialmarines.dme
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,7 @@
#include "code\game\gamemodes\events.dm"
#include "code\game\gamemodes\game_mode.dm"
#include "code\game\gamemodes\colonialmarines\colonialmarines.dm"
#include "code\game\gamemodes\colonialmarines\xenovsxeno.dm"
#include "code\game\gamemodes\colonialmarines\ai\colonialmarines_ai.dm"
#include "code\game\gamemodes\colonialmarines\ai\colonialmarines_ai_nospawn.dm"
#include "code\game\gamemodes\events\power_failure.dm"
Expand Down

0 comments on commit 4362009

Please sign in to comment.