mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Refactor/tidies up latejoin antags/in-round antag spawning.
This commit is contained in:
@@ -252,6 +252,7 @@
|
||||
#include "code\game\dna\genes\powers.dm"
|
||||
#include "code\game\gamemodes\events.dm"
|
||||
#include "code\game\gamemodes\game_mode.dm"
|
||||
#include "code\game\gamemodes\game_mode_latespawn.dm"
|
||||
#include "code\game\gamemodes\gameticker.dm"
|
||||
#include "code\game\gamemodes\intercept_report.dm"
|
||||
#include "code\game\gamemodes\objective.dm"
|
||||
|
||||
@@ -33,8 +33,9 @@
|
||||
var/nuke_spawn_loc
|
||||
|
||||
var/list/valid_species = list("Unathi","Tajara","Skrell","Human") // Used for setting appearance.
|
||||
var/list/starting_locations = list()
|
||||
var/list/current_antagonists = list()
|
||||
var/list/pending_antagonists = list()
|
||||
var/list/starting_locations = list()
|
||||
var/list/global_objectives = list()
|
||||
var/list/restricted_jobs = list()
|
||||
var/list/protected_jobs = list()
|
||||
@@ -57,29 +58,32 @@
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/get_candidates(var/ghosts_only)
|
||||
|
||||
candidates = list() // Clear.
|
||||
candidates = ticker.mode.get_players_for_role(role_type, id)
|
||||
// Prune restricted jobs and status.
|
||||
// Prune restricted jobs and status. Broke it up for readability.
|
||||
for(var/datum/mind/player in candidates)
|
||||
if((ghosts_only && !istype(player.current, /mob/dead)) || player.special_role || (player.assigned_role in restricted_jobs))
|
||||
if(ghosts_only && !istype(player.current, /mob/dead))
|
||||
candidates -= player
|
||||
else if(player.special_role)
|
||||
candidates -= player
|
||||
else if (player in pending_antagonists)
|
||||
candidates -= player
|
||||
else if(!can_become_antag(player))
|
||||
candidates -= player
|
||||
return candidates
|
||||
|
||||
/datum/antagonist/proc/attempt_random_spawn()
|
||||
attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
|
||||
|
||||
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player, var/move_to_spawn)
|
||||
|
||||
update_current_antag_max()
|
||||
if(get_antag_count() >= cur_max)
|
||||
return 0
|
||||
|
||||
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player)
|
||||
if(!can_late_spawn())
|
||||
return
|
||||
if(!istype(player)) player = get_candidates(is_latejoin_template())
|
||||
player.current << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
|
||||
if(move_to_spawn)
|
||||
place_mob(player.current)
|
||||
add_antagonist(player)
|
||||
equip(player.current)
|
||||
if(istype(player.current, /mob/dead))
|
||||
create_default(player.current)
|
||||
else
|
||||
add_antagonist(player,0,1,0,1,1)
|
||||
return
|
||||
|
||||
/datum/antagonist/proc/attempt_spawn(var/ghosts_only)
|
||||
@@ -95,11 +99,14 @@
|
||||
//Grab candidates randomly until we have enough.
|
||||
while(candidates.len)
|
||||
var/datum/mind/player = pick(candidates)
|
||||
current_antagonists |= player
|
||||
// Update job and role.
|
||||
player.special_role = role_text
|
||||
if(flags & ANTAG_OVERRIDE_JOB)
|
||||
player.assigned_role = "MODE"
|
||||
pending_antagonists |= player
|
||||
candidates -= player
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/finalize_spawn()
|
||||
if(!pending_antagonists || !pending_antagonists.len)
|
||||
return
|
||||
for(var/datum/mind/player in pending_antagonists)
|
||||
if(can_become_antag(player) && !player.special_role)
|
||||
add_antagonist(player,0,0,1)
|
||||
pending_antagonists.Cut()
|
||||
@@ -1,14 +1,23 @@
|
||||
/datum/antagonist/proc/add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance)
|
||||
if(!istype(player))
|
||||
return 0
|
||||
if(!player.current)
|
||||
return 0
|
||||
if(player in current_antagonists)
|
||||
return 0
|
||||
if(!can_become_antag(player, ignore_role))
|
||||
return 0
|
||||
|
||||
current_antagonists |= player
|
||||
create_antagonist(player, move_to_spawn, do_not_announce, preserve_appearance)
|
||||
if(!do_not_equip && player.current)
|
||||
equip(player.current)
|
||||
if(flags & ANTAG_OVERRIDE_JOB)
|
||||
player.assigned_role = "MODE"
|
||||
|
||||
if(istype(player.current, /mob/dead))
|
||||
create_default(player.current)
|
||||
else
|
||||
create_antagonist(player, move_to_spawn, do_not_announce, preserve_appearance)
|
||||
if(!do_not_equip)
|
||||
equip(player.current)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
/datum/antagonist/proc/create_default(var/mob/source)
|
||||
var/mob/living/M
|
||||
if(mob_path)
|
||||
M = new mob_path()
|
||||
M = new mob_path(get_turf(source))
|
||||
else
|
||||
M = new /mob/living/carbon/human
|
||||
M = new /mob/living/carbon/human(get_turf(source))
|
||||
M.real_name = source.real_name
|
||||
M.name = M.real_name
|
||||
M.ckey = source.ckey
|
||||
|
||||
@@ -30,4 +30,13 @@
|
||||
return 0
|
||||
|
||||
/datum/antagonist/proc/is_votable()
|
||||
return (flags & ANTAG_VOTABLE)
|
||||
return (flags & ANTAG_VOTABLE)
|
||||
|
||||
/datum/antagonist/proc/can_late_spawn()
|
||||
update_current_antag_max()
|
||||
if(get_antag_count() >= cur_max)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/is_latejoin_template()
|
||||
return (flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB))
|
||||
@@ -23,8 +23,6 @@
|
||||
for(var/datum/objective/O in global_objectives)
|
||||
if(!O.completed && !O.check_completion())
|
||||
result = 0
|
||||
else
|
||||
O.completed = 1 //Will this break anything?
|
||||
if(result && victory_text)
|
||||
world << "<span class='danger'><font size = 3>[victory_text]</span>"
|
||||
if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/num = 1
|
||||
for(var/datum/objective/O in P.objectives)
|
||||
text += print_objective(O, num)
|
||||
if(O.completed) // This is set actively in check_victory()
|
||||
if(O.check_completion())
|
||||
text += "<font color='green'><B>Success!</B></font>"
|
||||
feedback_add_details(feedback_tag,"[O.type]|SUCCESS")
|
||||
else
|
||||
@@ -21,11 +21,11 @@
|
||||
failed = 1
|
||||
num++
|
||||
|
||||
if(!config.objectives_disabled)
|
||||
if(failed)
|
||||
text += "<br><font color='red'><B>The [role_text] has failed.</B></font>"
|
||||
else
|
||||
text += "<br><font color='green'><B>The [role_text] was successful!</B></font>"
|
||||
if(!config.objectives_disabled)
|
||||
if(failed)
|
||||
text += "<br><font color='red'><B>The [role_text] has failed.</B></font>"
|
||||
else
|
||||
text += "<br><font color='green'><B>The [role_text] was successful!</B></font>"
|
||||
|
||||
if(global_objectives && global_objectives.len)
|
||||
text += "<BR/><FONT size = 2>Their objectives were:<FONT>"
|
||||
|
||||
@@ -62,15 +62,10 @@
|
||||
qdel(I)
|
||||
|
||||
/datum/antagonist/proc/update_current_antag_max()
|
||||
|
||||
candidates = list()
|
||||
var/main_type
|
||||
if(ticker && ticker.mode)
|
||||
if(ticker.mode.antag_tag && ticker.mode.antag_tag == id)
|
||||
main_type = 1
|
||||
else
|
||||
return list()
|
||||
|
||||
cur_max = (main_type ? max_antags_round : max_antags)
|
||||
if(ticker.mode.antag_scaling_coeff)
|
||||
cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max)
|
||||
cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max)
|
||||
|
||||
@@ -9,8 +9,8 @@ var/datum/antagonist/ninja/ninjas
|
||||
landmark_id = "ninjastart"
|
||||
welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor.</span>"
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
|
||||
max_antags = 3
|
||||
max_antags_round = 3
|
||||
max_antags = 1//3
|
||||
max_antags_round = 1//3
|
||||
|
||||
/datum/antagonist/ninja/New()
|
||||
..()
|
||||
@@ -164,7 +164,7 @@ var/datum/antagonist/ninja/ninjas
|
||||
if(17)
|
||||
directive += "The Spider Clan has recently begun recruiting outsiders. Consider suitable candidates and assess their behavior amongst the crew."
|
||||
if(18)
|
||||
directive += "A cyborg liberation group has expressed interest in our serves. Prove the Spider Clan merciful towards law-bound synthetics."
|
||||
directive += "A cyborg liberation group has expressed interest in our services. Prove the Spider Clan merciful towards law-bound synthetics."
|
||||
else
|
||||
directive += "There are no special supplemental instructions at this time."
|
||||
return directive
|
||||
|
||||
@@ -42,17 +42,10 @@ var/global/list/additional_antag_types = list()
|
||||
|
||||
var/antag_tag // First (main) antag template to spawn.
|
||||
var/list/antag_templates // Extra antagonist types to include.
|
||||
|
||||
var/list/latejoin_templates = list()
|
||||
var/round_autoantag = 0 // Will this round attempt to periodically spawn more antagonists?
|
||||
var/antag_prob = 0 // Likelihood of a new antagonist spawning.
|
||||
var/antag_count = 0 // Current number of antagonists.
|
||||
var/antag_scaling_coeff = 5 // Coefficient for scaling max antagonists to player count.
|
||||
|
||||
var/list/living_antag_templates = list() // Currently selected antag types that do not require a ghosted player.
|
||||
var/list/ghost_antag_templates = list() // Inverse of above.
|
||||
var/list/antag_candidates = list() // Living antag candidates.
|
||||
var/list/ghost_candidates = list() // Observing antag candidates.
|
||||
|
||||
var/station_was_nuked = 0 // See nuclearbomb.dm and malfunction.dm.
|
||||
var/explosion_in_progress = 0 // Sit back and relax
|
||||
var/waittime_l = 600 // Lower bound on time before intercept arrives (in tenths of seconds)
|
||||
@@ -272,7 +265,6 @@ var/global/list/additional_antag_types = list()
|
||||
EMajor.delay_modifier = event_delay_mod_major
|
||||
|
||||
///post_setup()
|
||||
///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things
|
||||
/datum/game_mode/proc/post_setup()
|
||||
|
||||
refresh_event_modifiers()
|
||||
@@ -285,9 +277,11 @@ var/global/list/additional_antag_types = list()
|
||||
spawn(rand(100,150))
|
||||
announce_ert_disabled()
|
||||
|
||||
//if(antag_templates && antag_templates.len)
|
||||
// for(var/datum/antagonist/antag in antag_templates)
|
||||
// antag.finalize()
|
||||
if(antag_templates && antag_templates.len)
|
||||
for(var/datum/antagonist/antag in antag_templates)
|
||||
antag.finalize_spawn()
|
||||
if(antag.is_latejoin_template())
|
||||
latejoin_templates |= antag
|
||||
|
||||
if(emergency_shuttle && auto_recall_shuttle)
|
||||
emergency_shuttle.auto_recall = 1
|
||||
@@ -336,67 +330,6 @@ var/global/list/additional_antag_types = list()
|
||||
)
|
||||
command_announcement.Announce("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time, and post-evacuation recovery efforts will be substantially delayed.","Emergency Transmission")
|
||||
|
||||
///process()
|
||||
///Called by the gameticker
|
||||
/datum/game_mode/proc/process()
|
||||
|
||||
if(emergency_shuttle.departed)
|
||||
return
|
||||
|
||||
if(!round_autoantag || !antag_templates || !antag_templates.len)
|
||||
return
|
||||
|
||||
var/player_count = 0
|
||||
antag_count = 0
|
||||
antag_candidates = list()
|
||||
|
||||
for(var/mob/living/player in mob_list)
|
||||
if(player.client)
|
||||
player_count += 1
|
||||
if(player.mind)
|
||||
if(player.stat == 2) // observing
|
||||
ghost_candidates |= player
|
||||
else
|
||||
if(player.mind.special_role)
|
||||
antag_count += 1
|
||||
else
|
||||
antag_candidates |= player
|
||||
|
||||
antag_prob = min(100,max(0,(player_count - 5 * 10) * 5)) // This is arbitrary, probably needs adjusting.
|
||||
|
||||
var/datum/antagonist/spawn_antag
|
||||
var/datum/mind/candidate
|
||||
|
||||
var/from_ghosts
|
||||
if(prob(antag_prob))
|
||||
if(ghost_candidates.len && ghost_antag_templates.len && prob(50))
|
||||
spawn_antag = pick(ghost_antag_templates)
|
||||
candidate = pick(ghost_candidates)
|
||||
from_ghosts = 1
|
||||
else if(antag_candidates.len && living_antag_templates.len)
|
||||
spawn_antag = pick(living_antag_templates)
|
||||
candidate = pick(antag_candidates)
|
||||
else
|
||||
return // Failed :(
|
||||
else
|
||||
return
|
||||
|
||||
if(spawn_antag.can_become_antag(candidate))
|
||||
spawn_antag.attempt_late_spawn(candidate, from_ghosts)
|
||||
|
||||
/datum/game_mode/proc/latespawn(mob/living/carbon/human/character)
|
||||
|
||||
if(emergency_shuttle.departed || !character.mind)
|
||||
return
|
||||
|
||||
var/datum/antagonist/spawn_antag
|
||||
if(prob(antag_prob) && round_autoantag && living_antag_templates.len)
|
||||
spawn_antag = pick(living_antag_templates)
|
||||
if(spawn_antag && spawn_antag.can_become_antag(character.mind))
|
||||
spawn_antag.attempt_late_spawn(character.mind)
|
||||
|
||||
return 0
|
||||
|
||||
/datum/game_mode/proc/check_finished()
|
||||
if(emergency_shuttle.returned() || station_was_nuked)
|
||||
return 1
|
||||
@@ -623,13 +556,10 @@ var/global/list/additional_antag_types = list()
|
||||
|
||||
if(antag_templates && antag_templates.len)
|
||||
for(var/datum/antagonist/antag in antag_templates)
|
||||
if(antag.flags & ANTAG_OVERRIDE_JOB)
|
||||
ghost_antag_templates |= antag
|
||||
else if(antag.flags & ANTAG_RANDSPAWN)
|
||||
living_antag_templates |= antag
|
||||
else
|
||||
antag_templates -= antag
|
||||
world << "<span class='danger'>[antag.role_text_plural] are invalid for additional roundtype antags!</span>"
|
||||
if(antag.flags & (ANTAG_OVERRIDE_JOB|ANTAG_RANDSPAWN))
|
||||
continue
|
||||
antag_templates -= antag
|
||||
world << "<span class='danger'>[antag.role_text_plural] are invalid for additional roundtype antags!</span>"
|
||||
|
||||
newscaster_announcements = pick(newscaster_standard_feeds)
|
||||
|
||||
|
||||
43
code/game/gamemodes/game_mode_latespawn.dm
Normal file
43
code/game/gamemodes/game_mode_latespawn.dm
Normal file
@@ -0,0 +1,43 @@
|
||||
/datum/game_mode/proc/get_usable_templates(var/list/supplied_templates)
|
||||
var/list/usable_templates = list()
|
||||
for(var/datum/antagonist/A in supplied_templates)
|
||||
if(A.can_late_spawn())
|
||||
usable_templates |= A
|
||||
return usable_templates
|
||||
|
||||
///process()
|
||||
///Called by the gameticker
|
||||
/datum/game_mode/proc/process()
|
||||
try_latespawn()
|
||||
|
||||
/datum/game_mode/proc/latespawn(var/mob/living/carbon/human/character)
|
||||
if(!character.mind)
|
||||
return
|
||||
try_latespawn(character.mind)
|
||||
return 0
|
||||
|
||||
/datum/game_mode/proc/try_latespawn(var/datum/mind/player, var/latejoin_only)
|
||||
|
||||
if(emergency_shuttle.departed || !round_autoantag)
|
||||
return
|
||||
|
||||
if(!prob(get_antag_prob()))
|
||||
return
|
||||
|
||||
var/list/usable_templates
|
||||
if(latejoin_only && latejoin_templates.len)
|
||||
usable_templates = get_usable_templates(latejoin_templates)
|
||||
else if (antag_templates.len)
|
||||
usable_templates = get_usable_templates(antag_templates)
|
||||
else
|
||||
return
|
||||
if(usable_templates.len)
|
||||
var/datum/antagonist/spawn_antag = pick(usable_templates)
|
||||
spawn_antag.attempt_late_spawn(player)
|
||||
|
||||
/datum/game_mode/proc/get_antag_prob()
|
||||
var/player_count = 0
|
||||
for(var/mob/living/M in mob_list)
|
||||
if(M.client)
|
||||
player_count += 1
|
||||
return min(100,max(0,(player_count - 5 * 10) * 5))
|
||||
@@ -1164,7 +1164,7 @@ proc/admin_notice(var/message, var/rights)
|
||||
out += "<b>Core antag id:</b> <a href='?src=\ref[ticker.mode];debug_antag=[ticker.mode.antag_tag]'>[ticker.mode.antag_tag]</a>.</br>"
|
||||
|
||||
if(ticker.mode.round_autoantag)
|
||||
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>enabled</a></b> ([ticker.mode.antag_prob]% spawn chance)"
|
||||
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>enabled</a></b> ([ticker.mode.get_antag_prob()]% spawn chance)"
|
||||
if(ticker.mode.antag_scaling_coeff)
|
||||
out += " (scaling with <a href='?src=\ref[ticker.mode];set=antag_scaling'>[ticker.mode.antag_scaling_coeff]</a>)"
|
||||
out += "<br/>"
|
||||
|
||||
Reference in New Issue
Block a user