Working on gamemode/antagonist code.

This commit is contained in:
Zuhayr
2015-03-17 01:23:03 +10:30
parent d79af13a2c
commit 4fdc00dee4
9 changed files with 106 additions and 126 deletions

View File

@@ -1,3 +1,5 @@
var/list/gamemode_cache = list()
/datum/configuration
var/server_name = null // server name (for world name / status)
var/server_suffix = 0 // generate numeric suffix based on server port
@@ -197,8 +199,8 @@
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
var/datum/game_mode/M = new T()
if (M.config_tag)
gamemode_cache[M.config_tag] = M // So we don't instantiate them repeatedly.
if(!(M.config_tag in modes)) // ensure each mode is added only once
log_misc("Adding game mode [M.name] ([M.config_tag]) to configuration.")
src.modes += M.config_tag
@@ -206,7 +208,6 @@
src.probabilities[M.config_tag] = M.probability
if (M.votable)
src.votable_modes += M.config_tag
del(M)
src.votable_modes += "secret"
/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist
@@ -779,24 +780,20 @@
/datum/configuration/proc/pick_mode(mode_name)
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
for (var/T in (typesof(/datum/game_mode) - /datum/game_mode))
var/datum/game_mode/M = new T()
for (var/game_mode in gamemode_cache)
var/datum/game_mode/M = gamemode_cache[game_mode]
if (M.config_tag && M.config_tag == mode_name)
M.create_antagonists()
return M
del(M)
return new /datum/game_mode/extended()
return gamemode_cache["extended"]
/datum/configuration/proc/get_runnable_modes()
var/list/datum/game_mode/runnable_modes = new
for (var/T in (typesof(/datum/game_mode) - /datum/game_mode))
var/datum/game_mode/M = new T()
//world << "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]"
for (var/game_mode in gamemode_cache)
var/datum/game_mode/M = gamemode_cache[game_mode]
if (!(M.config_tag in modes))
del(M)
continue
if (probabilities[M.config_tag]<=0)
del(M)
continue
if (M.can_start())
runnable_modes[M] = probabilities[M.config_tag]

View File

@@ -212,14 +212,12 @@ datum/controller/vote
if(ticker.current_state >= 2)
return 0
choices.Add(config.votable_modes)
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
for (var/F in choices)
for (var/T in L)
var/datum/game_mode/M = new T(1)
if (M.config_tag == F)
gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works
additional_text.Add("<td align = 'center'>[M.required_players]</td>")
break
var/datum/game_mode/M = gamemode_cache[F]
if(!M)
continue
gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works
additional_text.Add("<td align = 'center'>[M.required_players]</td>")
gamemode_names["secret"] = "Secret"
if("crew_transfer")
if(check_rights(R_ADMIN|R_MOD, 0))

View File

@@ -14,7 +14,7 @@ var/datum/antagonist/xenos/borer/borers
borers = src
/datum/antagonist/xenos/borer/get_extra_panel_options(var/datum/mind/player)
return "<td><a href='?src=\ref[src];move_to_spawn=\ref[player.current]'>\[put in host\]</a></td>"
return "<a href='?src=\ref[src];move_to_spawn=\ref[player.current]'>\[put in host\]</a>"
/datum/antagonist/xenos/borer/create_objectives(var/datum/mind/player)
if(!..())

View File

@@ -31,7 +31,7 @@ var/datum/antagonist/xenos/xenomorphs
if(href_list["move_to_spawn"]) place_mob(href_list["move_to_spawn"])
/datum/antagonist/xenos/get_extra_panel_options(var/datum/mind/player)
return "<td><a href='?src=\ref[src];move_to_spawn=\ref[player.current]'>\[move to vent\]</a></td>"
return "<a href='?src=\ref[src];move_to_spawn=\ref[player.current]'>\[move to vent\]</a>"
/datum/antagonist/xenos/random_spawn()
if(config.aliens_allowed) ..()

View File

