mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-08-31 01:46:14 +01:00
217 lines
8.4 KiB
Plaintext
217 lines
8.4 KiB
Plaintext
/datum/game_mode
|
|
var/name = "invalid" // Don't implement ticker.mode.name or .config_tag checks again, okay? I've had to swap them all to get game mode children to work.
|
|
var/config_tag = null // Use istype(ticker.mode, /datum/game_mode/whatever) instead.
|
|
var/votable = 1
|
|
var/probability = 0 // Overridden by the server config. If you don't have access to that repo, keep it 0.
|
|
var/crew_shortage_enabled = 1
|
|
var/shuttle_available = 1 // 0: Won't dock. | 1: Normal. | 2: Won't dock if called too early.
|
|
var/shuttle_available_threshold = 12000 // 20 min. Only works when shuttle_available == 2.
|
|
|
|
var/latejoin_antag_compatible = 0 // Ultimately depends on the global 'late_traitors' setting, though.
|
|
var/latejoin_only_if_all_antags_dead = 0 // Don't spawn 'em until all antagonists are dead.
|
|
var/list/latejoin_antag_roles = list() // Unrecognized roles default to traitor in mob/new_player/proc/makebad().
|
|
|
|
var/list/datum/mind/traitors = list() // enemies assigned at round start
|
|
var/list/datum/mind/token_players = list() //players redeeming an antag token
|
|
var/list/datum/mind/Agimmicks = list() // admin assigned and certain gimmick enemies
|
|
var/list/datum/mind/former_antagonists = list() // For mindslaves and rogue cyborgs we'd want to show in the game over stats (Convair880).
|
|
|
|
/datum/game_mode/proc/announce()
|
|
boutput(world, "<B>[src] did not define announce()</B>")
|
|
|
|
/datum/game_mode/proc/pre_setup()
|
|
return 1
|
|
|
|
/datum/game_mode/proc/post_setup()
|
|
|
|
// yes. fucking manufacturers
|
|
// Fuck.
|
|
// F U C K
|
|
/datum/game_mode/proc/post_post_setup()
|
|
|
|
/datum/game_mode/proc/process()
|
|
|
|
/datum/game_mode/proc/check_finished()
|
|
if(emergency_shuttle.location==2)
|
|
return 1
|
|
return 0
|
|
|
|
// Did some streamlining here (Convair880).
|
|
/datum/game_mode/proc/declare_completion()
|
|
var/list/datum/mind/antags = list()
|
|
|
|
for (var/datum/mind/traitor in traitors)
|
|
antags.Add(traitor)
|
|
for (var/datum/mind/various in Agimmicks)
|
|
antags.Add(various)
|
|
|
|
for (var/datum/mind/traitor in antags)
|
|
var/traitorwin = 1
|
|
var/traitor_name
|
|
|
|
if (traitor.current)
|
|
traitor_name = "[traitor.current.real_name] (played by [traitor.key])"
|
|
else
|
|
traitor_name = "[traitor.key] (character destroyed)"
|
|
|
|
if (traitor.special_role == "mindslave")
|
|
boutput(world, "<B>[traitor_name] was a mindslave!</B>")
|
|
continue // Objectives are irrelevant for mindslaves and thralls.
|
|
else if (traitor.special_role == "vampthrall")
|
|
boutput(world, "<B>[traitor_name] was a vampire's thrall!</B>")
|
|
continue // Ditto.
|
|
else
|
|
if (traitor.late_special_role)
|
|
boutput(world, "<B>[traitor_name] was a late-joining [traitor.special_role]!</B>")
|
|
else if (traitor.random_event_special_role)
|
|
boutput(world, "<B>[traitor_name] was a random event [traitor.special_role]!</B>")
|
|
else
|
|
boutput(world, "<B>[traitor_name] was a [traitor.special_role]!</B>")
|
|
|
|
if (traitor.special_role == "changeling" && traitor.current)
|
|
var/dna_absorbed = 0
|
|
var/datum/abilityHolder/changeling/C = traitor.current.get_ability_holder(/datum/abilityHolder/changeling)
|
|
if (C && istype(C))
|
|
dna_absorbed = max(0, C.absorbtions)
|
|
else
|
|
dna_absorbed = "N/A (body destroyed)"
|
|
boutput(world, "<B>Absorbed DNA:</b> [dna_absorbed]")
|
|
|
|
if (traitor.special_role == "vampire" && traitor.current)
|
|
var/blood_acquired = 0
|
|
if (isvampire(traitor.current))
|
|
blood_acquired = traitor.current.get_vampire_blood(1)
|
|
else
|
|
blood_acquired = "N/A (body destroyed)"
|
|
boutput(world, "<B>Blood acquired:</b> [blood_acquired][isnum(blood_acquired) ? " units" : ""]")
|
|
|
|
if (traitor.special_role == "werewolf")
|
|
// Werewolves may not have the feed objective, so we don't want to make this output universal.
|
|
for (var/datum/objective/specialist/werewolf/feed/O in traitor.objectives)
|
|
if (O && istype(O, /datum/objective/specialist/werewolf/feed/))
|
|
boutput(world, "<B>No. of victims:</b> [O.mobs_fed_on.len]")
|
|
|
|
if (traitor.special_role == "predator")
|
|
// Same reasoning here, really.
|
|
for (var/datum/objective/specialist/predator/trophy/T in traitor.objectives)
|
|
if (traitor.current && T && istype(T, /datum/objective/specialist/predator/trophy))
|
|
var/S = traitor.current.get_skull_value()
|
|
boutput(world, "<B>Combined trophy value:</b> [S]")
|
|
|
|
if (traitor.special_role == "traitor")
|
|
var/purchases = traitor.purchased_traitor_items.len
|
|
var/surplus = traitor.traitor_crate_items.len
|
|
boutput(world, "<b>They purchased [purchases <= 0 ? "nothing" : "[purchases] item[s_es(purchases)]"] with their telecrystals![purchases <= 0 ? " [pick("Wow", "Dang", "Gosh", "Good work", "Good job")]!" : null]</b>")
|
|
if (purchases)
|
|
var/item_detail = "They purchased: "
|
|
for (var/i in traitor.purchased_traitor_items)
|
|
item_detail += "[bicon(i:item)] [i:name], "
|
|
item_detail = copytext(item_detail, 1, -2)
|
|
if (surplus)
|
|
item_detail += "<br>Their surplus crate contained: "
|
|
for (var/i in traitor.traitor_crate_items)
|
|
item_detail += "[bicon(i:item)] [i:name], "
|
|
item_detail = copytext(item_detail, 1, -2)
|
|
boutput(world, item_detail)
|
|
|
|
var/count = 1
|
|
for (var/datum/objective/objective in traitor.objectives)
|
|
#ifdef CREW_OBJECTIVES
|
|
if (istype(objective, /datum/objective/crew)) continue
|
|
#endif
|
|
if (istype(objective, /datum/objective/miscreant)) continue
|
|
|
|
if (objective.check_completion())
|
|
boutput(world, "<B>Objective #[count]</B>: [objective.explanation_text] <span style=\"color:green\"><B>Success</B></span>")
|
|
if (!isnull(objective.medal_name) && !isnull(traitor.current))
|
|
traitor.current.unlock_medal(objective.medal_name, objective.medal_announce)
|
|
else
|
|
boutput(world, "<B>Objective #[count]</B>: [objective.explanation_text] <span style=\"color:red\">Failed</span>")
|
|
traitorwin = 0
|
|
count++
|
|
|
|
// Please use objective.medal_name for medals that are tied to a specific objective instead of adding them here.
|
|
if (traitorwin)
|
|
if (traitor.current)
|
|
traitor.current.unlock_medal("MISSION COMPLETE", 1)
|
|
if (traitor.special_role == "wizard" && traitor.current)
|
|
traitor.current.unlock_medal("You're no Elminster!", 1)
|
|
if (traitor.special_role == "wrestler" && traitor.current)
|
|
traitor.current.unlock_medal("Cream of the Crop", 1)
|
|
boutput(world, "<B>The [traitor.special_role] was successful!<B>")
|
|
else
|
|
boutput(world, "<B>The [traitor.special_role] has failed!<B>")
|
|
|
|
#ifdef DATALOGGER
|
|
if (traitorwin)
|
|
game_stats.Increment("traitorwin")
|
|
score_traitorswon += 1
|
|
else
|
|
game_stats.Increment("traitorloss")
|
|
#endif
|
|
|
|
// Their antag status is revoked on death/implant removal/expiration, but we still want them to show up in the game over stats (Convair880).
|
|
for (var/datum/mind/traitor in former_antagonists)
|
|
var/traitor_name
|
|
|
|
if (traitor.current)
|
|
traitor_name = "[traitor.current.real_name] (played by [traitor.key])"
|
|
else
|
|
traitor_name = "[traitor.key] (character destroyed)"
|
|
|
|
if (traitor.former_antagonist_roles.len)
|
|
for (var/string in traitor.former_antagonist_roles)
|
|
if (string == "mindslave")
|
|
boutput(world, "<B>[traitor_name] was a mindslave!</B>")
|
|
else if (string == "vampthrall")
|
|
boutput(world, "<B>[traitor_name] was a vampire's thrall!</B>")
|
|
else
|
|
boutput(world, "<B>[traitor_name] was a [string]!</B>")
|
|
|
|
return 1
|
|
|
|
/datum/game_mode/proc/check_win()
|
|
|
|
/datum/game_mode/proc/send_intercept()
|
|
|
|
////////////////////////////
|
|
// Objective related code //
|
|
////////////////////////////
|
|
|
|
/datum/game_mode/proc/bestow_objective(var/datum/mind/traitor,var/objective_path)
|
|
if (!istype(traitor) || !ispath(objective_path))
|
|
return null
|
|
|
|
var/datum/objective/O = new objective_path
|
|
O.owner = traitor
|
|
O.set_up()
|
|
traitor.objectives += O
|
|
|
|
return O
|
|
|
|
/datum/game_mode/proc/bestow_random_escape_objective(var/datum/mind/traitor,var/allow_hijack = 0)
|
|
if (!istype(traitor) || !isnum(allow_hijack))
|
|
return null
|
|
|
|
var/upperbound = 3
|
|
if (allow_hijack)
|
|
upperbound = 4
|
|
|
|
var/objective_path = null
|
|
var/picker = rand(1,upperbound)
|
|
switch(picker)
|
|
if(1)
|
|
objective_path = /datum/objective/escape
|
|
if(2)
|
|
objective_path = /datum/objective/escape/survive
|
|
if(3)
|
|
objective_path = /datum/objective/escape/kamikaze
|
|
if(4)
|
|
objective_path = /datum/objective/escape/hijack
|
|
|
|
var/datum/objective/O = new objective_path
|
|
O.owner = traitor
|
|
O.set_up()
|
|
traitor.objectives += O
|
|
|
|
return O |