Refactor/tidies up latejoin antags/in-round antag spawning.

This commit is contained in:
Zuhayr
2015-06-21 19:33:49 +09:30
parent ec5e05b9f1
commit d3bd63eec9
12 changed files with 115 additions and 123 deletions

View File

@@ -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"

View File

@@ -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()

View File

@@ -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)

View File

@@ -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

View File

@@ -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))

View File

@@ -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]")

View File

@@ -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>"

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View 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))

View File

@@ -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/>"