@@ -51,7 +51,6 @@ var/global/list/antag_names_to_ids = list()
var/loss_text
var/victory_feedback_tag
var/loss_feedback_tag
var/spawn_upper = 5
var/spawn_lower = 3
var/max_antags = 3
@@ -71,7 +70,7 @@ var/global/list/antag_names_to_ids = list()
var/bantype = "Syndicate"
var/suspicion_chance = 50
var/flags = 0
var/cur_max = 0
var/datum/mind/leader
@@ -82,6 +81,7 @@ var/global/list/antag_names_to_ids = list()
var/list/global_objectives = list()
var/list/restricted_jobs = list()
var/list/protected_jobs = list()
var/list/candidates = list()
/datum/antagonist/New()
..()
@@ -89,7 +89,7 @@ var/global/list/antag_names_to_ids = list()
if(config.protect_roles_from_antagonist)
restricted_jobs |= protected_jobs
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player)
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player, var/move_to_spawn)
var/main_type
if(ticker && ticker.mode)
@@ -106,6 +106,11 @@ var/global/list/antag_names_to_ids = list()
return 0
player.current << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
add_antagonist(player)
equip(player.current)
finalize(player)
if(move_to_spawn)
place_mob(player.current)
return
/datum/antagonist/proc/tick()
@@ -122,18 +127,17 @@ var/global/list/antag_names_to_ids = list()
/datum/antagonist/proc/get_panel_entry(var/datum/mind/player)
var/dat = "<tr>"
dat += "<td><b>[role_text]:</b></td>"
if(is_antagonist(player))
dat += "<td><a href='?src=\ref[player];remove_antagonist=[id]'>\[-\]</a></td>"
dat += "<td><a href='?src=\ref[player];equip_antagonist=[id]'>\[equip\]</a></td>"
if(starting_locations && starting_locations.len)
dat += "<td><a href='?src=\ref[player];move_antag_to_spawn=[id]'>\[move to spawn\]</a></td>"
else
dat += "<td><a href='?src=\ref[player];add_antagonist=[id]'>\[+\]</a></td>"
var/dat = "<tr><td><b>[role_text]:</b>"
var/extra = get_extra_panel_options(player)
if(extra) dat += "[extra]"
dat += "</tr>"
if(is_antagonist(player))
dat += "<a href='?src=\ref[player];remove_antagonist=[id]'>\[-\]</a>"
dat += "<a href='?src=\ref[player];equip_antagonist=[id]'>\[equip\]</a>"
if(starting_locations && starting_locations.len)
dat += "<a href='?src=\ref[player];move_antag_to_spawn=[id]'>\[move to spawn\]</a>"
if(extra) dat += "[extra]"
else
dat += "<a href='?src=\ref[player];add_antagonist=[id]'>\[+\]</a>"
dat += "</td></tr>"
return dat
@@ -152,25 +156,23 @@ var/global/list/antag_names_to_ids = list()
/datum/antagonist/proc/get_antag_count()
return current_antagonists ? current_antagonists.len : 0
/datum/antagonist/proc/attempt_spawn(var/lower_count, var/upper_count, var/ghosts_only)
world << "Attempting to spawn [id]."
/datum/antagonist/proc/get_candidates(var/lower_count, var/upper_count, var/ghosts_only)
candidates = list()
var/main_type
if(ticker && ticker.mode)
if(ticker.mode.antag_tag && ticker.mode.antag_tag == id)
main_type = 1
else
world << "Ticker uninitialized, failed."
return 0
return list()
var/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)
if(get_antag_count() >= cur_max)
world << "Antag count: [get_antag_count()] greater than [cur_max], failed."
return 0
return list()
// Sanity.
if(lower_count)
@@ -189,67 +191,44 @@ var/global/list/antag_names_to_ids = list()
if(upper_count < lower_count)
upper_count = lower_count
// Get the raw list of potential players.
var/req_num = 0
var/list/candidates = ticker.mode.get_players_for_role(role_type, id)
if(!candidates) candidates = list()
world << "Candidate count is [candidates.len]."
candidates = list() // Clear.
candidates = ticker.mode.get_players_for_role(role_type, id)
// Prune restricted jobs and status.
for(var/datum/mind/player in candidates)
if((ghosts_only && !istype(player.current, /mob/dead)) || (player.assigned_role in restricted_jobs))
world << "Removing [player.name]."
candidates -= player
world << "Candidate count is now [candidates.len]."
if((!candidates.len) || candidates.len < lower_count)
return list()
return candidates
/datum/antagonist/proc/attempt_spawn(var/lower_count, var/upper_count, var/ghosts_only)
world << "Attempting to spawn."
// Get the raw list of potential players.
candidates = get_candidates(lower_count, upper_count, ghosts_only)
// Update our boundaries.
if((!candidates.len) || candidates.len < lower_count)
world << "[candidates.len] not set or below [lower_count], failed."
if(!candidates.len)
world << "No candidates."
return 0
else if(candidates.len < upper_count)
req_num = candidates.len
else
req_num = upper_count
//Grab candidates randomly until we have enough.
while(req_num > 0)
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"
candidates -= player
req_num--
// This will be used in equip() and greet(). Random due to random order of candidates being grabbed.
if(flags & ANTAG_HAS_LEADER)
leader = current_antagonists[1]
// Generate first stage antagonists.
for(var/datum/mind/player in current_antagonists)
apply(player)
equip(player.current)
finalize(player)
spawn(1)
if(spawn_announcement)
if(spawn_announcement_delay)
sleep(spawn_announcement_delay)
if(spawn_announcement_sound)
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound)
else
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]")
world << "Success."
world << "Done."
return 1
/datum/antagonist/proc/apply(var/datum/mind/player)
// Update job and role.
player.special_role = role_text
if(flags & ANTAG_OVERRIDE_JOB)
player.assigned_role = "MODE"
// Get the mob.
if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path))))
var/mob/holder = player.current
@@ -334,13 +313,20 @@ var/global/list/antag_names_to_ids = list()
// This will fail if objectives have already been generated.
create_global_objectives()
if(flags & ANTAG_HAS_LEADER)
leader = current_antagonists[1]
if(target)
apply(target)
equip(target.current)
create_objectives(target)
update_icons_added(target)
greet(target)
return
for(var/datum/mind/player in current_antagonists)
apply(player)
equip(player.current)
create_objectives(player)
update_icons_added(player)
greet(player)
@@ -348,17 +334,29 @@ var/global/list/antag_names_to_ids = list()
if(flags & ANTAG_HAS_NUKE)
make_nuke(leader)
place_all_mobs()
spawn(1)
if(spawn_announcement)
if(spawn_announcement_delay)
sleep(spawn_announcement_delay)
if(spawn_announcement_sound)
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound)
else
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]")
/datum/antagonist/proc/print_player_summary()
if(!current_antagonists.len)
return 0
var/text = "<BR/><FONT size = 2><B>The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:</B></FONT>"
var/text = "<br><font size = 2><b>The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:</b></font>"
for(var/datum/mind/P in current_antagonists)
text += print_player_full(P)
text += get_special_objective_text(P)
var/failed
if(!global_objectives && P.objectives)
if(!global_objectives && P.objectives && P.objectives.len)
var/num = 1
for(var/datum/objective/O in P.objectives)
text += print_objective(O, num)
@@ -376,7 +374,7 @@ var/global/list/antag_names_to_ids = list()
else
text += "<br><font color='green'><B>The [role_text] was successful!</B></font>"
if(global_objectives)
if(global_objectives && global_objectives.len)
text += "<BR/><FONT size = 2>Their objectives were:<FONT>"
var/num = 1
for(var/datum/objective/O in global_objectives)

