mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Traitorbro gamemode (#30344)
A dead-simple traitor variant. It's like traitor, except instead of an uplink you get a buddy: your blood brother. You must team up with your brother to complete your objectives. It runs along side regular traitor mode, thus the name "traitorbro".
This commit is contained in:
@@ -18,3 +18,4 @@
|
|||||||
#define ANTAG_DATUM_IAA_HUMAN_CUSTOM /datum/antagonist/traitor/human/internal_affairs/custom
|
#define ANTAG_DATUM_IAA_HUMAN_CUSTOM /datum/antagonist/traitor/human/internal_affairs/custom
|
||||||
#define ANTAG_DATUM_IAA_AI_CUSTOM /datum/antagonist/traitor/AI/internal_affairs/custom
|
#define ANTAG_DATUM_IAA_AI_CUSTOM /datum/antagonist/traitor/AI/internal_affairs/custom
|
||||||
#define ANTAG_DATUM_IAA_AI /datum/antagonist/traitor/AI/internal_affairs
|
#define ANTAG_DATUM_IAA_AI /datum/antagonist/traitor/AI/internal_affairs
|
||||||
|
#define ANTAG_DATUM_BROTHER /datum/antagonist/brother
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#define ANTAG_HUD_SINTOUCHED 16
|
#define ANTAG_HUD_SINTOUCHED 16
|
||||||
#define ANTAG_HUD_SOULLESS 17
|
#define ANTAG_HUD_SOULLESS 17
|
||||||
#define ANTAG_HUD_CLOCKWORK 18
|
#define ANTAG_HUD_CLOCKWORK 18
|
||||||
|
#define ANTAG_HUD_BROTHER 19
|
||||||
|
|
||||||
// Notification action types
|
// Notification action types
|
||||||
#define NOTIFY_JUMP "jump"
|
#define NOTIFY_JUMP "jump"
|
||||||
|
|||||||
@@ -22,12 +22,14 @@
|
|||||||
#define ROLE_REVENANT "revenant"
|
#define ROLE_REVENANT "revenant"
|
||||||
#define ROLE_DEVIL "devil"
|
#define ROLE_DEVIL "devil"
|
||||||
#define ROLE_SERVANT_OF_RATVAR "servant of Ratvar"
|
#define ROLE_SERVANT_OF_RATVAR "servant of Ratvar"
|
||||||
|
#define ROLE_BROTHER "blood brother"
|
||||||
|
|
||||||
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
|
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
|
||||||
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
|
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
|
||||||
//(in game days played) to play that role
|
//(in game days played) to play that role
|
||||||
GLOBAL_LIST_INIT(special_roles, list(
|
GLOBAL_LIST_INIT(special_roles, list(
|
||||||
ROLE_TRAITOR = /datum/game_mode/traitor,
|
ROLE_TRAITOR = /datum/game_mode/traitor,
|
||||||
|
ROLE_BROTHER = /datum/game_mode/traitor/bros,
|
||||||
ROLE_OPERATIVE = /datum/game_mode/nuclear,
|
ROLE_OPERATIVE = /datum/game_mode/nuclear,
|
||||||
ROLE_CHANGELING = /datum/game_mode/changeling,
|
ROLE_CHANGELING = /datum/game_mode/changeling,
|
||||||
ROLE_WIZARD = /datum/game_mode/wizard,
|
ROLE_WIZARD = /datum/game_mode/wizard,
|
||||||
|
|||||||
@@ -147,11 +147,13 @@ GLOBAL_PROTECT(config_dir)
|
|||||||
var/irc_first_connection_alert = 0 // do we notify the irc channel when somebody is connecting for the first time?
|
var/irc_first_connection_alert = 0 // do we notify the irc channel when somebody is connecting for the first time?
|
||||||
|
|
||||||
var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors
|
var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors
|
||||||
|
var/brother_scaling_coeff = 25 //how many players per brother team
|
||||||
var/changeling_scaling_coeff = 6 //how much does the amount of players get divided by to determine changelings
|
var/changeling_scaling_coeff = 6 //how much does the amount of players get divided by to determine changelings
|
||||||
var/security_scaling_coeff = 8 //how much does the amount of players get divided by to determine open security officer positions
|
var/security_scaling_coeff = 8 //how much does the amount of players get divided by to determine open security officer positions
|
||||||
var/abductor_scaling_coeff = 15 //how many players per abductor team
|
var/abductor_scaling_coeff = 15 //how many players per abductor team
|
||||||
|
|
||||||
var/traitor_objectives_amount = 2
|
var/traitor_objectives_amount = 2
|
||||||
|
var/brother_objectives_amount = 2
|
||||||
var/protect_roles_from_antagonist = 0 //If security and such can be traitor/cult/other
|
var/protect_roles_from_antagonist = 0 //If security and such can be traitor/cult/other
|
||||||
var/protect_assistant_from_antagonist = 0 //If assistants can be traitor/cult/other
|
var/protect_assistant_from_antagonist = 0 //If assistants can be traitor/cult/other
|
||||||
var/enforce_human_authority = 0 //If non-human species are barred from joining as a head of staff
|
var/enforce_human_authority = 0 //If non-human species are barred from joining as a head of staff
|
||||||
@@ -692,6 +694,8 @@ GLOBAL_PROTECT(config_dir)
|
|||||||
ghost_interaction = 1
|
ghost_interaction = 1
|
||||||
if("traitor_scaling_coeff")
|
if("traitor_scaling_coeff")
|
||||||
traitor_scaling_coeff = text2num(value)
|
traitor_scaling_coeff = text2num(value)
|
||||||
|
if("brother_scaling_coeff")
|
||||||
|
brother_scaling_coeff = text2num(value)
|
||||||
if("changeling_scaling_coeff")
|
if("changeling_scaling_coeff")
|
||||||
changeling_scaling_coeff = text2num(value)
|
changeling_scaling_coeff = text2num(value)
|
||||||
if("security_scaling_coeff")
|
if("security_scaling_coeff")
|
||||||
@@ -700,6 +704,8 @@ GLOBAL_PROTECT(config_dir)
|
|||||||
abductor_scaling_coeff = text2num(value)
|
abductor_scaling_coeff = text2num(value)
|
||||||
if("traitor_objectives_amount")
|
if("traitor_objectives_amount")
|
||||||
traitor_objectives_amount = text2num(value)
|
traitor_objectives_amount = text2num(value)
|
||||||
|
if("brother_objectives_amount")
|
||||||
|
brother_objectives_amount = text2num(value)
|
||||||
if("probability")
|
if("probability")
|
||||||
var/prob_pos = findtext(value, " ")
|
var/prob_pos = findtext(value, " ")
|
||||||
var/prob_name = null
|
var/prob_name = null
|
||||||
|
|||||||
48
code/datums/antagonists/datum_brother.dm
Normal file
48
code/datums/antagonists/datum_brother.dm
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/datum/antagonist/brother
|
||||||
|
name = "Brother"
|
||||||
|
var/special_role = "blood brother"
|
||||||
|
var/datum/objective_team/brother_team/team
|
||||||
|
|
||||||
|
/datum/antagonist/brother/New(datum/mind/new_owner, datum/objective_team/brother_team/T)
|
||||||
|
team = T
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/antagonist/brother/on_gain()
|
||||||
|
SSticker.mode.brothers += owner
|
||||||
|
owner.special_role = special_role
|
||||||
|
owner.objectives += team.objectives
|
||||||
|
finalize_brother()
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/antagonist/brother/on_removal()
|
||||||
|
SSticker.mode.brothers -= owner
|
||||||
|
team.members -= owner
|
||||||
|
owner.objectives -= team.objectives
|
||||||
|
if(owner.current)
|
||||||
|
to_chat(owner.current,"<span class='userdanger'>You are no longer the [special_role]!</span>")
|
||||||
|
owner.special_role = null
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/antagonist/brother/proc/give_meeting_area()
|
||||||
|
if(!owner.current || !team || !team.meeting_area)
|
||||||
|
return
|
||||||
|
to_chat(owner.current, "<B>Your designated meeting area:</B> [team.meeting_area]")
|
||||||
|
owner.store_memory("<b>Meeting Area</b>: [team.meeting_area]")
|
||||||
|
|
||||||
|
/datum/antagonist/brother/greet()
|
||||||
|
var/brother_text = ""
|
||||||
|
var/list/brothers = team.members - owner
|
||||||
|
for(var/i = 1 to brothers.len)
|
||||||
|
var/datum/mind/M = brothers[i]
|
||||||
|
brother_text += M.name
|
||||||
|
if(i == brothers.len - 1)
|
||||||
|
brother_text += " and "
|
||||||
|
else if(i != brothers.len)
|
||||||
|
brother_text += ", "
|
||||||
|
to_chat(owner.current, "<B><font size=3 color=red>You are the [owner.special_role] of [brother_text].</font></B>")
|
||||||
|
to_chat(owner.current, "The Syndicate only accepts those that have proven themself. Prove yourself and prove your [team.member_name]s by completing your objectives together!")
|
||||||
|
owner.announce_objectives()
|
||||||
|
give_meeting_area()
|
||||||
|
|
||||||
|
/datum/antagonist/brother/proc/finalize_brother()
|
||||||
|
SSticker.mode.update_brother_icons_added(owner)
|
||||||
@@ -20,6 +20,7 @@ GLOBAL_LIST_INIT(huds, list(
|
|||||||
ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(),
|
ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(),
|
||||||
ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(),
|
ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(),
|
||||||
ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(),
|
ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(),
|
||||||
|
ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(),
|
||||||
))
|
))
|
||||||
|
|
||||||
/datum/atom_hud
|
/datum/atom_hud
|
||||||
|
|||||||
@@ -127,10 +127,10 @@
|
|||||||
memory = null
|
memory = null
|
||||||
|
|
||||||
// Datum antag mind procs
|
// Datum antag mind procs
|
||||||
/datum/mind/proc/add_antag_datum(datum_type)
|
/datum/mind/proc/add_antag_datum(datum_type, team)
|
||||||
if(!datum_type)
|
if(!datum_type)
|
||||||
return
|
return
|
||||||
var/datum/antagonist/A = new datum_type(src)
|
var/datum/antagonist/A = new datum_type(src, team)
|
||||||
if(!A.can_be_owned(src))
|
if(!A.can_be_owned(src))
|
||||||
qdel(A)
|
qdel(A)
|
||||||
return
|
return
|
||||||
@@ -190,6 +190,11 @@
|
|||||||
src.remove_antag_datum(ANTAG_DATUM_TRAITOR)
|
src.remove_antag_datum(ANTAG_DATUM_TRAITOR)
|
||||||
SSticker.mode.update_traitor_icons_removed(src)
|
SSticker.mode.update_traitor_icons_removed(src)
|
||||||
|
|
||||||
|
/datum/mind/proc/remove_brother()
|
||||||
|
if(src in SSticker.mode.brothers)
|
||||||
|
src.remove_antag_datum(ANTAG_DATUM_BROTHER)
|
||||||
|
SSticker.mode.update_brother_icons_removed(src)
|
||||||
|
|
||||||
/datum/mind/proc/remove_nukeop()
|
/datum/mind/proc/remove_nukeop()
|
||||||
if(src in SSticker.mode.syndicates)
|
if(src in SSticker.mode.syndicates)
|
||||||
SSticker.mode.syndicates -= src
|
SSticker.mode.syndicates -= src
|
||||||
@@ -345,6 +350,12 @@
|
|||||||
var/obj_count = 1
|
var/obj_count = 1
|
||||||
for(var/datum/objective/objective in objectives)
|
for(var/datum/objective/objective in objectives)
|
||||||
output += "<br><B>Objective #[obj_count++]</B>: [objective.explanation_text]"
|
output += "<br><B>Objective #[obj_count++]</B>: [objective.explanation_text]"
|
||||||
|
var/list/datum/mind/other_owners = objective.get_owners() - src
|
||||||
|
if(other_owners.len)
|
||||||
|
output += "<ul>"
|
||||||
|
for(var/datum/mind/M in other_owners)
|
||||||
|
output += "<li>Conspirator: [M.name]</li>"
|
||||||
|
output += "</ul>"
|
||||||
|
|
||||||
if(window)
|
if(window)
|
||||||
recipient << browse(output,"window=memory")
|
recipient << browse(output,"window=memory")
|
||||||
@@ -381,7 +392,7 @@
|
|||||||
|
|
||||||
/** TRAITOR ***/
|
/** TRAITOR ***/
|
||||||
text = "traitor"
|
text = "traitor"
|
||||||
if (SSticker.mode.config_tag=="traitor" || SSticker.mode.config_tag=="traitorchan")
|
if (SSticker.mode.config_tag=="traitor" || SSticker.mode.config_tag=="traitorchan" || SSticker.mode.config_tag=="traitorbro")
|
||||||
text = uppertext(text)
|
text = uppertext(text)
|
||||||
text = "<i><b>[text]</b></i>: "
|
text = "<i><b>[text]</b></i>: "
|
||||||
if (src in SSticker.mode.traitors)
|
if (src in SSticker.mode.traitors)
|
||||||
@@ -401,6 +412,21 @@
|
|||||||
|
|
||||||
if(ishuman(current) || ismonkey(current))
|
if(ishuman(current) || ismonkey(current))
|
||||||
|
|
||||||
|
/** BROTHER **/
|
||||||
|
text = "brother"
|
||||||
|
if(SSticker.mode.config_tag == "traitorbro")
|
||||||
|
text = uppertext(text)
|
||||||
|
text = "<i><b>[text]</b></i>: "
|
||||||
|
if(src in SSticker.mode.brothers)
|
||||||
|
text += "<b>Brother</b> | <a href='?src=\ref[src];brother=clear'>no</a>"
|
||||||
|
|
||||||
|
if(current && current.client && (ROLE_BROTHER in current.client.prefs.be_special))
|
||||||
|
text += " | Enabled in Prefs"
|
||||||
|
else
|
||||||
|
text += " | Disabled in Prefs"
|
||||||
|
|
||||||
|
sections["brother"] = text
|
||||||
|
|
||||||
/** CHANGELING ***/
|
/** CHANGELING ***/
|
||||||
text = "changeling"
|
text = "changeling"
|
||||||
if (SSticker.mode.config_tag=="changeling" || SSticker.mode.config_tag=="traitorchan")
|
if (SSticker.mode.config_tag=="changeling" || SSticker.mode.config_tag=="traitorchan")
|
||||||
@@ -1275,6 +1301,13 @@
|
|||||||
if(H)
|
if(H)
|
||||||
src = H.mind
|
src = H.mind
|
||||||
|
|
||||||
|
else if (href_list["brother"])
|
||||||
|
switch(href_list["brother"])
|
||||||
|
if("clear")
|
||||||
|
remove_brother()
|
||||||
|
log_admin("[key_name(usr)] has de-brother'ed [current].")
|
||||||
|
SSticker.mode.update_brother_icons_removed(src)
|
||||||
|
|
||||||
else if (href_list["silicon"])
|
else if (href_list["silicon"])
|
||||||
switch(href_list["silicon"])
|
switch(href_list["silicon"])
|
||||||
if("unemag")
|
if("unemag")
|
||||||
|
|||||||
137
code/game/gamemodes/brother/traitor_bro.dm
Normal file
137
code/game/gamemodes/brother/traitor_bro.dm
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/datum/objective_team/brother_team
|
||||||
|
name = "brotherhood"
|
||||||
|
member_name = "blood brother"
|
||||||
|
var/list/objectives = list()
|
||||||
|
var/meeting_area
|
||||||
|
|
||||||
|
/datum/objective_team/brother_team/is_solo()
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/datum/objective_team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE)
|
||||||
|
O.team = src
|
||||||
|
if(needs_target)
|
||||||
|
O.find_target()
|
||||||
|
O.update_explanation_text()
|
||||||
|
objectives += O
|
||||||
|
|
||||||
|
/datum/objective_team/brother_team/proc/forge_brother_objectives()
|
||||||
|
objectives = list()
|
||||||
|
var/is_hijacker = prob(10)
|
||||||
|
for(var/i = 1 to max(1, config.brother_objectives_amount + (members.len > 2) - is_hijacker))
|
||||||
|
forge_single_objective()
|
||||||
|
if(is_hijacker)
|
||||||
|
if(!locate(/datum/objective/hijack) in objectives)
|
||||||
|
add_objective(new/datum/objective/hijack)
|
||||||
|
else if(!locate(/datum/objective/escape) in objectives)
|
||||||
|
add_objective(new/datum/objective/escape)
|
||||||
|
|
||||||
|
/datum/objective_team/brother_team/proc/forge_single_objective()
|
||||||
|
if(prob(50))
|
||||||
|
if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len))
|
||||||
|
add_objective(new/datum/objective/destroy, TRUE)
|
||||||
|
else if(prob(30))
|
||||||
|
add_objective(new/datum/objective/maroon, TRUE)
|
||||||
|
else
|
||||||
|
add_objective(new/datum/objective/assassinate, TRUE)
|
||||||
|
else
|
||||||
|
add_objective(new/datum/objective/steal, TRUE)
|
||||||
|
|
||||||
|
/datum/game_mode
|
||||||
|
var/list/datum/mind/brothers = list()
|
||||||
|
var/list/datum/objective_team/brother_team/brother_teams = list()
|
||||||
|
|
||||||
|
/datum/game_mode/traitor/bros
|
||||||
|
name = "traitor+brothers"
|
||||||
|
config_tag = "traitorbro"
|
||||||
|
restricted_jobs = list("AI", "Cyborg")
|
||||||
|
|
||||||
|
announce_span = "danger"
|
||||||
|
announce_text = "There are Syndicate agents and Blood Brothers on the station!\n\
|
||||||
|
<span class='danger'>Traitors</span>: Accomplish your objectives.\n\
|
||||||
|
<span class='danger'>Blood Brothers</span>: Accomplish your objectives.\n\
|
||||||
|
<span class='notice'>Crew</span>: Do not let the traitors or brothers succeed!"
|
||||||
|
|
||||||
|
var/list/datum/objective_team/brother_team/pre_brother_teams = list()
|
||||||
|
var/const/team_amount = 2 //hard limit on brother teams if scaling is turned off
|
||||||
|
var/const/min_team_size = 2
|
||||||
|
|
||||||
|
var/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library")
|
||||||
|
|
||||||
|
/datum/game_mode/traitor/bros/pre_setup()
|
||||||
|
if(config.protect_roles_from_antagonist)
|
||||||
|
restricted_jobs += protected_jobs
|
||||||
|
if(config.protect_assistant_from_antagonist)
|
||||||
|
restricted_jobs += "Assistant"
|
||||||
|
|
||||||
|
var/list/datum/mind/possible_brothers = get_players_for_role(ROLE_BROTHER)
|
||||||
|
|
||||||
|
var/num_teams = team_amount
|
||||||
|
if(config.brother_scaling_coeff)
|
||||||
|
num_teams = max(1, round(num_players()/config.brother_scaling_coeff))
|
||||||
|
|
||||||
|
for(var/j = 1 to num_teams)
|
||||||
|
if(possible_brothers.len < min_team_size || antag_candidates.len <= required_enemies)
|
||||||
|
break
|
||||||
|
var/datum/objective_team/brother_team/team = new
|
||||||
|
var/team_size = prob(10) ? min(3, possible_brothers.len) : 2
|
||||||
|
for(var/k = 1 to team_size)
|
||||||
|
var/datum/mind/bro = pick(possible_brothers)
|
||||||
|
possible_brothers -= bro
|
||||||
|
antag_candidates -= bro
|
||||||
|
team.members += bro
|
||||||
|
bro.restricted_roles = restricted_jobs
|
||||||
|
log_game("[key_name(bro)] has been selected as a Brother")
|
||||||
|
pre_brother_teams += team
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/game_mode/traitor/bros/post_setup()
|
||||||
|
for(var/datum/objective_team/brother_team/team in pre_brother_teams)
|
||||||
|
team.meeting_area = pick(meeting_areas)
|
||||||
|
meeting_areas -= team.meeting_area
|
||||||
|
team.forge_brother_objectives()
|
||||||
|
for(var/datum/mind/M in team.members)
|
||||||
|
M.add_antag_datum(ANTAG_DATUM_BROTHER, team)
|
||||||
|
modePlayer += M
|
||||||
|
brother_teams += pre_brother_teams
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/game_mode/proc/auto_declare_completion_brother()
|
||||||
|
if(!LAZYLEN(brother_teams))
|
||||||
|
return
|
||||||
|
var/text = "<br><font size=4><b>The blood brothers were:</b></font>"
|
||||||
|
var/teamnumber = 1
|
||||||
|
for(var/datum/objective_team/brother_team/team in brother_teams)
|
||||||
|
if(!team.members.len)
|
||||||
|
continue
|
||||||
|
text += "<br><font size=3><b>Team #[teamnumber++]</b></font>"
|
||||||
|
for(var/datum/mind/M in team.members)
|
||||||
|
text += printplayer(M)
|
||||||
|
var/win = TRUE
|
||||||
|
var/objective_count = 1
|
||||||
|
for(var/datum/objective/objective in team.objectives)
|
||||||
|
if(objective.check_completion())
|
||||||
|
text += "<br><B>Objective #[objective_count]</B>: [objective.explanation_text] <font color='green'><B>Success!</B></font>"
|
||||||
|
SSblackbox.add_details("traitor_objective","[objective.type]|SUCCESS")
|
||||||
|
else
|
||||||
|
text += "<br><B>Objective #[objective_count]</B>: [objective.explanation_text] <font color='red'>Fail.</font>"
|
||||||
|
SSblackbox.add_details("traitor_objective","[objective.type]|FAIL")
|
||||||
|
win = FALSE
|
||||||
|
objective_count++
|
||||||
|
if(win)
|
||||||
|
text += "<br><font color='green'><B>The blood brothers were successful!</B></font>"
|
||||||
|
SSblackbox.add_details("brother_success","SUCCESS")
|
||||||
|
else
|
||||||
|
text += "<br><font color='red'><B>The blood brothers have failed!</B></font>"
|
||||||
|
SSblackbox.add_details("brother_success","FAIL")
|
||||||
|
text += "<br>"
|
||||||
|
to_chat(world, text)
|
||||||
|
|
||||||
|
/datum/game_mode/proc/update_brother_icons_added(datum/mind/brother_mind)
|
||||||
|
var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER]
|
||||||
|
brotherhud.join_hud(brother_mind.current)
|
||||||
|
set_antag_hud(brother_mind.current, "brother")
|
||||||
|
|
||||||
|
/datum/game_mode/proc/update_brother_icons_removed(datum/mind/brother_mind)
|
||||||
|
var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER]
|
||||||
|
brotherhud.leave_hud(brother_mind.current)
|
||||||
|
set_antag_hud(brother_mind.current, null)
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
team_names[team_number] = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names
|
team_names[team_number] = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names
|
||||||
//Team Objective
|
//Team Objective
|
||||||
var/datum/objective/experiment/team_objective = new
|
var/datum/objective/experiment/team_objective = new
|
||||||
team_objective.team = team_number
|
team_objective.team_number = team_number
|
||||||
team_objectives[team_number] = team_objective
|
team_objectives[team_number] = team_objective
|
||||||
//Team Members
|
//Team Members
|
||||||
|
|
||||||
@@ -212,13 +212,13 @@
|
|||||||
// OBJECTIVES
|
// OBJECTIVES
|
||||||
/datum/objective/experiment
|
/datum/objective/experiment
|
||||||
target_amount = 6
|
target_amount = 6
|
||||||
var/team
|
var/team_number
|
||||||
|
|
||||||
/datum/objective/experiment/New()
|
/datum/objective/experiment/New()
|
||||||
explanation_text = "Experiment on [target_amount] humans."
|
explanation_text = "Experiment on [target_amount] humans."
|
||||||
|
|
||||||
/datum/objective/experiment/check_completion()
|
/datum/objective/experiment/check_completion()
|
||||||
var/ab_team = team
|
var/ab_team = team_number
|
||||||
if(owner)
|
if(owner)
|
||||||
if(!owner.current || !ishuman(owner.current))
|
if(!owner.current || !ishuman(owner.current))
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/datum/objective
|
/datum/objective
|
||||||
var/datum/mind/owner = null //Who owns the objective.
|
var/datum/mind/owner //The primary owner of the objective. !!SOMEWHAT DEPRECATED!! Prefer using 'team' for new code.
|
||||||
|
var/datum/objective_team/team //An alternative to 'owner': a team. Use this when writing new code.
|
||||||
var/explanation_text = "Nothing" //What that person is supposed to do.
|
var/explanation_text = "Nothing" //What that person is supposed to do.
|
||||||
|
var/team_explanation_text //For when there are multiple owners.
|
||||||
var/datum/mind/target = null //If they are focused on a particular person.
|
var/datum/mind/target = null //If they are focused on a particular person.
|
||||||
var/target_amount = 0 //If they are focused on a particular number. Steal objectives have their own counter.
|
var/target_amount = 0 //If they are focused on a particular number. Steal objectives have their own counter.
|
||||||
var/completed = 0 //currently only used for custom objectives.
|
var/completed = 0 //currently only used for custom objectives.
|
||||||
@@ -10,19 +12,48 @@
|
|||||||
if(text)
|
if(text)
|
||||||
explanation_text = text
|
explanation_text = text
|
||||||
|
|
||||||
|
/datum/objective/proc/get_owners() // Combine owner and team into a single list.
|
||||||
|
. = (team && team.members) ? team.members.Copy() : list()
|
||||||
|
if(owner)
|
||||||
|
. += owner
|
||||||
|
|
||||||
|
/datum/objective/proc/considered_alive(var/datum/mind/M)
|
||||||
|
if(M && M.current)
|
||||||
|
var/mob/living/carbon/human/H
|
||||||
|
if(ishuman(M.current))
|
||||||
|
H = M.current
|
||||||
|
return M.current.stat != DEAD && !issilicon(M.current) && !isbrain(M.current) && (!H || H.dna.species.id != "memezombies")
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/datum/objective/proc/considered_escaped(datum/mind/M)
|
||||||
|
if(!considered_alive(M))
|
||||||
|
return FALSE
|
||||||
|
if(SSticker.force_ending || SSticker.mode.station_was_nuked) // Just let them win.
|
||||||
|
return TRUE
|
||||||
|
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
||||||
|
return FALSE
|
||||||
|
var/turf/location = get_turf(M.current)
|
||||||
|
if(!location || istype(location, /turf/open/floor/plasteel/shuttle/red) || istype(location, /turf/open/floor/mineral/plastitanium/brig)) // Fails if they are in the shuttle brig
|
||||||
|
return FALSE
|
||||||
|
return location.onCentCom() || location.onSyndieBase()
|
||||||
|
|
||||||
|
/datum/objective/proc/considered_afk(datum/mind/M)
|
||||||
|
return !M || !M.current || !M.current.client || M.current.client.is_afk()
|
||||||
|
|
||||||
/datum/objective/proc/check_completion()
|
/datum/objective/proc/check_completion()
|
||||||
return completed
|
return completed
|
||||||
|
|
||||||
/datum/objective/proc/is_unique_objective(possible_target)
|
/datum/objective/proc/is_unique_objective(possible_target)
|
||||||
for(var/datum/objective/O in owner.objectives)
|
var/list/datum/mind/owners = get_owners()
|
||||||
if(istype(O, type) && O.get_target() == possible_target)
|
for(var/datum/mind/M in owners)
|
||||||
return 0
|
for(var/datum/objective/O in M.objectives)
|
||||||
return 1
|
if(istype(O, type) && O.get_target() == possible_target)
|
||||||
|
return FALSE
|
||||||
|
return TRUE
|
||||||
|
|
||||||
/datum/objective/proc/get_target()
|
/datum/objective/proc/get_target()
|
||||||
return target
|
return target
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/proc/get_crewmember_minds()
|
/datum/objective/proc/get_crewmember_minds()
|
||||||
. = list()
|
. = list()
|
||||||
for(var/V in GLOB.data_core.locked)
|
for(var/V in GLOB.data_core.locked)
|
||||||
@@ -32,9 +63,10 @@
|
|||||||
. += M
|
. += M
|
||||||
|
|
||||||
/datum/objective/proc/find_target()
|
/datum/objective/proc/find_target()
|
||||||
|
var/list/datum/mind/owners = get_owners()
|
||||||
var/list/possible_targets = list()
|
var/list/possible_targets = list()
|
||||||
for(var/datum/mind/possible_target in get_crewmember_minds())
|
for(var/datum/mind/possible_target in get_crewmember_minds())
|
||||||
if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && is_unique_objective(possible_target))
|
if(!(possible_target in owners) && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && is_unique_objective(possible_target))
|
||||||
possible_targets += possible_target
|
possible_targets += possible_target
|
||||||
if(possible_targets.len > 0)
|
if(possible_targets.len > 0)
|
||||||
target = pick(possible_targets)
|
target = pick(possible_targets)
|
||||||
@@ -42,8 +74,9 @@
|
|||||||
return target
|
return target
|
||||||
|
|
||||||
/datum/objective/proc/find_target_by_role(role, role_type=0, invert=0)//Option sets either to check assigned role or special role. Default to assigned., invert inverts the check, eg: "Don't choose a Ling"
|
/datum/objective/proc/find_target_by_role(role, role_type=0, invert=0)//Option sets either to check assigned role or special role. Default to assigned., invert inverts the check, eg: "Don't choose a Ling"
|
||||||
|
var/list/datum/mind/owners = get_owners()
|
||||||
for(var/datum/mind/possible_target in get_crewmember_minds())
|
for(var/datum/mind/possible_target in get_crewmember_minds())
|
||||||
if((possible_target != owner) && ishuman(possible_target.current))
|
if(!(possible_target in owners) && ishuman(possible_target.current))
|
||||||
var/is_role = 0
|
var/is_role = 0
|
||||||
if(role_type)
|
if(role_type)
|
||||||
if(possible_target.special_role == role)
|
if(possible_target.special_role == role)
|
||||||
@@ -64,13 +97,15 @@
|
|||||||
update_explanation_text()
|
update_explanation_text()
|
||||||
|
|
||||||
/datum/objective/proc/update_explanation_text()
|
/datum/objective/proc/update_explanation_text()
|
||||||
//Default does nothing, override where needed
|
if(team_explanation_text && LAZYLEN(get_owners()) > 1)
|
||||||
|
explanation_text = team_explanation_text
|
||||||
|
|
||||||
/datum/objective/proc/give_special_equipment(special_equipment)
|
/datum/objective/proc/give_special_equipment(special_equipment)
|
||||||
if(owner && owner.current)
|
var/datum/mind/receiver = pick(get_owners())
|
||||||
if(ishuman(owner.current))
|
if(receiver && receiver.current)
|
||||||
var/mob/living/carbon/human/H = owner.current
|
if(ishuman(receiver.current))
|
||||||
var/list/slots = list ("backpack" = slot_in_backpack)
|
var/mob/living/carbon/human/H = receiver.current
|
||||||
|
var/list/slots = list("backpack" = slot_in_backpack)
|
||||||
for(var/eq_path in special_equipment)
|
for(var/eq_path in special_equipment)
|
||||||
var/obj/O = new eq_path
|
var/obj/O = new eq_path
|
||||||
H.equip_in_one_of_slots(O, slots)
|
H.equip_in_one_of_slots(O, slots)
|
||||||
@@ -86,14 +121,7 @@
|
|||||||
return target
|
return target
|
||||||
|
|
||||||
/datum/objective/assassinate/check_completion()
|
/datum/objective/assassinate/check_completion()
|
||||||
if(target && target.current)
|
return !target || !considered_alive(target)
|
||||||
var/mob/living/carbon/human/H
|
|
||||||
if(ishuman(target.current))
|
|
||||||
H = target.current
|
|
||||||
if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey || (H && H.dna.species.id == "memezombies")) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/datum/objective/assassinate/update_explanation_text()
|
/datum/objective/assassinate/update_explanation_text()
|
||||||
..()
|
..()
|
||||||
@@ -110,7 +138,6 @@
|
|||||||
if(target && !target.current)
|
if(target && !target.current)
|
||||||
explanation_text = "Assassinate [target.name], who was obliterated"
|
explanation_text = "Assassinate [target.name], who was obliterated"
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/mutiny
|
/datum/objective/mutiny
|
||||||
var/target_role_type=0
|
var/target_role_type=0
|
||||||
martyr_compatible = 1
|
martyr_compatible = 1
|
||||||
@@ -122,14 +149,10 @@
|
|||||||
return target
|
return target
|
||||||
|
|
||||||
/datum/objective/mutiny/check_completion()
|
/datum/objective/mutiny/check_completion()
|
||||||
if(target && target.current)
|
if(!target || !considered_alive(target) || considered_afk(target))
|
||||||
if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey)
|
return TRUE
|
||||||
return 1
|
var/turf/T = get_turf(target.current)
|
||||||
var/turf/T = get_turf(target.current)
|
return T && !(T.z in GLOB.station_z_levels)
|
||||||
if(T && (!(T.z in GLOB.station_z_levels)) || (target.current.client && target.current.client.is_afk())) //If they leave the station or go afk they count as dead for this
|
|
||||||
return 2
|
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/datum/objective/mutiny/update_explanation_text()
|
/datum/objective/mutiny/update_explanation_text()
|
||||||
..()
|
..()
|
||||||
@@ -138,8 +161,6 @@
|
|||||||
else
|
else
|
||||||
explanation_text = "Free Objective"
|
explanation_text = "Free Objective"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/maroon
|
/datum/objective/maroon
|
||||||
var/target_role_type=0
|
var/target_role_type=0
|
||||||
martyr_compatible = 1
|
martyr_compatible = 1
|
||||||
@@ -151,15 +172,7 @@
|
|||||||
return target
|
return target
|
||||||
|
|
||||||
/datum/objective/maroon/check_completion()
|
/datum/objective/maroon/check_completion()
|
||||||
if(target && target.current)
|
return !target || !considered_alive(target) || (!target.current.onCentCom() && !target.current.onSyndieBase())
|
||||||
var/mob/living/carbon/human/H
|
|
||||||
if(ishuman(target.current))
|
|
||||||
H = target.current
|
|
||||||
if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey || (H && H.dna.species.id == "memezombies")) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
|
|
||||||
return 1
|
|
||||||
if(target.current.onCentCom() || target.current.onSyndieBase())
|
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/datum/objective/maroon/update_explanation_text()
|
/datum/objective/maroon/update_explanation_text()
|
||||||
if(target && target.current)
|
if(target && target.current)
|
||||||
@@ -167,9 +180,7 @@
|
|||||||
else
|
else
|
||||||
explanation_text = "Free Objective"
|
explanation_text = "Free Objective"
|
||||||
|
|
||||||
|
/datum/objective/debrain
|
||||||
|
|
||||||
/datum/objective/debrain//I want braaaainssss
|
|
||||||
var/target_role_type=0
|
var/target_role_type=0
|
||||||
|
|
||||||
/datum/objective/debrain/find_target_by_role(role, role_type=0, invert=0)
|
/datum/objective/debrain/find_target_by_role(role, role_type=0, invert=0)
|
||||||
@@ -180,17 +191,20 @@
|
|||||||
|
|
||||||
/datum/objective/debrain/check_completion()
|
/datum/objective/debrain/check_completion()
|
||||||
if(!target)//If it's a free objective.
|
if(!target)//If it's a free objective.
|
||||||
return 1
|
return TRUE
|
||||||
if( !owner.current || owner.current.stat==DEAD )//If you're otherwise dead.
|
|
||||||
return 0
|
if(!target.current || !isbrain(target.current))
|
||||||
if( !target.current || !isbrain(target.current) )
|
return FALSE
|
||||||
return 0
|
|
||||||
var/atom/A = target.current
|
var/atom/A = target.current
|
||||||
while(A.loc) //check to see if the brainmob is on our person
|
var/list/datum/mind/owners = get_owners()
|
||||||
|
|
||||||
|
while(A.loc) // Check to see if the brainmob is on our person
|
||||||
A = A.loc
|
A = A.loc
|
||||||
if(A == owner.current)
|
for(var/datum/mind/M in owners)
|
||||||
return 1
|
if(M.current && M.current.stat != DEAD && A == M.current)
|
||||||
return 0
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
/datum/objective/debrain/update_explanation_text()
|
/datum/objective/debrain/update_explanation_text()
|
||||||
..()
|
..()
|
||||||
@@ -199,8 +213,6 @@
|
|||||||
else
|
else
|
||||||
explanation_text = "Free Objective"
|
explanation_text = "Free Objective"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/protect//The opposite of killing a dude.
|
/datum/objective/protect//The opposite of killing a dude.
|
||||||
var/target_role_type=0
|
var/target_role_type=0
|
||||||
martyr_compatible = 1
|
martyr_compatible = 1
|
||||||
@@ -212,13 +224,7 @@
|
|||||||
return target
|
return target
|
||||||
|
|
||||||
/datum/objective/protect/check_completion()
|
/datum/objective/protect/check_completion()
|
||||||
if(!target) //If it's a free objective.
|
return !target || considered_alive(target)
|
||||||
return 1
|
|
||||||
if(target.current)
|
|
||||||
if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current))
|
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/objective/protect/update_explanation_text()
|
/datum/objective/protect/update_explanation_text()
|
||||||
..()
|
..()
|
||||||
@@ -227,76 +233,32 @@
|
|||||||
else
|
else
|
||||||
explanation_text = "Free Objective"
|
explanation_text = "Free Objective"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/hijack
|
/datum/objective/hijack
|
||||||
explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody."
|
explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody."
|
||||||
|
team_explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive and out of custody. Leave no team member behind."
|
||||||
martyr_compatible = 0 //Technically you won't get both anyway.
|
martyr_compatible = 0 //Technically you won't get both anyway.
|
||||||
|
|
||||||
/datum/objective/hijack/check_completion()
|
/datum/objective/hijack/check_completion() // Requires all owners to escape.
|
||||||
if(!owner.current || owner.current.stat)
|
|
||||||
return 0
|
|
||||||
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
||||||
return 0
|
return FALSE
|
||||||
if(issilicon(owner.current))
|
var/list/datum/mind/owners = get_owners()
|
||||||
return 0
|
for(var/datum/mind/M in owners)
|
||||||
if(!SSshuttle.emergency.shuttle_areas[get_area(owner.current)])
|
if(!considered_alive(M) || !SSshuttle.emergency.shuttle_areas[get_area(M.current)])
|
||||||
return 0
|
return FALSE
|
||||||
return SSshuttle.emergency.is_hijacked()
|
return SSshuttle.emergency.is_hijacked()
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/hijackclone
|
|
||||||
explanation_text = "Hijack the emergency shuttle by ensuring only you (or your copies) escape."
|
|
||||||
martyr_compatible = 0
|
|
||||||
|
|
||||||
/datum/objective/hijackclone/check_completion()
|
|
||||||
if(!owner.current)
|
|
||||||
return FALSE
|
|
||||||
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
|
||||||
return FALSE
|
|
||||||
|
|
||||||
var/in_shuttle = FALSE
|
|
||||||
for(var/mob/living/player in GLOB.player_list) //Make sure nobody else is onboard
|
|
||||||
if(SSshuttle.emergency.shuttle_areas[get_area(player)])
|
|
||||||
if(player.mind && player.mind != owner)
|
|
||||||
if(player.stat != DEAD)
|
|
||||||
if(issilicon(player)) //Borgs are technically dead anyways
|
|
||||||
continue
|
|
||||||
if(isanimal(player)) //animals don't count
|
|
||||||
continue
|
|
||||||
if(isbrain(player)) //also technically dead
|
|
||||||
continue
|
|
||||||
var/location = get_turf(player.mind.current)
|
|
||||||
if(istype(location, /turf/open/floor/plasteel/shuttle/red))
|
|
||||||
continue
|
|
||||||
if(istype(location, /turf/open/floor/mineral/plastitanium/brig))
|
|
||||||
continue
|
|
||||||
if(player.real_name != owner.current.real_name)
|
|
||||||
return FALSE
|
|
||||||
else
|
|
||||||
in_shuttle = TRUE
|
|
||||||
return in_shuttle
|
|
||||||
|
|
||||||
/datum/objective/block
|
/datum/objective/block
|
||||||
explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive."
|
explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive."
|
||||||
martyr_compatible = 1
|
martyr_compatible = 1
|
||||||
|
|
||||||
/datum/objective/block/check_completion()
|
/datum/objective/block/check_completion()
|
||||||
if(!issilicon(owner.current))
|
|
||||||
return 0
|
|
||||||
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
||||||
return 1
|
return TRUE
|
||||||
|
|
||||||
for(var/mob/living/player in GLOB.player_list)
|
for(var/mob/living/player in GLOB.player_list)
|
||||||
if(issilicon(player))
|
if(player.mind && player.stat != DEAD && !issilicon(player))
|
||||||
continue
|
if(get_area(player) in SSshuttle.emergency.shuttle_areas)
|
||||||
if(player.mind)
|
return FALSE
|
||||||
if(player.stat != DEAD)
|
return TRUE
|
||||||
if(get_area(player) in SSshuttle.emergency.shuttle_areas)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/purge
|
/datum/objective/purge
|
||||||
explanation_text = "Ensure no mutant humanoid species are present aboard the escape shuttle."
|
explanation_text = "Ensure no mutant humanoid species are present aboard the escape shuttle."
|
||||||
@@ -304,63 +266,41 @@
|
|||||||
|
|
||||||
/datum/objective/purge/check_completion()
|
/datum/objective/purge/check_completion()
|
||||||
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
||||||
return 1
|
return TRUE
|
||||||
|
|
||||||
for(var/mob/living/player in GLOB.player_list)
|
for(var/mob/living/player in GLOB.player_list)
|
||||||
if(get_area(player) in SSshuttle.emergency.shuttle_areas && player.mind && player.stat != DEAD && ishuman(player))
|
if(get_area(player) in SSshuttle.emergency.shuttle_areas && player.mind && player.stat != DEAD && ishuman(player))
|
||||||
var/mob/living/carbon/human/H = player
|
var/mob/living/carbon/human/H = player
|
||||||
if(H.dna.species.id != "human")
|
if(H.dna.species.id != "human")
|
||||||
return 0
|
return FALSE
|
||||||
|
return TRUE
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/robot_army
|
/datum/objective/robot_army
|
||||||
explanation_text = "Have at least eight active cyborgs synced to you."
|
explanation_text = "Have at least eight active cyborgs synced to you."
|
||||||
martyr_compatible = 0
|
martyr_compatible = 0
|
||||||
|
|
||||||
/datum/objective/robot_army/check_completion()
|
/datum/objective/robot_army/check_completion()
|
||||||
if(!isAI(owner.current))
|
|
||||||
return 0
|
|
||||||
var/mob/living/silicon/ai/A = owner.current
|
|
||||||
|
|
||||||
var/counter = 0
|
var/counter = 0
|
||||||
|
var/list/datum/mind/owners = get_owners()
|
||||||
for(var/mob/living/silicon/robot/R in A.connected_robots)
|
for(var/datum/mind/M in owners)
|
||||||
if(R.stat != DEAD)
|
if(!M.current || !isAI(M.current))
|
||||||
counter++
|
continue
|
||||||
|
var/mob/living/silicon/ai/A = M.current
|
||||||
if(counter < 8)
|
for(var/mob/living/silicon/robot/R in A.connected_robots)
|
||||||
return 0
|
if(R.stat != DEAD)
|
||||||
return 1
|
counter++
|
||||||
|
return counter >= 8
|
||||||
|
|
||||||
/datum/objective/escape
|
/datum/objective/escape
|
||||||
explanation_text = "Escape on the shuttle or an escape pod alive and without being in custody."
|
explanation_text = "Escape on the shuttle or an escape pod alive and without being in custody."
|
||||||
|
team_explanation_text = "Have all members of your team escape on a shuttle or pod alive, without being in custody."
|
||||||
|
|
||||||
/datum/objective/escape/check_completion()
|
/datum/objective/escape/check_completion()
|
||||||
if(issilicon(owner.current))
|
// Require all owners escape safely.
|
||||||
return 0
|
var/list/datum/mind/owners = get_owners()
|
||||||
if(isbrain(owner.current))
|
for(var/datum/mind/M in owners)
|
||||||
return 0
|
if(!considered_escaped(M))
|
||||||
if(!owner.current || owner.current.stat == DEAD)
|
return FALSE
|
||||||
return 0
|
return TRUE
|
||||||
if(SSticker.force_ending) //This one isn't their fault, so lets just assume good faith
|
|
||||||
return 1
|
|
||||||
if(SSticker.mode.station_was_nuked) //If they escaped the blast somehow, let them win
|
|
||||||
return 1
|
|
||||||
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
|
||||||
return 0
|
|
||||||
var/turf/location = get_turf(owner.current)
|
|
||||||
if(!location)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if(istype(location, /turf/open/floor/plasteel/shuttle/red) || istype(location, /turf/open/floor/mineral/plastitanium/brig)) // Fails traitors if they are in the shuttle brig -- Polymorph
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if(location.onCentCom() || location.onSyndieBase())
|
|
||||||
return 1
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
/datum/objective/escape/escape_with_identity
|
/datum/objective/escape/escape_with_identity
|
||||||
var/target_real_name // Has to be stored because the target's real_name can change over the course of the round
|
var/target_real_name // Has to be stored because the target's real_name can change over the course of the round
|
||||||
@@ -387,39 +327,36 @@
|
|||||||
explanation_text = "Free Objective."
|
explanation_text = "Free Objective."
|
||||||
|
|
||||||
/datum/objective/escape/escape_with_identity/check_completion()
|
/datum/objective/escape/escape_with_identity/check_completion()
|
||||||
if(!target_real_name)
|
if(!target || !target_real_name)
|
||||||
return 1
|
return TRUE
|
||||||
if(!ishuman(owner.current))
|
var/list/datum/mind/owners = get_owners()
|
||||||
return 0
|
for(var/datum/mind/M in owners)
|
||||||
var/mob/living/carbon/human/H = owner.current
|
if(!ishuman(M.current) || !considered_escaped(M))
|
||||||
if(..())
|
continue
|
||||||
if(H.dna.real_name == target_real_name)
|
var/mob/living/carbon/human/H = M.current
|
||||||
if(H.get_id_name()== target_real_name || target_missing_id)
|
if(H.dna.real_name == target_real_name && (H.get_id_name() == target_real_name || target_missing_id))
|
||||||
return 1
|
return TRUE
|
||||||
return 0
|
return FALSE
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/survive
|
/datum/objective/survive
|
||||||
explanation_text = "Stay alive until the end."
|
explanation_text = "Stay alive until the end."
|
||||||
|
|
||||||
/datum/objective/survive/check_completion()
|
/datum/objective/survive/check_completion()
|
||||||
if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current))
|
var/list/datum/mind/owners = get_owners()
|
||||||
return 0 //Brains no longer win survive objectives. --NEO
|
for(var/datum/mind/M in owners)
|
||||||
if(!is_special_character(owner.current)) //This fails borg'd traitors
|
if(!considered_alive(M))
|
||||||
return 0
|
return FALSE
|
||||||
return 1
|
return TRUE
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/martyr
|
/datum/objective/martyr
|
||||||
explanation_text = "Die a glorious death."
|
explanation_text = "Die a glorious death."
|
||||||
|
|
||||||
/datum/objective/martyr/check_completion()
|
/datum/objective/martyr/check_completion()
|
||||||
if(!owner.current) //Gibbed, etc.
|
var/list/datum/mind/owners = get_owners()
|
||||||
return 1
|
for(var/datum/mind/M in owners)
|
||||||
if(owner.current && owner.current.stat == DEAD) //You're dead! Yay!
|
if(considered_alive(M))
|
||||||
return 1
|
return FALSE
|
||||||
return 0
|
return TRUE
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/nuclear
|
/datum/objective/nuclear
|
||||||
explanation_text = "Destroy the station with a nuclear device."
|
explanation_text = "Destroy the station with a nuclear device."
|
||||||
@@ -427,8 +364,8 @@
|
|||||||
|
|
||||||
/datum/objective/nuclear/check_completion()
|
/datum/objective/nuclear/check_completion()
|
||||||
if(SSticker && SSticker.mode && SSticker.mode.station_was_nuked)
|
if(SSticker && SSticker.mode && SSticker.mode.station_was_nuked)
|
||||||
return 1
|
return TRUE
|
||||||
return 0
|
return FALSE
|
||||||
|
|
||||||
GLOBAL_LIST_EMPTY(possible_items)
|
GLOBAL_LIST_EMPTY(possible_items)
|
||||||
/datum/objective/steal
|
/datum/objective/steal
|
||||||
@@ -446,16 +383,21 @@ GLOBAL_LIST_EMPTY(possible_items)
|
|||||||
new I
|
new I
|
||||||
|
|
||||||
/datum/objective/steal/find_target()
|
/datum/objective/steal/find_target()
|
||||||
|
var/list/datum/mind/owners = get_owners()
|
||||||
var/approved_targets = list()
|
var/approved_targets = list()
|
||||||
for(var/datum/objective_item/possible_item in GLOB.possible_items)
|
check_items:
|
||||||
if(is_unique_objective(possible_item.targetitem) && !(owner.current.mind.assigned_role in possible_item.excludefromjob))
|
for(var/datum/objective_item/possible_item in GLOB.possible_items)
|
||||||
|
if(!is_unique_objective(possible_item.targetitem))
|
||||||
|
continue
|
||||||
|
for(var/datum/mind/M in owners)
|
||||||
|
if(M.current.mind.assigned_role in possible_item.excludefromjob)
|
||||||
|
continue check_items
|
||||||
approved_targets += possible_item
|
approved_targets += possible_item
|
||||||
return set_target(safepick(approved_targets))
|
return set_target(safepick(approved_targets))
|
||||||
|
|
||||||
/datum/objective/steal/proc/set_target(datum/objective_item/item)
|
/datum/objective/steal/proc/set_target(datum/objective_item/item)
|
||||||
if(item)
|
if(item)
|
||||||
targetinfo = item
|
targetinfo = item
|
||||||
|
|
||||||
steal_target = targetinfo.targetitem
|
steal_target = targetinfo.targetitem
|
||||||
explanation_text = "Steal [targetinfo.name]"
|
explanation_text = "Steal [targetinfo.name]"
|
||||||
give_special_equipment(targetinfo.special_equipment)
|
give_special_equipment(targetinfo.special_equipment)
|
||||||
@@ -483,23 +425,26 @@ GLOBAL_LIST_EMPTY(possible_items)
|
|||||||
return steal_target
|
return steal_target
|
||||||
|
|
||||||
/datum/objective/steal/check_completion()
|
/datum/objective/steal/check_completion()
|
||||||
|
var/list/datum/mind/owners = get_owners()
|
||||||
if(!steal_target)
|
if(!steal_target)
|
||||||
return 1
|
return TRUE
|
||||||
if(!isliving(owner.current))
|
for(var/datum/mind/M in owners)
|
||||||
return 0
|
if(!isliving(M.current))
|
||||||
var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc.
|
continue
|
||||||
|
|
||||||
for(var/obj/I in all_items) //Check for items
|
var/list/all_items = M.current.GetAllContents() //this should get things in cheesewheels, books, etc.
|
||||||
if(istype(I, steal_target))
|
|
||||||
if(!targetinfo) //If there's no targetinfo, then that means it was a custom objective. At this point, we know you have the item, so return 1.
|
|
||||||
return 1
|
|
||||||
else if(targetinfo.check_special_completion(I))//Returns 1 by default. Items with special checks will return 1 if the conditions are fulfilled.
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if(targetinfo && I.type in targetinfo.altitems) //Ok, so you don't have the item. Do you have an alternative, at least?
|
for(var/obj/I in all_items) //Check for items
|
||||||
if(targetinfo.check_special_completion(I))//Yeah, we do! Don't return 0 if we don't though - then you could fail if you had 1 item that didn't pass and got checked first!
|
if(istype(I, steal_target))
|
||||||
return 1
|
if(!targetinfo) //If there's no targetinfo, then that means it was a custom objective. At this point, we know you have the item, so return 1.
|
||||||
return 0
|
return TRUE
|
||||||
|
else if(targetinfo.check_special_completion(I))//Returns 1 by default. Items with special checks will return 1 if the conditions are fulfilled.
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
if(targetinfo && I.type in targetinfo.altitems) //Ok, so you don't have the item. Do you have an alternative, at least?
|
||||||
|
if(targetinfo.check_special_completion(I))//Yeah, we do! Don't return 0 if we don't though - then you could fail if you had 1 item that didn't pass and got checked first!
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
|
||||||
GLOBAL_LIST_EMPTY(possible_items_special)
|
GLOBAL_LIST_EMPTY(possible_items_special)
|
||||||
@@ -553,31 +498,22 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
explanation_text = "Download [target_amount] research level\s."
|
explanation_text = "Download [target_amount] research level\s."
|
||||||
return target_amount
|
return target_amount
|
||||||
|
|
||||||
/datum/objective/download/check_completion()//NINJACODE
|
/datum/objective/download/check_completion()//NINJACODE.
|
||||||
if(!ishuman(owner.current))
|
var/current_amount = 0
|
||||||
return 0
|
var/list/datum/mind/owners = get_owners()
|
||||||
|
for(var/datum/mind/M in owners)
|
||||||
var/mob/living/carbon/human/H = owner.current
|
if(!ishuman(owner.current))
|
||||||
if(!H || H.stat == DEAD)
|
continue
|
||||||
return 0
|
var/mob/living/carbon/human/H = owner.current
|
||||||
|
if(!H || H.stat == DEAD || !istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
|
||||||
if(!istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
|
continue
|
||||||
return 0
|
var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit
|
||||||
|
if(!SN.s_initialized)
|
||||||
var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit
|
continue
|
||||||
if(!SN.s_initialized)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
var/current_amount
|
|
||||||
if(!SN.stored_research.len)
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
for(var/datum/tech/current_data in SN.stored_research)
|
for(var/datum/tech/current_data in SN.stored_research)
|
||||||
if(current_data.level)
|
if(current_data.level)
|
||||||
current_amount += (current_data.level-1)
|
current_amount += (current_data.level-1)
|
||||||
if(current_amount<target_amount)
|
return current_amount >= target_amount
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -614,10 +550,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
captured_amount+=1
|
captured_amount+=1
|
||||||
continue
|
continue
|
||||||
captured_amount+=2
|
captured_amount+=2
|
||||||
if(captured_amount<target_amount)
|
return captured_amount >= target_amount
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/datum/objective/absorb
|
/datum/objective/absorb
|
||||||
@@ -625,13 +558,14 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
/datum/objective/absorb/proc/gen_amount_goal(lowbound = 4, highbound = 6)
|
/datum/objective/absorb/proc/gen_amount_goal(lowbound = 4, highbound = 6)
|
||||||
target_amount = rand (lowbound,highbound)
|
target_amount = rand (lowbound,highbound)
|
||||||
var/n_p = 1 //autowin
|
var/n_p = 1 //autowin
|
||||||
|
var/list/datum/mind/owners = get_owners()
|
||||||
if (SSticker.current_state == GAME_STATE_SETTING_UP)
|
if (SSticker.current_state == GAME_STATE_SETTING_UP)
|
||||||
for(var/mob/dead/new_player/P in GLOB.player_list)
|
for(var/mob/dead/new_player/P in GLOB.player_list)
|
||||||
if(P.client && P.ready == PLAYER_READY_TO_PLAY && P.mind!=owner)
|
if(P.client && P.ready == PLAYER_READY_TO_PLAY && !(P.mind in owners))
|
||||||
n_p ++
|
n_p ++
|
||||||
else if (SSticker.IsRoundInProgress())
|
else if (SSticker.IsRoundInProgress())
|
||||||
for(var/mob/living/carbon/human/P in GLOB.player_list)
|
for(var/mob/living/carbon/human/P in GLOB.player_list)
|
||||||
if(P.client && !(P.mind in SSticker.mode.changelings) && P.mind!=owner)
|
if(P.client && !(P.mind in SSticker.mode.changelings) && !(P.mind in owners))
|
||||||
n_p ++
|
n_p ++
|
||||||
target_amount = min(target_amount, n_p)
|
target_amount = min(target_amount, n_p)
|
||||||
|
|
||||||
@@ -639,10 +573,13 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
return target_amount
|
return target_amount
|
||||||
|
|
||||||
/datum/objective/absorb/check_completion()
|
/datum/objective/absorb/check_completion()
|
||||||
if(owner && owner.changeling && owner.changeling.stored_profiles && (owner.changeling.absorbedcount >= target_amount))
|
var/list/datum/mind/owners = get_owners()
|
||||||
return 1
|
var/absorbedcount = 0
|
||||||
else
|
for(var/datum/mind/M in owners)
|
||||||
return 0
|
if(!owner || !owner.changeling || !owner.changeling.stored_profiles)
|
||||||
|
continue
|
||||||
|
absorbedcount += M.changeling.absorbedcount
|
||||||
|
return absorbedcount >= target_amount
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -658,10 +595,8 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
|
|
||||||
/datum/objective/destroy/check_completion()
|
/datum/objective/destroy/check_completion()
|
||||||
if(target && target.current)
|
if(target && target.current)
|
||||||
if(target.current.stat == DEAD || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
|
return target.current.stat == DEAD || target.current.z > 6 || !target.current.ckey //Borgs/brains/AIs count as dead for traitor objectives.
|
||||||
return 1
|
return TRUE
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/datum/objective/destroy/update_explanation_text()
|
/datum/objective/destroy/update_explanation_text()
|
||||||
..()
|
..()
|
||||||
@@ -690,18 +625,16 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
|||||||
wanted_items = list(/obj/item/spellbook, /obj/item/gun/magic, /obj/item/clothing/suit/space/hardsuit/wizard, /obj/item/scrying, /obj/item/antag_spawner/contract, /obj/item/device/necromantic_stone)
|
wanted_items = list(/obj/item/spellbook, /obj/item/gun/magic, /obj/item/clothing/suit/space/hardsuit/wizard, /obj/item/scrying, /obj/item/antag_spawner/contract, /obj/item/device/necromantic_stone)
|
||||||
|
|
||||||
/datum/objective/steal_five_of_type/check_completion()
|
/datum/objective/steal_five_of_type/check_completion()
|
||||||
if(!isliving(owner.current))
|
var/list/datum/mind/owners = get_owners()
|
||||||
return 0
|
|
||||||
var/stolen_count = 0
|
var/stolen_count = 0
|
||||||
var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc.
|
for(var/datum/mind/M in owners)
|
||||||
for(var/obj/I in all_items) //Check for wanted items
|
if(!isliving(M.current))
|
||||||
if(is_type_in_typecache(I, wanted_items))
|
continue
|
||||||
stolen_count++
|
var/list/all_items = M.current.GetAllContents() //this should get things in cheesewheels, books, etc.
|
||||||
if(stolen_count >= 5)
|
for(var/obj/I in all_items) //Check for wanted items
|
||||||
return 1
|
if(is_type_in_typecache(I, wanted_items))
|
||||||
else
|
stolen_count++
|
||||||
return 0
|
return stolen_count >= 5
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|||||||
13
code/game/gamemodes/objective_team.dm
Normal file
13
code/game/gamemodes/objective_team.dm
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
//A barebones antagonist team.
|
||||||
|
/datum/objective_team
|
||||||
|
var/list/datum/mind/members = list()
|
||||||
|
var/name = "team"
|
||||||
|
var/member_name = "member"
|
||||||
|
|
||||||
|
/datum/objective_team/New(starting_members)
|
||||||
|
. = ..()
|
||||||
|
if(starting_members)
|
||||||
|
members += starting_members
|
||||||
|
|
||||||
|
/datum/objective_team/proc/is_solo()
|
||||||
|
return members.len == 1
|
||||||
@@ -54,10 +54,7 @@
|
|||||||
log_game("[traitor.key] (ckey) has been selected as a [traitor_name]")
|
log_game("[traitor.key] (ckey) has been selected as a [traitor_name]")
|
||||||
antag_candidates.Remove(traitor)
|
antag_candidates.Remove(traitor)
|
||||||
|
|
||||||
|
return pre_traitors.len > 0
|
||||||
if(pre_traitors.len < required_enemies)
|
|
||||||
return 0
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
/datum/game_mode/traitor/post_setup()
|
/datum/game_mode/traitor/post_setup()
|
||||||
|
|||||||
@@ -517,6 +517,21 @@
|
|||||||
dat += "<td><A href='?priv_msg=[traitor.key]'>PM</A></td></tr>"
|
dat += "<td><A href='?priv_msg=[traitor.key]'>PM</A></td></tr>"
|
||||||
dat += "</table>"
|
dat += "</table>"
|
||||||
|
|
||||||
|
if(SSticker.mode.brother_teams.len > 0)
|
||||||
|
dat += "<br><table cellspacing=5><tr><td><B>Brothers</B></td><td></td><td></td></tr>"
|
||||||
|
for(var/datum/objective_team/brother_team/team in SSticker.mode.brother_teams)
|
||||||
|
for(var/datum/mind/brother in team.members)
|
||||||
|
var/mob/M = brother.current
|
||||||
|
if(M)
|
||||||
|
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||||
|
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||||
|
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||||
|
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||||
|
else
|
||||||
|
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[brother]'>[brother.name]([brother.key])</a><i>Brother body destroyed!</i></td>"
|
||||||
|
dat += "<td><A href='?priv_msg=[brother.key]'>PM</A></td></tr>"
|
||||||
|
dat += "</table>"
|
||||||
|
|
||||||
if(SSticker.mode.abductors.len)
|
if(SSticker.mode.abductors.len)
|
||||||
dat += "<br><table cellspacing=5><tr><td><B>Abductors</B></td><td></td><td></td></tr>"
|
dat += "<br><table cellspacing=5><tr><td><B>Abductors</B></td><td></td><td></td></tr>"
|
||||||
for(var/datum/mind/abductor in SSticker.mode.abductors)
|
for(var/datum/mind/abductor in SSticker.mode.abductors)
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
|||||||
var/B_monkey = 2048
|
var/B_monkey = 2048
|
||||||
var/B_gang = 4096
|
var/B_gang = 4096
|
||||||
var/B_abductor = 16384
|
var/B_abductor = 16384
|
||||||
|
var/B_brother = 32768
|
||||||
|
|
||||||
var/list/archived = list(B_traitor,B_operative,B_changeling,B_wizard,B_malf,B_rev,B_alien,B_pai,B_cultist,B_blob,B_ninja,B_monkey,B_gang,B_abductor)
|
var/list/archived = list(B_traitor,B_operative,B_changeling,B_wizard,B_malf,B_rev,B_alien,B_pai,B_cultist,B_blob,B_ninja,B_monkey,B_gang,B_abductor,B_brother)
|
||||||
|
|
||||||
be_special = list()
|
be_special = list()
|
||||||
|
|
||||||
@@ -83,6 +84,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
|||||||
be_special += ROLE_MONKEY
|
be_special += ROLE_MONKEY
|
||||||
if(16384)
|
if(16384)
|
||||||
be_special += ROLE_ABDUCTOR
|
be_special += ROLE_ABDUCTOR
|
||||||
|
if(32768)
|
||||||
|
be_special += ROLE_BROTHER
|
||||||
|
|
||||||
|
|
||||||
/datum/preferences/proc/update_preferences(current_version, savefile/S)
|
/datum/preferences/proc/update_preferences(current_version, savefile/S)
|
||||||
|
|||||||
@@ -262,7 +262,7 @@
|
|||||||
if(shuttle_areas[get_area(player)])
|
if(shuttle_areas[get_area(player)])
|
||||||
has_people = TRUE
|
has_people = TRUE
|
||||||
var/location = get_turf(player.mind.current)
|
var/location = get_turf(player.mind.current)
|
||||||
if(!(player.mind.special_role == "traitor" || player.mind.special_role == "Syndicate") && !istype(location, /turf/open/floor/plasteel/shuttle/red) && !istype(location, /turf/open/floor/mineral/plastitanium/brig))
|
if(!(player.mind.special_role == "traitor" || player.mind.special_role == "Syndicate" || player.mind.special_role == "blood brother") && !istype(location, /turf/open/floor/plasteel/shuttle/red) && !istype(location, /turf/open/floor/mineral/plastitanium/brig))
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
return has_people
|
return has_people
|
||||||
|
|||||||
@@ -81,11 +81,11 @@ ALERT_DELTA Destruction of the station is imminent. All crew are instructed to o
|
|||||||
## Set to 0 to disable that mode.
|
## Set to 0 to disable that mode.
|
||||||
|
|
||||||
PROBABILITY TRAITOR 5
|
PROBABILITY TRAITOR 5
|
||||||
|
PROBABILITY TRAITORBRO 2
|
||||||
PROBABILITY TRAITORCHAN 4
|
PROBABILITY TRAITORCHAN 4
|
||||||
PROBABILITY INTERNAL_AFFAIRS 3
|
PROBABILITY INTERNAL_AFFAIRS 3
|
||||||
PROBABILITY NUCLEAR 2
|
PROBABILITY NUCLEAR 2
|
||||||
PROBABILITY REVOLUTION 2
|
PROBABILITY REVOLUTION 2
|
||||||
PROBABILITY GANG 2
|
|
||||||
PROBABILITY CULT 2
|
PROBABILITY CULT 2
|
||||||
PROBABILITY CHANGELING 2
|
PROBABILITY CHANGELING 2
|
||||||
PROBABILITY WIZARD 4
|
PROBABILITY WIZARD 4
|
||||||
@@ -109,11 +109,11 @@ REPEATED_MODE_ADJUST 45 30 10
|
|||||||
## Modes that aren't continuous will end the instant all antagonists are dead.
|
## Modes that aren't continuous will end the instant all antagonists are dead.
|
||||||
|
|
||||||
CONTINUOUS TRAITOR
|
CONTINUOUS TRAITOR
|
||||||
|
CONTINUOUS TRAITORBRO
|
||||||
CONTINUOUS TRAITORCHAN
|
CONTINUOUS TRAITORCHAN
|
||||||
CONTINUOUS INTERNAL_AFFAIRS
|
CONTINUOUS INTERNAL_AFFAIRS
|
||||||
#CONTINUOUS NUCLEAR
|
#CONTINUOUS NUCLEAR
|
||||||
#CONTINUOUS REVOLUTION
|
#CONTINUOUS REVOLUTION
|
||||||
CONTINUOUS GANG
|
|
||||||
CONTINUOUS CULT
|
CONTINUOUS CULT
|
||||||
CONTINUOUS CLOCKWORK_CULT
|
CONTINUOUS CLOCKWORK_CULT
|
||||||
CONTINUOUS CHANGELING
|
CONTINUOUS CHANGELING
|
||||||
@@ -134,11 +134,11 @@ CONTINUOUS SECRET_EXTENDED
|
|||||||
## In modes that are continuous, if all antagonists should die then a new set of antagonists will be created.
|
## In modes that are continuous, if all antagonists should die then a new set of antagonists will be created.
|
||||||
|
|
||||||
MIDROUND_ANTAG TRAITOR
|
MIDROUND_ANTAG TRAITOR
|
||||||
|
#MIDROUND_ANTAG TRAITORBRO
|
||||||
MIDROUND_ANTAG TRAITORCHAN
|
MIDROUND_ANTAG TRAITORCHAN
|
||||||
MIDROUND_ANTAG INTERNAL_AFFAIRS
|
MIDROUND_ANTAG INTERNAL_AFFAIRS
|
||||||
#MIDROUND_ANTAG NUCLEAR
|
#MIDROUND_ANTAG NUCLEAR
|
||||||
#MIDROUND_ANTAG REVOLUTION
|
#MIDROUND_ANTAG REVOLUTION
|
||||||
#MIDROUND_ANTAG GANG
|
|
||||||
MIDROUND_ANTAG CULT
|
MIDROUND_ANTAG CULT
|
||||||
MIDROUND_ANTAG CLOCKWORK_CULT
|
MIDROUND_ANTAG CLOCKWORK_CULT
|
||||||
MIDROUND_ANTAG CHANGELING
|
MIDROUND_ANTAG CHANGELING
|
||||||
@@ -157,6 +157,9 @@ MIDROUND_ANTAG ABDUCTION
|
|||||||
#MIN_POP TRAITOR 0
|
#MIN_POP TRAITOR 0
|
||||||
#MAX_POP TRAITOR -1
|
#MAX_POP TRAITOR -1
|
||||||
|
|
||||||
|
#MIN_POP TRAITORBRO 0
|
||||||
|
#MAX_POP TRAITORBRO -1
|
||||||
|
|
||||||
#MIN_POP TRAITORCHAN 15
|
#MIN_POP TRAITORCHAN 15
|
||||||
#MAX_POP TRAITORCHAN -1
|
#MAX_POP TRAITORCHAN -1
|
||||||
|
|
||||||
@@ -169,9 +172,6 @@ MIDROUND_ANTAG ABDUCTION
|
|||||||
#MIN_POP REVOLUTION 20
|
#MIN_POP REVOLUTION 20
|
||||||
#MAX_POP REVOLUTION -1
|
#MAX_POP REVOLUTION -1
|
||||||
|
|
||||||
#MIN_POP GANG 20
|
|
||||||
#MAX_POP GANG -1
|
|
||||||
|
|
||||||
#MIN_POP CULT 24
|
#MIN_POP CULT 24
|
||||||
#MAX_POP CULT -1
|
#MAX_POP CULT -1
|
||||||
|
|
||||||
@@ -212,6 +212,7 @@ SHUTTLE_REFUEL_DELAY 12000
|
|||||||
## Used as (Antagonists = Population / Coeff)
|
## Used as (Antagonists = Population / Coeff)
|
||||||
## Set to 0 to disable scaling and use default numbers instead.
|
## Set to 0 to disable scaling and use default numbers instead.
|
||||||
TRAITOR_SCALING_COEFF 6
|
TRAITOR_SCALING_COEFF 6
|
||||||
|
BROTHER_SCALING_COEFF 6
|
||||||
CHANGELING_SCALING_COEFF 6
|
CHANGELING_SCALING_COEFF 6
|
||||||
|
|
||||||
## Variables calculate how number of open security officer positions will scale to population.
|
## Variables calculate how number of open security officer positions will scale to population.
|
||||||
@@ -222,6 +223,7 @@ SECURITY_SCALING_COEFF 8
|
|||||||
## The number of objectives traitors get.
|
## The number of objectives traitors get.
|
||||||
## Not including escaping/hijacking.
|
## Not including escaping/hijacking.
|
||||||
TRAITOR_OBJECTIVES_AMOUNT 2
|
TRAITOR_OBJECTIVES_AMOUNT 2
|
||||||
|
BROTHER_OBJECTIVES_AMOUNT 2
|
||||||
|
|
||||||
## Uncomment to prohibit jobs that start with loyalty
|
## Uncomment to prohibit jobs that start with loyalty
|
||||||
## implants from being most antagonists.
|
## implants from being most antagonists.
|
||||||
|
|||||||
@@ -244,6 +244,7 @@
|
|||||||
#include "code\datums\spawners_menu.dm"
|
#include "code\datums\spawners_menu.dm"
|
||||||
#include "code\datums\verbs.dm"
|
#include "code\datums\verbs.dm"
|
||||||
#include "code\datums\antagonists\antag_datum.dm"
|
#include "code\datums\antagonists\antag_datum.dm"
|
||||||
|
#include "code\datums\antagonists\datum_brother.dm"
|
||||||
#include "code\datums\antagonists\datum_clockcult.dm"
|
#include "code\datums\antagonists\datum_clockcult.dm"
|
||||||
#include "code\datums\antagonists\datum_cult.dm"
|
#include "code\datums\antagonists\datum_cult.dm"
|
||||||
#include "code\datums\antagonists\datum_internal_affairs.dm"
|
#include "code\datums\antagonists\datum_internal_affairs.dm"
|
||||||
@@ -374,6 +375,8 @@
|
|||||||
#include "code\game\gamemodes\game_mode.dm"
|
#include "code\game\gamemodes\game_mode.dm"
|
||||||
#include "code\game\gamemodes\objective.dm"
|
#include "code\game\gamemodes\objective.dm"
|
||||||
#include "code\game\gamemodes\objective_items.dm"
|
#include "code\game\gamemodes\objective_items.dm"
|
||||||
|
#include "code\game\gamemodes\objective_team.dm"
|
||||||
|
#include "code\game\gamemodes\brother\traitor_bro.dm"
|
||||||
#include "code\game\gamemodes\blob\blob.dm"
|
#include "code\game\gamemodes\blob\blob.dm"
|
||||||
#include "code\game\gamemodes\blob\blob_finish.dm"
|
#include "code\game\gamemodes\blob\blob_finish.dm"
|
||||||
#include "code\game\gamemodes\blob\blob_report.dm"
|
#include "code\game\gamemodes\blob\blob_report.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user