View File

@@ -33,19 +33,18 @@ var/datum/antagonist/rogue_ai/malf
if(hack_time <=0)
capture_station()
/datum/antagonist/rogue_ai/attempt_spawn()
var/list/candidates = ticker.mode.get_players_for_role(role_type, id)
/datum/antagonist/rogue_ai/get_candidates()
candidates = ticker.mode.get_players_for_role(role_type, id)
for(var/datum/mind/player in candidates)
if(player.assigned_role != "AI")
candidates -= player
if(!candidates.len)
return 0
return list()
/datum/antagonist/rogue_ai/attempt_spawn()
var/datum/mind/player = pick(candidates)
current_antagonists |= player
apply(player)
return 1
/datum/antagonist/rogue_ai/equip(var/mob/living/silicon/ai/player)
@@ -126,9 +125,6 @@ var/datum/antagonist/rogue_ai/malf
set category = "Abilities"
set name = "System Override"
set desc = "Begin taking over the station."
if (!istype(ticker.mode,/datum/game_mode/malfunction))
usr << "You cannot begin a takeover in this round type!"
return
if (malf.revealed)
usr << "You've already begun your takeover."
return

View File

@@ -13,7 +13,7 @@ var/datum/antagonist/traitor/traitors
traitors = src
/datum/antagonist/traitor/get_extra_panel_options(var/datum/mind/player)
return "<td><a href='?src=\ref[player];common=crystals'>\[set crystals\]</a><a href='?src=\ref[src];spawn_uplink=\ref[player.current]'>\[spawn uplink\]</a></td>"
return "<a href='?src=\ref[player];common=crystals'>\[set crystals\]</a><a href='?src=\ref[src];spawn_uplink=\ref[player.current]'>\[spawn uplink\]</a>"
/datum/antagonist/traitor/Topic(href, href_list)
if (..())

View File

@@ -1,6 +1,5 @@
var/global/antag_add_failed // Used in antag type voting.
var/global/list/additional_antag_types = list()
///////////////////////////////////
//Keeps track of all living heads//
///////////////////////////////////
@@ -218,7 +217,7 @@ var/global/list/additional_antag_types = list()
world << "<B>The current game mode is [capitalize(name)]!</B>"
if(round_description) world << "[round_description]"
if(round_autoantag) world << "Antagonists will be added to the round automagically as needed."
if(antag_templates && antag_templates.len > 1 && master_mode != "secret")
if(antag_templates && antag_templates.len)
var/antag_summary = "<b>Possible antagonist types:</b> "
var/i = 1
for(var/datum/antagonist/antag in antag_templates)
@@ -230,11 +229,14 @@ var/global/list/additional_antag_types = list()
antag_summary += "[antag.role_text_plural]"
i++
antag_summary += "."
world << "[antag_summary]"
if(antag_templates.len > 1 && master_mode != "secret")
world << "[antag_summary]"
else
message_admins("[antag_summary]")
///can_start()
///Checks to see if the game can be setup and ran with the current number of players or whatnot.
/datum/game_mode/proc/can_start()
/datum/game_mode/proc/can_start(var/do_not_spawn)
var/playerC = 0
for(var/mob/new_player/player in player_list)
if((player.client)&&(player.ready))
@@ -247,25 +249,17 @@ var/global/list/additional_antag_types = list()
if(playerC < required_players)
return 0
// Ensure we can spawn at least the voted roundtype main antagonist type after scaling the max antag counts.
// If we can, -try- to spawn the other voted antagonist types. It doesn't really matter if we can't.
if(antag_templates && antag_templates.len)
var/datum/antagonist/main_antags = antag_templates[1]
if(main_antags.attempt_spawn(required_enemies))
for(var/datum/antagonist/antag in (antag_templates-main_antags))
antag.attempt_spawn()
return 1
if(!do_not_spawn)
if(antag_templates && antag_templates.len)
var/datum/antagonist/main_antags = antag_templates[1]
var/list/candidates = main_antags.get_candidates(required_enemies)
if(candidates.len > required_enemies)
return 1
else
return 1
return 0
///pre_setup()
///Attempts to select players for special roles the mode might have.
/datum/game_mode/proc/pre_setup()
if(antag_templates && antag_templates.len)
for(var/datum/antagonist/antag in antag_templates)
antag.place_all_mobs()
return 1
/datum/game_mode/proc/refresh_event_modifiers()
if(event_delay_mod_moderate || event_delay_mod_major)
event_manager.report_at_round_end = 1
@@ -292,7 +286,7 @@ var/global/list/additional_antag_types = list()
if(antag_templates && antag_templates.len)
for(var/datum/antagonist/antag in antag_templates)
antag.create_global_objectives()
antag.attempt_spawn(required_enemies)
antag.finalize()
if(emergency_shuttle && auto_recall_shuttle)
@@ -373,10 +367,12 @@ var/global/list/additional_antag_types = list()
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)
@@ -386,7 +382,7 @@ var/global/list/additional_antag_types = list()
return
if(spawn_antag.can_become_antag(candidate))
spawn_antag.attempt_late_spawn(candidate)
spawn_antag.attempt_late_spawn(candidate, from_ghosts)
/datum/game_mode/proc/latespawn(mob/living/carbon/human/character)

View File

@@ -76,6 +76,7 @@ var/global/datum/controller/gameticker/ticker
if(master_mode=="secret")
src.hide_mode = 1
var/list/datum/game_mode/runnable_modes
var/mode_started
if((master_mode=="random") || (master_mode=="secret"))
runnable_modes = config.get_runnable_modes()
if (runnable_modes.len==0)
@@ -85,6 +86,7 @@ var/global/datum/controller/gameticker/ticker
if(secret_force_mode != "secret")
var/datum/game_mode/M = config.pick_mode(secret_force_mode)
if(M.can_start())
mode_started = 1
src.mode = config.pick_mode(secret_force_mode)
job_master.ResetOccupations()
if(!src.mode)
@@ -94,7 +96,7 @@ var/global/datum/controller/gameticker/ticker
src.mode = new mtype
else
src.mode = config.pick_mode(master_mode)
if (!src.mode.can_start())
if(!mode_started && !src.mode.can_start())
world << "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby."
del(mode)
current_state = GAME_STATE_PREGAME
@@ -103,13 +105,6 @@ var/global/datum/controller/gameticker/ticker
//Configure mode and assign player to special mode stuff
job_master.DivideOccupations() //Distribute jobs
var/can_continue = src.mode.pre_setup()//Setup special modes
if(!can_continue)
del(mode)
current_state = GAME_STATE_PREGAME
world << "<B>Error setting up [master_mode].</B> Reverting to pre-game lobby."
job_master.ResetOccupations()
return 0
if(hide_mode)
var/list/modes = new