Merge pull request #10998 from Zuhayr/antagsystem

Antag system fixes.
This commit is contained in:
Chinsky
2015-09-05 07:56:42 +03:00
48 changed files with 551 additions and 584 deletions

View File

@@ -217,6 +217,7 @@
#include "code\game\antagonist\antagonist_add.dm" #include "code\game\antagonist\antagonist_add.dm"
#include "code\game\antagonist\antagonist_create.dm" #include "code\game\antagonist\antagonist_create.dm"
#include "code\game\antagonist\antagonist_equip.dm" #include "code\game\antagonist\antagonist_equip.dm"
#include "code\game\antagonist\antagonist_factions.dm"
#include "code\game\antagonist\antagonist_helpers.dm" #include "code\game\antagonist\antagonist_helpers.dm"
#include "code\game\antagonist\antagonist_objectives.dm" #include "code\game\antagonist\antagonist_objectives.dm"
#include "code\game\antagonist\antagonist_panel.dm" #include "code\game\antagonist\antagonist_panel.dm"
@@ -235,6 +236,7 @@
#include "code\game\antagonist\station\changeling.dm" #include "code\game\antagonist\station\changeling.dm"
#include "code\game\antagonist\station\cultist.dm" #include "code\game\antagonist\station\cultist.dm"
#include "code\game\antagonist\station\highlander.dm" #include "code\game\antagonist\station\highlander.dm"
#include "code\game\antagonist\station\loyalist.dm"
#include "code\game\antagonist\station\renegade.dm" #include "code\game\antagonist\station\renegade.dm"
#include "code\game\antagonist\station\revolutionary.dm" #include "code\game\antagonist\station\revolutionary.dm"
#include "code\game\antagonist\station\rogue_ai.dm" #include "code\game\antagonist\station\rogue_ai.dm"

View File

@@ -74,9 +74,6 @@ var/list/gamemode_cache = list()
var/automute_on = 0 //enables automuting/spam prevention var/automute_on = 0 //enables automuting/spam prevention
var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access. var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access.
var/rp_rev = 0 // Changes between conversion methods in rev.
var/announce_revheads = 0 // Determines if revheads are announced in revolution mode.
var/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds... var/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds...
var/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active. var/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active.
@@ -635,12 +632,6 @@ var/list/gamemode_cache = list()
if("disable_welder_vision") if("disable_welder_vision")
config.welder_vision = 0 config.welder_vision = 0
if("rp_rev")
config.rp_rev = 1
if("announce_revheads")
config.announce_revheads = 1
if("allow_extra_antags") if("allow_extra_antags")
config.allow_extra_antags = 1 config.allow_extra_antags = 1

View File

@@ -7,7 +7,14 @@ var/datum/antagonist/xenos/borer/borers
mob_path = /mob/living/simple_animal/borer mob_path = /mob/living/simple_animal/borer
bantype = "Borer" bantype = "Borer"
welcome_text = "Use your Infest power to crawl into the ear of a host and fuse with their brain. You can only take control temporarily, and at risk of hurting your host, so be clever and careful; your host is encouraged to help you however they can. Talk to your fellow borers with :x." welcome_text = "Use your Infest power to crawl into the ear of a host and fuse with their brain. You can only take control temporarily, and at risk of hurting your host, so be clever and careful; your host is encouraged to help you however they can. Talk to your fellow borers with :x."
var/list/hosts = list() antag_indicator = "brainworm"
faction_role_text = "Borer Thrall"
faction_descriptor = "Unity"
faction_welcome = "You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head."
initial_spawn_req = 3
initial_spawn_target = 5
/datum/antagonist/xenos/borer/New() /datum/antagonist/xenos/borer/New()
..(1) ..(1)
@@ -23,29 +30,23 @@ var/datum/antagonist/xenos/borer/borers
player.objectives += new /datum/objective/borer_reproduce() player.objectives += new /datum/objective/borer_reproduce()
player.objectives += new /datum/objective/escape() player.objectives += new /datum/objective/escape()
/datum/antagonist/xenos/borer/proc/place_in_host(var/mob/living/simple_animal/borer/borer, var/mob/living/carbon/human/host)
borer.host = host
borer.host_brain.name = host.name
borer.host_brain.real_name = host.real_name
var/obj/item/organ/external/head = host.get_organ("head")
if(head) head.implants += borer
/datum/antagonist/xenos/borer/proc/get_hosts()
var/list/possible_hosts = list()
for(var/mob/living/carbon/human/H in mob_list)
if(H.stat != 2 && !(H.species.flags & IS_SYNTHETIC) && !H.has_brain_worms())
possible_hosts |= H
return possible_hosts
/datum/antagonist/xenos/borer/place_all_mobs()
var/list/possible_hosts = get_hosts()
for(var/datum/mind/player in current_antagonists)
if(!possible_hosts.len)
return
var/mob/host = pick(possible_hosts)
possible_hosts -= host
place_in_host(player, host)
/datum/antagonist/xenos/borer/place_mob(var/mob/living/mob) /datum/antagonist/xenos/borer/place_mob(var/mob/living/mob)
var/list/possible_hosts = get_hosts() var/mob/living/simple_animal/borer/borer = mob
if(possible_hosts.len) place_in_host(mob, pick(possible_hosts)) if(istype(borer))
var/mob/living/carbon/human/host
for(var/mob/living/carbon/human/H in mob_list)
if(H.stat != 2 && !(H.species.flags & IS_SYNTHETIC) && !H.has_brain_worms())
host = H
break
if(istype(host))
var/obj/item/organ/external/head = host.get_organ("head")
if(head)
borer.host = host
head.implants += borer
borer.loc = head
if(!borer.host_brain)
borer.host_brain = new(borer)
borer.host_brain.name = host.name
borer.host_brain.real_name = host.real_name
return
..() // Place them at a vent if they can't get a host.

View File

@@ -10,27 +10,21 @@ var/datum/antagonist/xenos/xenomorphs
flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE
welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve." welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve."
max_antags = 5 hard_cap = 5
max_antags_round = 8 hard_cap_round = 8
initial_spawn_req = 4
initial_spawn_target = 6
spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation." spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation."
spawn_announcement_title = "Lifesign Alert" spawn_announcement_title = "Lifesign Alert"
spawn_announcement_sound = 'sound/AI/aliens.ogg' spawn_announcement_sound = 'sound/AI/aliens.ogg'
spawn_announcement_delay = 400 spawn_announcement_delay = 5000
/datum/antagonist/xenos/New(var/no_reference) /datum/antagonist/xenos/New(var/no_reference)
..() ..()
if(!no_reference) if(!no_reference)
xenomorphs = src xenomorphs = src
/datum/antagonist/xenos/Topic(href, href_list)
if (..())
return
if(href_list["move_to_spawn"]) place_mob(locate(href_list["move_to_spawn"]))
/datum/antagonist/xenos/get_extra_panel_options(var/datum/mind/player)
return "<a href='?src=\ref[src];move_to_spawn=\ref[player.current]'>\[move to vent\]</a>"
/datum/antagonist/xenos/attempt_random_spawn() /datum/antagonist/xenos/attempt_random_spawn()
if(config.aliens_allowed) ..() if(config.aliens_allowed) ..()
@@ -48,12 +42,5 @@ var/datum/antagonist/xenos/xenomorphs
player.objectives += new /datum/objective/survive() player.objectives += new /datum/objective/survive()
player.objectives += new /datum/objective/escape() player.objectives += new /datum/objective/escape()
/datum/antagonist/xenos/place_all_mobs()
var/list/vents = get_vents()
for(var/datum/mind/player in current_antagonists)
var/obj/machinery/atmospherics/unary/vent_pump/temp_vent = pick(vents)
vents -= temp_vent
player.current.loc = get_turf(temp_vent)
/datum/antagonist/xenos/place_mob(var/mob/living/player) /datum/antagonist/xenos/place_mob(var/mob/living/player)
player.loc = get_turf(pick(get_vents())) player.loc = get_turf(pick(get_vents()))

View File

@@ -1,53 +1,76 @@
/datum/antagonist /datum/antagonist
var/role_type = BE_TRAITOR // Text shown when becoming this antagonist.
var/role_text = "Traitor" var/list/restricted_jobs = list() // Jobs that cannot be this antagonist (depending on config)
var/role_text_plural = "Traitors" var/list/protected_jobs = list() // As above.
// Strings.
var/welcome_text = "Cry havoc and let slip the dogs of war!" var/welcome_text = "Cry havoc and let slip the dogs of war!"
var/leader_welcome_text var/leader_welcome_text // Text shown to the leader, if any.
var/victory_text var/victory_text // World output at roundend for victory.
var/loss_text var/loss_text // As above for loss.
var/victory_feedback_tag var/victory_feedback_tag // Used by the database for end of round loss.
var/loss_feedback_tag var/loss_feedback_tag // Used by the database for end of round loss.
var/max_antags = 3
var/max_antags_round = 5
// Random spawn values. // Role data.
var/spawn_announcement var/id = "traitor" // Unique datum identifier.
var/spawn_announcement_title var/role_type = BE_TRAITOR // Preferences option for this role.
var/spawn_announcement_sound var/role_text = "Traitor" // special_role text.
var/spawn_announcement_delay var/role_text_plural = "Traitors" // As above but plural.
var/id = "traitor" // Visual references.
var/landmark_id var/antag_indicator // icon_state for icons/mob/mob.dm visual indicator.
var/antag_indicator var/faction_indicator // See antag_indicator, but for factionalized people only.
var/mob_path = /mob/living/carbon/human var/faction_invisible // Can members of the faction identify other antagonists?
var/feedback_tag = "traitor_objective"
var/bantype = "Syndicate"
var/suspicion_chance = 50
var/flags = 0
var/cur_max = 0
var/datum/mind/leader // Faction data.
var/spawned_nuke var/faction_role_text // Role for sub-antags. Mandatory for faction role.
var/nuke_spawn_loc var/faction_descriptor // Description of the cause. Mandatory for faction role.
var/faction_verb // Verb added when becoming a member of the faction, if any.
var/faction_welcome // Message shown to faction members.
var/list/valid_species = list("Unathi","Tajara","Skrell","Human") // Used for setting appearance. // Spawn values (autotraitor and game mode)
var/list/current_antagonists = list() var/hard_cap = 3 // Autotraitor var. Won't spawn more than this many antags.
var/list/pending_antagonists = list() var/hard_cap_round = 5 // As above but 'core' round antags ie. roundstart.
var/list/starting_locations = list() var/initial_spawn_req = 1 // Gamemode using this template won't start without this # candidates.
var/list/global_objectives = list() var/initial_spawn_target = 3 // Gamemode will attempt to spawn this many antags.
var/list/restricted_jobs = list() var/announced // Has an announcement been sent?
var/list/protected_jobs = list() var/spawn_announcement // When the datum spawn proc is called, does it announce to the world? (ie. xenos)
var/list/candidates = list() var/spawn_announcement_title // Report title.
var/spawn_announcement_sound // Report sound clip.
var/spawn_announcement_delay // Time between initial spawn and round announcement.
// Misc.
var/landmark_id // Spawn point identifier.
var/mob_path = /mob/living/carbon/human // Mobtype this antag will use if none is provided.
var/feedback_tag = "traitor_objective" // End of round
var/bantype = "Syndicate" // Ban to check when spawning this antag.
var/suspicion_chance = 50 // Prob of being on the initial Command report
var/flags = 0 // Various runtime options.
// Used for setting appearance.
var/list/valid_species = list("Unathi","Tajara","Skrell","Human")
// Runtime vars.
var/datum/mind/leader // Current leader, if any.
var/cur_max = 0 // Autotraitor current effective maximum.
var/spawned_nuke // Has a bomb been spawned?
var/nuke_spawn_loc // If so, where should it be placed?
var/list/current_antagonists = list() // All marked antagonists for this type.
var/list/pending_antagonists = list() // Candidates that are awaiting finalized antag status.
var/list/starting_locations = list() // Spawn points.
var/list/global_objectives = list() // Universal objectives if any.
var/list/candidates = list() // Potential candidates.
var/list/faction_members = list() // Semi-antags (in-round revs, borer thralls)
// ID card stuff.
var/default_access = list() var/default_access = list()
var/id_type = /obj/item/weapon/card/id var/id_type = /obj/item/weapon/card/id
var/announced
/datum/antagonist/New() /datum/antagonist/New()
..() ..()
cur_max = max_antags cur_max = hard_cap
get_starting_locations() get_starting_locations()
if(!role_text_plural) if(!role_text_plural)
role_text_plural = role_text role_text_plural = role_text
@@ -59,7 +82,7 @@
/datum/antagonist/proc/get_candidates(var/ghosts_only) /datum/antagonist/proc/get_candidates(var/ghosts_only)
candidates = list() // Clear. candidates = list() // Clear.
// Prune restricted status. Broke it up for readability. // Prune restricted status. Broke it up for readability.
// Note that this is done before jobs are handed out. // Note that this is done before jobs are handed out.
for(var/datum/mind/player in ticker.mode.get_players_for_role(role_type, id)) for(var/datum/mind/player in ticker.mode.get_players_for_role(role_type, id))
@@ -85,14 +108,21 @@
/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player) /datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player)
if(!can_late_spawn()) if(!can_late_spawn())
return return 0
if(!istype(player)) player = get_candidates(is_latejoin_template()) if(!istype(player))
var/list/players = get_candidates(is_latejoin_template())
if(players && players.len)
player = pick(players)
if(!istype(player))
message_admins("AUTO[uppertext(ticker.mode.name)]: Failed to find a candidate for [role_text].")
return 0
player.current << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>" player.current << "<span class='danger'><i>You have been selected this round as an antagonist!</i></span>"
message_admins("AUTO[uppertext(ticker.mode.name)]: Selected [player] as a [role_text].")
if(istype(player.current, /mob/dead)) if(istype(player.current, /mob/dead))
create_default(player.current) create_default(player.current)
else else
add_antagonist(player,0,1,0,1,1) add_antagonist(player,0,0,0,1,1)
return return 1
/datum/antagonist/proc/build_candidate_list(var/ghosts_only) /datum/antagonist/proc/build_candidate_list(var/ghosts_only)
// Get the raw list of potential players. // Get the raw list of potential players.
@@ -111,7 +141,7 @@
return 0 return 0
//Grab candidates randomly until we have enough. //Grab candidates randomly until we have enough.
while(candidates.len && pending_antagonists.len < cur_max) while(candidates.len && pending_antagonists.len < initial_spawn_target)
var/datum/mind/player = pick(candidates) var/datum/mind/player = pick(candidates)
candidates -= player candidates -= player
draft_antagonist(player) draft_antagonist(player)
@@ -132,14 +162,14 @@
pending_antagonists |= player pending_antagonists |= player
log_debug("[player.key] has been selected for [role_text] by lottery.") log_debug("[player.key] has been selected for [role_text] by lottery.")
//Ensure that antags with ANTAG_OVERRIDE_JOB do not occupy job slots. //Ensure that antags with ANTAG_OVERRIDE_JOB do not occupy job slots.
if(flags & ANTAG_OVERRIDE_JOB) if(flags & ANTAG_OVERRIDE_JOB)
player.assigned_role = role_text player.assigned_role = role_text
//Ensure that a player cannot be drafted for multiple antag roles, taking up slots for antag roles that they will not fill. //Ensure that a player cannot be drafted for multiple antag roles, taking up slots for antag roles that they will not fill.
player.special_role = role_text player.special_role = role_text
return 1 return 1
//Spawns all pending_antagonists. This is done separately from attempt_spawn in case the game mode setup fails. //Spawns all pending_antagonists. This is done separately from attempt_spawn in case the game mode setup fails.

View File

@@ -1,15 +1,8 @@
/datum/antagonist/proc/add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance) /datum/antagonist/proc/add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance)
if(!istype(player))
return 0
if(!player.current)
return 0
if(player in current_antagonists)
return 0
if(!can_become_antag(player, ignore_role))
return 0
current_antagonists |= player if(!add_antagonist_mind(player, ignore_role))
return
//do this again, just in case //do this again, just in case
if(flags & ANTAG_OVERRIDE_JOB) if(flags & ANTAG_OVERRIDE_JOB)
player.assigned_role = role_text player.assigned_role = role_text
@@ -23,10 +16,37 @@
equip(player.current) equip(player.current)
return 1 return 1
/datum/antagonist/proc/add_antagonist_mind(var/datum/mind/player, var/ignore_role, var/nonstandard_role_type, var/nonstandard_role_msg)
if(!istype(player))
return 0
if(!player.current)
return 0
if(player in current_antagonists)
return 0
if(!can_become_antag(player, ignore_role))
return 0
current_antagonists |= player
if(faction_verb && player.current)
player.current.verbs |= faction_verb
// Handle only adding a mind and not bothering with gear etc.
if(nonstandard_role_type)
faction_members |= player
player.current << "<span class='danger'><font size=3>You are \a [nonstandard_role_type]!</span>"
player.special_role = nonstandard_role_type
if(nonstandard_role_msg)
player.current << "<span class='notice'>[nonstandard_role_msg]</span>"
update_icons_added(player)
return 1
/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted) /datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
if(player.current && faction_verb)
player.current.verbs -= faction_verb
if(player in current_antagonists) if(player in current_antagonists)
player.current << "<span class='danger'><font size = 3>You are no longer a [role_text]!</font></span>" player.current << "<span class='danger'><font size = 3>You are no longer a [role_text]!</font></span>"
current_antagonists -= player current_antagonists -= player
faction_members -= player
player.special_role = null player.special_role = null
update_icons_removed(player) update_icons_removed(player)
BITSET(player.current.hud_updateflag, SPECIALROLE_HUD) BITSET(player.current.hud_updateflag, SPECIALROLE_HUD)

View File

@@ -0,0 +1,50 @@
/mob/living/proc/convert_to_rev(mob/M as mob in oview(src))
set name = "Convert Bourgeoise"
set category = "Abilities"
if(!M.mind)
return
convert_to_faction(M.mind, revs)
/mob/living/proc/convert_to_faction(var/datum/mind/player, var/datum/antagonist/faction)
if(!player || !faction || !player.current)
return
if(!faction.faction_verb || !faction.faction_descriptor || !faction.faction_verb)
return
if(faction.is_antagonist(player))
src << "<span class='warning'>\The [player.current] already serves the [faction.faction_descriptor].</span>"
return
if(player_is_antag(player))
src << "<span class='warning'>\The [player.current]'s loyalties seem to be elsewhere...</span>"
return
if(!faction.can_become_antag(player))
src << "<span class='warning'>\The [player.current] cannot be \a [faction.faction_role_text]!</span>"
return
if(world.time < player.rev_cooldown)
src << "<span class='danger'>You must wait five seconds between attempts.</span>"
return
src << "<span class='danger'>You are attempting to convert \the [player.current]...</span>"
log_admin("[src]([src.ckey]) attempted to convert [player.current].")
message_admins("<span class='danger'>[src]([src.ckey]) attempted to convert [player.current].</span>")
player.rev_cooldown = world.time+100
var/choice = alert(player.current,"Asked by [src]: Do you want to join the [faction.faction_descriptor]?","Join the [faction.faction_descriptor]?","No!","Yes!")
if(choice == "Yes!" && faction.add_antagonist_mind(player, 0, faction.faction_role_text, faction.faction_welcome))
src << "<span class='notice'>\The [player.current] joins the [faction.faction_descriptor]!</span>"
return
if(choice == "No!")
player << "<span class='danger'>You reject this traitorous cause!</span>"
src << "<span class='danger'>\The [player.current] does not support the [faction.faction_descriptor]!</span>"
/mob/living/proc/convert_to_loyalist(mob/M as mob in oview(src))
set name = "Convert Recidivist"
set category = "Abilities"
if(!M.mind)
return
convert_to_faction(M.mind, loyalists)

View File

@@ -5,23 +5,20 @@
if(L.name == landmark_id) if(L.name == landmark_id)
starting_locations |= get_turf(L) starting_locations |= get_turf(L)
/datum/antagonist/proc/place_all_mobs()
if(!starting_locations || !starting_locations.len || !current_antagonists || !current_antagonists.len)
return
for(var/datum/mind/player in current_antagonists)
player.current.loc = pick(starting_locations)
/datum/antagonist/proc/announce_antagonist_spawn() /datum/antagonist/proc/announce_antagonist_spawn()
if(spawn_announcement) if(spawn_announcement)
if(announced) if(announced)
return return
announced = 1 announced = 1
if(spawn_announcement_delay) spawn(0)
sleep(spawn_announcement_delay) if(spawn_announcement_delay)
if(spawn_announcement_sound) sleep(spawn_announcement_delay)
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound) if(spawn_announcement_sound)
else command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound)
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]") else
command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]")
return
/datum/antagonist/proc/place_mob(var/mob/living/mob) /datum/antagonist/proc/place_mob(var/mob/living/mob)
if(!starting_locations || !starting_locations.len) if(!starting_locations || !starting_locations.len)

View File

@@ -22,50 +22,63 @@
id.name = "[player.real_name]'s ID Card" id.name = "[player.real_name]'s ID Card"
id.registered_name = player.real_name id.registered_name = player.real_name
/datum/antagonist/proc/clear_indicators(var/datum/mind/recipient)
if(!recipient.current || !recipient.current.client)
return
for(var/image/I in recipient.current.client.images)
if(I.icon_state == antag_indicator || (faction_indicator && I.icon_state == faction_indicator))
qdel(I)
/datum/antagonist/proc/get_indicator(var/datum/mind/recipient, var/datum/mind/other)
if(!antag_indicator || !other.current || !recipient.current)
return
var/indicator = (faction_indicator && (other in faction_members)) ? faction_indicator : antag_indicator
return image('icons/mob/mob.dmi', loc = other.current, icon_state = indicator)
/datum/antagonist/proc/update_all_icons() /datum/antagonist/proc/update_all_icons()
if(!antag_indicator) if(!antag_indicator)
return return
for(var/datum/mind/antag in current_antagonists) for(var/datum/mind/antag in current_antagonists)
if(antag.current && antag.current.client) clear_indicators(antag)
for(var/image/I in antag.current.client.images) if(faction_invisible && (antag in faction_members))
if(I.icon_state == antag_indicator) continue
qdel(I) for(var/datum/mind/other_antag in current_antagonists)
for(var/datum/mind/other_antag in current_antagonists) if(antag.current && antag.current.client)
if(other_antag.current) antag.current.client.images |= get_indicator(antag, other_antag)
antag.current.client.images |= image('icons/mob/mob.dmi', loc = other_antag.current, icon_state = antag_indicator)
/datum/antagonist/proc/update_icons_added(var/datum/mind/player) /datum/antagonist/proc/update_icons_added(var/datum/mind/player)
if(!antag_indicator || !player.current) if(!antag_indicator || !player.current)
return return
spawn(0) spawn(0)
var/give_to_player = (!faction_invisible || !(player in faction_members))
for(var/datum/mind/antag in current_antagonists) for(var/datum/mind/antag in current_antagonists)
if(!antag.current) if(!antag.current)
continue continue
if(antag.current.client) if(antag.current.client)
antag.current.client.images |= image('icons/mob/mob.dmi', loc = player.current, icon_state = antag_indicator) antag.current.client.images |= get_indicator(antag, player)
if(!give_to_player)
continue
if(player.current.client) if(player.current.client)
player.current.client.images |= image('icons/mob/mob.dmi', loc = antag.current, icon_state = antag_indicator) player.current.client.images |= get_indicator(player, antag)
/datum/antagonist/proc/update_icons_removed(var/datum/mind/player) /datum/antagonist/proc/update_icons_removed(var/datum/mind/player)
if(!antag_indicator || !player.current) if(!antag_indicator || !player.current)
return return
spawn(0) spawn(0)
for(var/datum/mind/antag in current_antagonists) clear_indicators(player)
if(antag.current)
if(antag.current.client)
for(var/image/I in antag.current.client.images)
if(I.icon_state == antag_indicator && I.loc == player.current)
qdel(I)
if(player.current && player.current.client) if(player.current && player.current.client)
for(var/image/I in player.current.client.images) for(var/datum/mind/antag in current_antagonists)
if(I.icon_state == antag_indicator) if(antag.current && antag.current.client)
qdel(I) for(var/image/I in antag.current.client.images)
if(I.loc == player.current)
qdel(I)
/datum/antagonist/proc/update_current_antag_max() /datum/antagonist/proc/update_current_antag_max()
var/main_type var/main_type
if(ticker && ticker.mode) if(ticker && ticker.mode)
if(ticker.mode.antag_tag && ticker.mode.antag_tag == id) if(ticker.mode.antag_tags && (id in ticker.mode.antag_tags))
main_type = 1 main_type = 1
cur_max = (main_type ? max_antags_round : max_antags) cur_max = (main_type ? hard_cap_round : hard_cap)
if(ticker.mode.antag_scaling_coeff) if(ticker.mode.antag_scaling_coeff)
cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max) cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max)

View File

@@ -7,6 +7,12 @@ var/datum/antagonist/deathsquad/mercenary/commandos
role_text_plural = "Commandos" role_text_plural = "Commandos"
welcome_text = "You are in the employ of a criminal syndicate hostile to NanoTrasen." welcome_text = "You are in the employ of a criminal syndicate hostile to NanoTrasen."
hard_cap = 4
hard_cap_round = 8
initial_spawn_req = 4
initial_spawn_target = 6
/datum/antagonist/deathsquad/mercenary/New() /datum/antagonist/deathsquad/mercenary/New()
..(1) ..(1)
commandos = src commandos = src

View File

@@ -8,9 +8,13 @@ var/datum/antagonist/deathsquad/deathsquad
welcome_text = "You work in the service of Central Command Asset Protection, answering directly to the Board of Directors." welcome_text = "You work in the service of Central Command Asset Protection, answering directly to the Board of Directors."
landmark_id = "Commando" landmark_id = "Commando"
flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER
max_antags = 4
max_antags_round = 6
default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage) default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
hard_cap = 4
hard_cap_round = 8
initial_spawn_req = 4
initial_spawn_target = 6
var/deployed = 0 var/deployed = 0
/datum/antagonist/deathsquad/New(var/no_reference) /datum/antagonist/deathsquad/New(var/no_reference)

View File

@@ -8,12 +8,14 @@ var/datum/antagonist/ert/ert
role_text_plural = "Emergency Responders" role_text_plural = "Emergency Responders"
welcome_text = "As member of the Emergency Response Team, you answer only to your leader and CentComm officials." welcome_text = "As member of the Emergency Response Team, you answer only to your leader and CentComm officials."
leader_welcome_text = "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however." leader_welcome_text = "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however."
max_antags = 5
max_antags_round = 5 // ERT mode?
landmark_id = "Response Team" landmark_id = "Response Team"
flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER | ANTAG_CHOOSE_NAME
hard_cap = 5
hard_cap_round = 7
initial_spawn_req = 5
initial_spawn_target = 7
/datum/antagonist/ert/create_default(var/mob/source) /datum/antagonist/ert/create_default(var/mob/source)
var/mob/living/carbon/human/M = ..() var/mob/living/carbon/human/M = ..()
if(istype(M)) M.age = rand(25,45) if(istype(M)) M.age = rand(25,45)

View File

@@ -5,15 +5,19 @@ var/datum/antagonist/mercenary/mercs
role_type = BE_OPERATIVE role_type = BE_OPERATIVE
role_text = "Mercenary" role_text = "Mercenary"
bantype = "operative" bantype = "operative"
antag_indicator = "synd"
role_text_plural = "Mercenaries" role_text_plural = "Mercenaries"
landmark_id = "Syndicate-Spawn" landmark_id = "Syndicate-Spawn"
leader_welcome_text = "You are the leader of the mercenary strikeforce; hail to the chief. Use :t to speak to your underlings." leader_welcome_text = "You are the leader of the mercenary strikeforce; hail to the chief. Use :t to speak to your underlings."
welcome_text = "To speak on the strike team's private channel use :t." welcome_text = "To speak on the strike team's private channel use :t."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER
max_antags = 4
max_antags_round = 6
id_type = /obj/item/weapon/card/id/syndicate id_type = /obj/item/weapon/card/id/syndicate
hard_cap = 4
hard_cap_round = 8
initial_spawn_req = 4
initial_spawn_target = 6
/datum/antagonist/mercenary/New() /datum/antagonist/mercenary/New()
..() ..()
mercs = src mercs = src
@@ -44,14 +48,6 @@ var/datum/antagonist/mercenary/mercs
create_radio(SYND_FREQ, player) create_radio(SYND_FREQ, player)
return 1 return 1
/datum/antagonist/mercenary/place_all_mobs()
var/spawnpos = 1
for(var/datum/mind/player in current_antagonists)
player.current.loc = starting_locations[spawnpos]
spawnpos++
if(spawnpos > starting_locations.len)
spawnpos = 1
/datum/antagonist/mercenary/create_nuke() /datum/antagonist/mercenary/create_nuke()
..() ..()
// Create the radio. // Create the radio.

View File

@@ -9,8 +9,12 @@ var/datum/antagonist/ninja/ninjas
landmark_id = "ninjastart" landmark_id = "ninjastart"
welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor.</span>" welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor.</span>"
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
max_antags = 1
max_antags_round = 1 initial_spawn_req = 1
initial_spawn_target = 1
hard_cap = 1
hard_cap_round = 3
id_type = /obj/item/weapon/card/id/syndicate id_type = /obj/item/weapon/card/id/syndicate
/datum/antagonist/ninja/New() /datum/antagonist/ninja/New()

View File

@@ -6,11 +6,16 @@ var/datum/antagonist/raider/raiders
role_text = "Raider" role_text = "Raider"
role_text_plural = "Raiders" role_text_plural = "Raiders"
bantype = "raider" bantype = "raider"
antag_indicator = "mutineer"
landmark_id = "voxstart" landmark_id = "voxstart"
welcome_text = "Use :H to talk on your encrypted channel." welcome_text = "Use :H to talk on your encrypted channel."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER
max_antags = 6
max_antags_round = 10 hard_cap = 6
hard_cap_round = 10
initial_spawn_req = 4
initial_spawn_target = 6
id_type = /obj/item/weapon/card/id/syndicate id_type = /obj/item/weapon/card/id/syndicate
// Heist overrides check_victory() and doesn't need victory or loss strings/tags. // Heist overrides check_victory() and doesn't need victory or loss strings/tags.

View File

@@ -9,8 +9,12 @@ var/datum/antagonist/wizard/wizards
landmark_id = "wizard" landmark_id = "wizard"
welcome_text = "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.<br>In your pockets you will find a teleport scroll. Use it as needed." welcome_text = "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.<br>In your pockets you will find a teleport scroll. Use it as needed."
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE
max_antags = 1
max_antags_round = 1 hard_cap = 1
hard_cap_round = 3
initial_spawn_req = 1
initial_spawn_target = 1
/datum/antagonist/wizard/New() /datum/antagonist/wizard/New()
..() ..()

View File

@@ -22,10 +22,12 @@ var/datum/antagonist/cultist/cult
victory_feedback_tag = "win - cult win" victory_feedback_tag = "win - cult win"
loss_feedback_tag = "loss - staff stopped the cult" loss_feedback_tag = "loss - staff stopped the cult"
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
max_antags = 200 // No upper limit. hard_cap = 5
max_antags_round = 200 hard_cap_round = 6
var/allow_narsie = 1 initial_spawn_req = 4
initial_spawn_target = 6
var/allow_narsie = 1
var/datum/mind/sacrifice_target var/datum/mind/sacrifice_target
var/list/startwords = list("blood","join","self","hell") var/list/startwords = list("blood","join","self","hell")
var/list/allwords = list("travel","self","see","hell","blood","join","tech","destroy", "other", "hide") var/list/allwords = list("travel","self","see","hell","blood","join","tech","destroy", "other", "hide")

View File

@@ -6,8 +6,11 @@ var/datum/antagonist/highlander/highlanders
welcome_text = "There can be only one." welcome_text = "There can be only one."
id = MODE_HIGHLANDER id = MODE_HIGHLANDER
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE //| ANTAG_RANDSPAWN | ANTAG_VOTABLE // Someday... flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE //| ANTAG_RANDSPAWN | ANTAG_VOTABLE // Someday...
max_antags = 5
max_antags_round = 7 hard_cap = 5
hard_cap_round = 7
initial_spawn_req = 3
initial_spawn_target = 5
/datum/antagonist/highlander/New() /datum/antagonist/highlander/New()
..() ..()

View File

@@ -0,0 +1,46 @@
var/datum/antagonist/loyalists/loyalists
/datum/antagonist/loyalists
id = MODE_LOYALIST
role_type = BE_LOYALIST
role_text = "Head Loyalist"
role_text_plural = "Loyalists"
bantype = "loyalist"
feedback_tag = "loyalist_objective"
antag_indicator = "loyal_head"
welcome_text = "You belong to the Company, body and soul. Preserve its interests against the conspirators amongst the crew."
victory_text = "The heads of staff remained at their posts! The loyalists win!"
loss_text = "The heads of staff did not stop the revolution!"
victory_feedback_tag = "win - rev heads killed"
loss_feedback_tag = "loss - heads killed"
flags = 0
hard_cap = 2
hard_cap_round = 4
initial_spawn_req = 2
initial_spawn_target = 4
// Inround loyalists.
faction_role_text = "Loyalist"
faction_descriptor = "Company"
faction_verb = /mob/living/proc/convert_to_loyalist
faction_welcome = "Preserve NanoTrasen's interests against the traitorous recidivists amongst the crew. Protect the heads of staff with your life."
faction_indicator = "loyal"
faction_invisible = 1
restricted_jobs = list("AI", "Cyborg")
/datum/antagonist/loyalists/New()
..()
loyalists = src
/datum/antagonist/loyalists/create_global_objectives()
if(!..())
return
global_objectives = list()
for(var/mob/living/carbon/human/player in mob_list)
if(!player.mind || player.stat==2 || !(player.mind.assigned_role in command_positions))
continue
var/datum/objective/protect/loyal_obj = new
loyal_obj.target = player.mind
loyal_obj.explanation_text = "Protect [player.real_name], the [player.mind.assigned_role]."
global_objectives += loyal_obj

View File

@@ -6,30 +6,28 @@ var/datum/antagonist/renegade/renegades
welcome_text = "Your own safety matters above all else, trust no one and kill anyone who gets in your way. However, armed as you are, now would be the perfect time to settle that score or grab that pair of yellow gloves you've been eyeing..." welcome_text = "Your own safety matters above all else, trust no one and kill anyone who gets in your way. However, armed as you are, now would be the perfect time to settle that score or grab that pair of yellow gloves you've been eyeing..."
id = MODE_RENEGADE id = MODE_RENEGADE
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
max_antags = 5 hard_cap = 5
max_antags_round = 7 hard_cap_round = 7
hard_cap = 8
hard_cap_round = 12
initial_spawn_req = 3
initial_spawn_target = 6
var/list/spawn_guns = list( var/list/spawn_guns = list(
/obj/item/weapon/gun/energy/taser,
/obj/item/weapon/gun/energy/gun, /obj/item/weapon/gun/energy/gun,
/obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/laser,
/obj/item/weapon/gun/projectile, /obj/item/weapon/gun/projectile,
/obj/item/weapon/gun/projectile/revolver/detective, /obj/item/weapon/gun/projectile/revolver/detective,
/obj/item/weapon/gun/projectile/automatic/c20r, /obj/item/weapon/gun/projectile/automatic/c20r,
/obj/item/weapon/gun/energy/gun/nuclear,
/obj/item/weapon/gun/projectile/deagle/camo, /obj/item/weapon/gun/projectile/deagle/camo,
/obj/item/weapon/gun/projectile/pistol, /obj/item/weapon/gun/projectile/pistol,
/obj/item/weapon/silencer, /obj/item/weapon/silencer,
/obj/item/weapon/gun/energy/lasercannon,
/obj/item/weapon/gun/projectile/shotgun/pump, /obj/item/weapon/gun/projectile/shotgun/pump,
/obj/item/weapon/gun/projectile/shotgun/pump/combat, /obj/item/weapon/gun/projectile/shotgun/pump/combat,
/obj/item/weapon/gun/projectile/automatic, /obj/item/weapon/gun/projectile/automatic,
/obj/item/weapon/gun/projectile/automatic/mini_uzi, /obj/item/weapon/gun/projectile/automatic/mini_uzi,
/obj/item/weapon/gun/energy/crossbow /obj/item/weapon/gun/energy/crossbow
//obj/item/weapon/gun/projectile/gyropistol,
//obj/item/weapon/gun/energy/pulse_rifle,
//obj/item/weapon/gun/projectile/revolver/mateba,
//obj/item/weapon/gun/projectile/automatic/l6_saw,
) )
/datum/antagonist/renegade/New() /datum/antagonist/renegade/New()

View File

@@ -3,196 +3,46 @@ var/datum/antagonist/revolutionary/revs
/datum/antagonist/revolutionary /datum/antagonist/revolutionary
id = MODE_REVOLUTIONARY id = MODE_REVOLUTIONARY
role_type = BE_REV role_type = BE_REV
role_text = "Revolutionary" role_text = "Head Revolutionary"
role_text_plural = "Revolutionaries" role_text_plural = "Revolutionaries"
bantype = "revolutionary" bantype = "revolutionary"
feedback_tag = "rev_objective" feedback_tag = "rev_objective"
restricted_jobs = list("Internal Affairs Agent", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") antag_indicator = "rev_head"
protected_jobs = list("Security Officer", "Warden", "Detective") welcome_text = "Down with the capitalists! Down with the Bourgeoise!"
antag_indicator = "rev"
welcome_text = "The flash in your possession will help you to persuade the crew to join your cause."
victory_text = "The heads of staff were relieved of their posts! The revolutionaries win!" victory_text = "The heads of staff were relieved of their posts! The revolutionaries win!"
loss_text = "The heads of staff managed to stop the revolution!" loss_text = "The heads of staff managed to stop the revolution!"
victory_feedback_tag = "win - heads killed" victory_feedback_tag = "win - heads killed"
loss_feedback_tag = "loss - rev heads killed" loss_feedback_tag = "loss - rev heads killed"
flags = ANTAG_SUSPICIOUS | ANTAG_VOTABLE flags = ANTAG_SUSPICIOUS | ANTAG_VOTABLE
max_antags = 200 // No upper limit.
max_antags_round = 200
var/list/head_revolutionaries = list() hard_cap = 2
hard_cap_round = 4
initial_spawn_req = 2
initial_spawn_target = 4
//Inround revs.
faction_role_text = "Revolutionary"
faction_descriptor = "Revolution"
faction_verb = /mob/living/proc/convert_to_rev
faction_welcome = "Help the cause overturn the ruling class. Do not harm your fellow freedom fighters."
faction_indicator = "rev"
faction_invisible = 1
restricted_jobs = list("Internal Affairs Agent", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
protected_jobs = list("Security Officer", "Warden", "Detective")
/datum/antagonist/revolutionary/New() /datum/antagonist/revolutionary/New()
..() ..()
revs = src revs = src
/datum/antagonist/revolutionary/is_antagonist(var/datum/mind/player)
if(..() || (player in head_revolutionaries))
return 1
return 0
/datum/antagonist/revolutionary/equip(mob/living/carbon/human/mob)
if(!..())
return 0
if(!config.rp_rev)
mob.verbs |= /mob/living/carbon/human/proc/convert_to_rev
return
var/obj/item/device/flash/T = new(mob)
var/list/slots = list (
"backpack" = slot_in_backpack,
"left pocket" = slot_l_store,
"right pocket" = slot_r_store,
"left hand" = slot_l_hand,
"right hand" = slot_r_hand,
)
mob.equip_in_one_of_slots(T, slots)
/*
datum/antagonist/revolutionary/finalize(var/datum/mind/target)
if(target)
return ..(target)
current_antagonists |= head_revolutionaries
create_global_objectives()
..()
/datum/antagonist/revolutionary/get_additional_check_antag_output(var/datum/admins/caller)
return ..() //Todo
Rev extras:
dat += "<br><table cellspacing=5><tr><td><B>Revolutionaries</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.head_revolutionaries)
var/mob/M = N.current
if(!M)
dat += "<tr><td><i>Head Revolutionary not found!</i></td></tr>"
else
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
for(var/datum/mind/N in ticker.mode.revolutionaries)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
for(var/datum/mind/N in ticker.mode.get_living_heads())
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
var/turf/mob_loc = get_turf(M)
dat += "<td>[mob_loc.loc]</td></tr>"
else
dat += "<tr><td><i>Head not found!</i></td></tr>"
*/
/datum/antagonist/revolutionary/create_global_objectives() /datum/antagonist/revolutionary/create_global_objectives()
if(!..()) if(!..())
return return
global_objectives = list() global_objectives = list()
for(var/mob/living/carbon/human/player in mob_list)
for(var/datum/mind/head_mind in get_living_heads()) if(!player.mind || player.stat==2 || !(player.mind.assigned_role in command_positions))
var/datum/objective/mutiny/rev_obj = new continue
rev_obj.target = head_mind var/datum/objective/rev/rev_obj = new
rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]." rev_obj.target = player.mind
rev_obj.explanation_text = "Assassinate, capture or convert [player.real_name], the [player.mind.assigned_role]."
global_objectives += rev_obj global_objectives += rev_obj
/datum/antagonist/revolutionary/print_player_summary()
current_antagonists |= head_revolutionaries
if(!current_antagonists.len)
return
var/text = "<BR/><FONT size = 2><B>The [head_revolutionaries.len == 1 ? "Head Revolutionary was" : "Head Revolutionaries were"]:</B></FONT>"
for(var/datum/mind/ply in head_revolutionaries)
text += "<BR/><b>[ply.name]</b>"
world << text
..()
var/list/heads = list()
for(var/mob/player in mob_list)
if(player.mind && (player.mind.assigned_role in command_positions))
heads += player.mind
text = "<FONT size = 2><B>The heads of staff were:</B></FONT>"
for(var/datum/mind/head in heads)
text += "<br>[head.key] was [head.name] ("
if(head.current)
if(head.current.stat == DEAD)
text += "died"
else if(isNotStationLevel(head.current.z))
text += "fled the station"
else
text += "survived the revolution"
if(head.current.real_name != head.name)
text += " as [head.current.real_name]"
else
text += "body destroyed"
text += ")"
world << text
// This is a total redefine because headrevs are greeted differently to subrevs.
/datum/antagonist/revolutionary/add_antagonist(var/datum/mind/player, var/ignore_role)
if((player in current_antagonists) || (player in head_revolutionaries))
return 0
if(!can_become_antag(player, ignore_role))
return 0
current_antagonists |= player
player.current << "<span class='danger'><font size=3>You are a Revolutionary!</font></span>"
player.current << "<span class='danger'>Help the cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them overturn the ruling class!</span>"
player.special_role = "Revolutionary"
create_objectives(player)
show_objectives(player)
update_icons_added(player)
return 1
/datum/antagonist/revolutionary/remove_antagonist(datum/mind/player, var/show_message, var/implanted)
if(!..())
return
if(player in head_revolutionaries)
return
if(istype(player.current, /mob/living/carbon/brain))
player.current << "<span class='danger'>The frame's firmware detects and deletes your neural reprogramming! You remember nothing from the moment you were flashed until now.</span>"
if(show_message)
player.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.")
else
if(implanted)
player.current << "<span class='danger'>The nanobots in the loyalty implant remove all thoughts about being a revolutionary. Get back to work!</span>"
else
player.current << "<span class='danger'>You have been brainwashed! You are no longer a revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...</span>"
if(show_message)
player.current.visible_message("[player.current] looks like they just remembered their real allegiance!")
// Used by RP-rev.
/mob/living/carbon/human/proc/convert_to_rev(mob/M as mob in oview(src))
set name = "Convert Bourgeoise"
set category = "Abilities"
if(revs.is_antagonist(M.mind))
src << "<span class='danger'>\The [M] already serves the revolution.</span>"
return
if(!revs.can_become_antag(M.mind))
src << "<span class='danger'>\The [M] cannot be a revolutionary!</span>"
if(world.time < M.mind.rev_cooldown)
src << "<span class='danger'>You must wait five seconds between attempts.</span>"
return
src << "<span class='danger'>You are attempting to convert \the [M]...</span>"
log_admin("[src]([src.ckey]) attempted to convert [M].")
message_admins("<span class='danger'>[src]([src.ckey]) attempted to convert [M].</span>")
var/choice = alert(M,"Asked by [src]: Do you want to join the revolution?","Join the revolution?","No!","Yes!")
if(choice == "Yes!")
M << "<span class='notice'>You join the revolution!</span>"
src << "<span class='notice'>[M] joins the revolution!</span>"
revs.add_antagonist(M.mind, 0, 0, 1)
else if(choice == "No!")
M << "<span class='danger'>You reject this traitorous cause!</span>"
src << "<span class='danger'>\The [M] does not support the revolution!</span>"
M.mind.rev_cooldown = world.time+50

View File

@@ -11,8 +11,10 @@ var/datum/antagonist/rogue_ai/malf
victory_text = "The AI has taken control of all of the station's systems." victory_text = "The AI has taken control of all of the station's systems."
loss_text = "The AI has been shut down!" loss_text = "The AI has been shut down!"
flags = ANTAG_VOTABLE | ANTAG_OVERRIDE_MOB | ANTAG_OVERRIDE_JOB | ANTAG_CHOOSE_NAME flags = ANTAG_VOTABLE | ANTAG_OVERRIDE_MOB | ANTAG_OVERRIDE_JOB | ANTAG_CHOOSE_NAME
max_antags = 1 hard_cap = 1
max_antags_round = 1 hard_cap_round = 1
initial_spawn_req = 1
initial_spawn_target = 1
/datum/antagonist/rogue_ai/New() /datum/antagonist/rogue_ai/New()

View File

@@ -1,12 +1,10 @@
var/datum/antagonist/traitor/traitors var/datum/antagonist/traitor/traitors
// Inherits most of its vars from the base datum.
/datum/antagonist/traitor /datum/antagonist/traitor
id = MODE_TRAITOR id = MODE_TRAITOR
restricted_jobs = list("Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Captain")
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Captain")//AI", Currently out of the list as malf does not work for shit
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
max_antags = 200 // No upper limit.
max_antags_round = 200
/datum/antagonist/traitor/New() /datum/antagonist/traitor/New()
..() ..()

View File

@@ -18,7 +18,7 @@
for(var/antag_id in all_antag_types) for(var/antag_id in all_antag_types)
if(i > grab_antags) if(i > grab_antags)
break break
additional_antag_types |= antag_id antag_tags |= antag_id
i++ i++
..() ..()

View File

@@ -1,5 +1,4 @@
/datum/game_mode/changeling /datum/game_mode/changeling
antag_tag = MODE_CHANGELING
name = "changeling" name = "changeling"
round_description = "There are alien changelings on the station. Do not let the changelings succeed!" round_description = "There are alien changelings on the station. Do not let the changelings succeed!"
extended_round_description = "Life always finds a way. However, life can sometimes take a more disturbing route. Humanity's extensive knowledge of xeno-biological specimens has made them confident and arrogant. Yet something slipped past their eyes. Something dangerous. Something alive. Most frightening of all, however, is that this something is someone. An unknown alien specimen has incorporated itself into the crew of the NSS Exodus. Its unique biology allows it to manipulate its own or anyone else's DNA. With the ability to copy faces, voices, animals, but also change the chemical make up of your own body, its existence is a threat to not only your personal safety but the lives of everyone on board. No one knows where it came from. No one knows who it is or what it wants. One thing is for certain though... there is never just one of them. Good luck." extended_round_description = "Life always finds a way. However, life can sometimes take a more disturbing route. Humanity's extensive knowledge of xeno-biological specimens has made them confident and arrogant. Yet something slipped past their eyes. Something dangerous. Something alive. Most frightening of all, however, is that this something is someone. An unknown alien specimen has incorporated itself into the crew of the NSS Exodus. Its unique biology allows it to manipulate its own or anyone else's DNA. With the ability to copy faces, voices, animals, but also change the chemical make up of your own body, its existence is a threat to not only your personal safety but the lives of everyone on board. No one knows where it came from. No one knows who it is or what it wants. One thing is for certain though... there is never just one of them. Good luck."
@@ -9,3 +8,4 @@
required_enemies = 1 required_enemies = 1
end_on_antag_death = 1 end_on_antag_death = 1
antag_scaling_coeff = 10 antag_scaling_coeff = 10
antag_tags = list(MODE_CHANGELING)

View File

@@ -8,4 +8,4 @@
required_enemies = 3 required_enemies = 3
uplink_welcome = "Nar-Sie Uplink Console:" uplink_welcome = "Nar-Sie Uplink Console:"
end_on_antag_death = 1 end_on_antag_death = 1
antag_tag = MODE_CULTIST antag_tags = list(MODE_CULTIST)

View File

@@ -1,25 +1,5 @@
var/global/antag_add_failed // Used in antag type voting. var/global/antag_add_failed // Used in antag type voting.
var/global/list/additional_antag_types = list() var/global/list/additional_antag_types = list()
///////////////////////////////////
//Keeps track of all living heads//
///////////////////////////////////
/proc/get_living_heads()
var/list/heads = list()
for(var/mob/living/carbon/human/player in mob_list)
if(player.stat!=2 && player.mind && (player.mind.assigned_role in command_positions))
heads += player.mind
return heads
/*
* GAMEMODES (by Rastaf0)
*
* In the new mode system all special roles are fully supported.
* You can have proper wizards/traitors/changelings/cultists during any mode.
* Only two things really depends on gamemode:
* 1. Starting roles, equipment and preparations
* 2. Conditions of finishing the round.
*
*/
/datum/game_mode /datum/game_mode
var/name = "invalid" var/name = "invalid"
@@ -40,11 +20,12 @@ var/global/list/additional_antag_types = list()
var/shuttle_delay = 1 // Shuttle transit time is multiplied by this. var/shuttle_delay = 1 // Shuttle transit time is multiplied by this.
var/auto_recall_shuttle = 0 // Will the shuttle automatically be recalled? var/auto_recall_shuttle = 0 // Will the shuttle automatically be recalled?
var/antag_tag // First (main) antag template to spawn. var/list/antag_tags = list() // Core antag templates to spawn.
var/list/antag_templates // Extra antagonist types to include. var/list/antag_templates // Extra antagonist types to include.
var/list/latejoin_templates = list() var/list/latejoin_templates = list()
var/round_autoantag = 0 // Will this round attempt to periodically spawn more antagonists? var/round_autoantag = 0 // Will this round attempt to periodically spawn more antagonists?
var/antag_scaling_coeff = 5 // Coefficient for scaling max antagonists to player count. var/antag_scaling_coeff = 5 // Coefficient for scaling max antagonists to player count.
var/require_all_templates = 0 // Will only start if all templates are checked and can spawn.
var/station_was_nuked = 0 // See nuclearbomb.dm and malfunction.dm. var/station_was_nuked = 0 // See nuclearbomb.dm and malfunction.dm.
var/explosion_in_progress = 0 // Sit back and relax var/explosion_in_progress = 0 // Sit back and relax
@@ -158,18 +139,18 @@ var/global/list/additional_antag_types = list()
shuttle_delay = choice shuttle_delay = choice
if("antag_scaling") if("antag_scaling")
choice = input("Enter a new antagonist cap scaling coefficient.") as num choice = input("Enter a new antagonist cap scaling coefficient.") as num
if(!choice || choice < 0 || choice > 100) if(isnull(choice) || choice < 0 || choice > 100)
return return
antag_scaling_coeff = choice antag_scaling_coeff = choice
if("event_modifier_moderate") if("event_modifier_moderate")
choice = input("Enter a new moderate event time modifier.") as num choice = input("Enter a new moderate event time modifier.") as num
if(!choice || choice < 0 || choice > 100) if(isnull(choice) || choice < 0 || choice > 100)
return return
event_delay_mod_moderate = choice event_delay_mod_moderate = choice
refresh_event_modifiers() refresh_event_modifiers()
if("event_modifier_severe") if("event_modifier_severe")
choice = input("Enter a new moderate event time modifier.") as num choice = input("Enter a new moderate event time modifier.") as num
if(!choice || choice < 0 || choice > 100) if(isnull(choice) || choice < 0 || choice > 100)
return return
event_delay_mod_major = choice event_delay_mod_major = choice
refresh_event_modifiers() refresh_event_modifiers()
@@ -183,7 +164,7 @@ var/global/list/additional_antag_types = list()
usr.client.debug_variables(antag) usr.client.debug_variables(antag)
message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.") message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.")
else if(href_list["remove_antag_type"]) else if(href_list["remove_antag_type"])
if(antag_tag && href_list["remove_antag_type"] == antag_tag) if(antag_tags && (href_list["remove_antag_type"] in antag_tags))
usr << "Cannot remove core mode antag type." usr << "Cannot remove core mode antag type."
return return
var/datum/antagonist/antag = all_antag_types[href_list["remove_antag_type"]] var/datum/antagonist/antag = all_antag_types[href_list["remove_antag_type"]]
@@ -197,14 +178,15 @@ var/global/list/additional_antag_types = list()
return return
var/datum/antagonist/antag = all_antag_types[choice] var/datum/antagonist/antag = all_antag_types[choice]
if(antag) if(antag)
additional_antag_types |= antag ticker.mode.antag_templates |= antag
message_admins("Admin [key_name_admin(usr)] added [antag.role_text] template to game mode.") message_admins("Admin [key_name_admin(usr)] added [antag.role_text] template to game mode.")
// I am very sure there's a better way to do this, but I'm not sure what it might be. ~Z // I am very sure there's a better way to do this, but I'm not sure what it might be. ~Z
for(var/datum/admins/admin in world) spawn(1)
if(usr.client == admin.owner) for(var/datum/admins/admin in world)
admin.show_game_mode(usr) if(usr.client == admin.owner)
return admin.show_game_mode(usr)
return
/datum/game_mode/proc/announce() //to be called when round starts /datum/game_mode/proc/announce() //to be called when round starts
world << "<B>The current game mode is [capitalize(name)]!</B>" world << "<B>The current game mode is [capitalize(name)]!</B>"
@@ -245,15 +227,23 @@ var/global/list/additional_antag_types = list()
if(!(antag_templates && antag_templates.len)) if(!(antag_templates && antag_templates.len))
return 1 return 1
var/datum/antagonist/main_antags = antag_templates[1] var/enemy_count = 0
var/list/potential if(antag_tags && antag_tags.len)
if(main_antags.flags & ANTAG_OVERRIDE_JOB) for(var/antag_tag in antag_tags)
potential = main_antags.pending_antagonists var/datum/antagonist/antag = all_antag_types[antag_tag]
else if(!antag)
potential = main_antags.candidates continue
var/list/potential = list()
if(potential.len >= required_enemies) if(antag.flags & ANTAG_OVERRIDE_JOB)
return 1 potential = antag.pending_antagonists
else
potential = antag.candidates
if(islist(potential))
if(require_all_templates && potential.len < antag.initial_spawn_req)
return 0
enemy_count += potential.len
if(enemy_count >= required_enemies)
return 1
return 0 return 0
/datum/game_mode/proc/refresh_event_modifiers() /datum/game_mode/proc/refresh_event_modifiers()
@@ -550,11 +540,13 @@ var/global/list/additional_antag_types = list()
if(!config.traitor_scaling) if(!config.traitor_scaling)
antag_scaling_coeff = 0 antag_scaling_coeff = 0
if(antag_tag) if(antag_tags && antag_tags.len)
antag_templates = list() antag_templates = list()
var/datum/antagonist/antag = all_antag_types[antag_tag] for(var/antag_tag in antag_tags)
if(antag) var/datum/antagonist/antag = all_antag_types[antag_tag]
antag_templates |= antag if(antag)
antag_templates |= antag
if(additional_antag_types && additional_antag_types.len) if(additional_antag_types && additional_antag_types.len)
if(!antag_templates) if(!antag_templates)
antag_templates = list() antag_templates = list()
@@ -563,15 +555,6 @@ var/global/list/additional_antag_types = list()
if(antag) if(antag)
antag_templates |= antag antag_templates |= antag
/*
if(antag_templates && antag_templates.len)
for(var/datum/antagonist/antag in antag_templates)
if(antag.flags & (ANTAG_OVERRIDE_JOB|ANTAG_RANDSPAWN))
continue
antag_templates -= antag
world << "<span class='danger'>[antag.role_text_plural] are invalid for additional roundtype antags!</span>"
*/
newscaster_announcements = pick(newscaster_standard_feeds) newscaster_announcements = pick(newscaster_standard_feeds)
/datum/game_mode/proc/check_victory() /datum/game_mode/proc/check_victory()

View File

@@ -1,7 +1,12 @@
/datum/game_mode/var/next_spawn = 0
/datum/game_mode/var/min_autotraitor_delay = 4200 // Approx 7 minutes.
/datum/game_mode/var/max_autotraitor_delay = 12000 // Approx 20 minutes.
/datum/game_mode/proc/get_usable_templates(var/list/supplied_templates) /datum/game_mode/proc/get_usable_templates(var/list/supplied_templates)
var/list/usable_templates = list() var/list/usable_templates = list()
for(var/datum/antagonist/A in supplied_templates) for(var/datum/antagonist/A in supplied_templates)
if(A.can_late_spawn()) if(A.can_late_spawn())
message_admins("AUTO[uppertext(name)]: [A.id] selected for spawn attempt.")
usable_templates |= A usable_templates |= A
return usable_templates return usable_templates
@@ -21,23 +26,27 @@
if(emergency_shuttle.departed || !round_autoantag) if(emergency_shuttle.departed || !round_autoantag)
return return
if(!prob(get_antag_prob())) if(world.time < next_spawn)
return return
message_admins("AUTO[uppertext(name)]: Attempting spawn.")
var/list/usable_templates var/list/usable_templates
if(latejoin_only && latejoin_templates.len) if(latejoin_only && latejoin_templates.len)
usable_templates = get_usable_templates(latejoin_templates) usable_templates = get_usable_templates(latejoin_templates)
else if (antag_templates.len) else if (antag_templates && antag_templates.len)
usable_templates = get_usable_templates(antag_templates) usable_templates = get_usable_templates(antag_templates)
else else
message_admins("AUTO[uppertext(name)]: Failed to find configured mode spawn templates, please disable auto-antagonists until one is added.")
round_autoantag = 0
return return
if(usable_templates.len)
var/datum/antagonist/spawn_antag = pick(usable_templates)
spawn_antag.attempt_late_spawn(player)
/datum/game_mode/proc/get_antag_prob() while(usable_templates.len)
var/player_count = 0 var/datum/antagonist/spawn_antag = pick(usable_templates)
for(var/mob/living/M in mob_list) usable_templates -= spawn_antag
if(M.client) if(spawn_antag.attempt_late_spawn(player))
player_count += 1 message_admins("AUTO[uppertext(name)]: Attempting to latespawn [spawn_antag.id]. ([spawn_antag.get_antag_count()]/[spawn_antag.cur_max])")
return min(100,max(0,(player_count - 5 * 10) * 5)) next_spawn = world.time + rand(min_autotraitor_delay, max_autotraitor_delay)
return
message_admins("AUTO[uppertext(name)]: Failed to proc a viable spawn template.")
next_spawn = world.time + rand(min_autotraitor_delay, max_autotraitor_delay)

View File

@@ -5,7 +5,6 @@ VOX HEIST ROUNDTYPE
var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' objective. Clumsy, rewrite sometime. var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' objective. Clumsy, rewrite sometime.
/datum/game_mode/heist /datum/game_mode/heist
antag_tag = MODE_RAIDER
name = "heist" name = "heist"
config_tag = "heist" config_tag = "heist"
required_players = 15 required_players = 15
@@ -13,6 +12,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
required_enemies = 4 required_enemies = 4
round_description = "An unidentified bluespace signature has slipped past the Icarus and is approaching the station!" round_description = "An unidentified bluespace signature has slipped past the Icarus and is approaching the station!"
end_on_antag_death = 1 end_on_antag_death = 1
antag_tags = list(MODE_RAIDER)
/datum/game_mode/heist/check_finished() /datum/game_mode/heist/check_finished()
if(!..()) if(!..())

View File

@@ -9,4 +9,4 @@
required_enemies = 1 required_enemies = 1
end_on_antag_death = 0 end_on_antag_death = 0
auto_recall_shuttle = 0 auto_recall_shuttle = 0
antag_tag = MODE_MALFUNCTION antag_tags = list(MODE_MALFUNCTION)

View File

@@ -2,9 +2,9 @@
name = "ninja" name = "ninja"
round_description = "An agent of the Spider Clan is onboard the station!" round_description = "An agent of the Spider Clan is onboard the station!"
extended_round_description = "What was that?! Was that a person or did your eyes just play tricks on you? You have no idea. That slim-suited, cryptic individual is an enigma to you and all of your knowledge. Their purpose is unknown. Their mission is unknown. How they arrived to this secure and isolated section of the galaxy, you don't know. What you do know is that there is a silent shadow-stalker piercing through the defenses of Nanotrasen with technological capabilities eons ahead of your time. They can avoid the omniscience of the AI and rival the most hardened weapons your station is capable of. Tread lightly and only hope this unknown assassin isn't here for you." extended_round_description = "What was that?! Was that a person or did your eyes just play tricks on you? You have no idea. That slim-suited, cryptic individual is an enigma to you and all of your knowledge. Their purpose is unknown. Their mission is unknown. How they arrived to this secure and isolated section of the galaxy, you don't know. What you do know is that there is a silent shadow-stalker piercing through the defenses of Nanotrasen with technological capabilities eons ahead of your time. They can avoid the omniscience of the AI and rival the most hardened weapons your station is capable of. Tread lightly and only hope this unknown assassin isn't here for you."
antag_tag = MODE_NINJA
config_tag = "ninja" config_tag = "ninja"
required_players = 1 required_players = 1
required_players_secret = 10 required_players_secret = 10
required_enemies = 1 required_enemies = 1
end_on_antag_death = 1 end_on_antag_death = 1
antag_tags = list(MODE_NINJA)

View File

@@ -10,12 +10,11 @@
required_players_secret = 25 // 25 players - 5 players to be the nuke ops = 20 players remaining required_players_secret = 25 // 25 players - 5 players to be the nuke ops = 20 players remaining
required_enemies = 1 required_enemies = 1
end_on_antag_death = 1 end_on_antag_death = 1
antag_tag = MODE_MERCENARY
uplink_welcome = "Corporate Backed Uplink Console:" uplink_welcome = "Corporate Backed Uplink Console:"
uplink_uses = 40 uplink_uses = 40
var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station
var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level
antag_tags = list(MODE_MERCENARY)
/datum/game_mode/nuclear/declare_completion() /datum/game_mode/nuclear/declare_completion()
if(config.objectives_disabled) if(config.objectives_disabled)

View File

@@ -64,69 +64,6 @@ datum/objective/assassinate
return 1 return 1
datum/objective/mutiny
find_target()
..()
if(target && target.current)
explanation_text = "Assassinate [target.current.real_name], the [target.assigned_role]."
else
explanation_text = "Free Objective"
return target
find_target_by_role(role, role_type=0)
..(role, role_type)
if(target && target.current)
explanation_text = "Assassinate [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]."
else
explanation_text = "Free Objective"
return target
check_completion()
if(target && target.current)
if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey)
return 1
var/turf/T = get_turf(target.current)
if(T && isNotStationLevel(T.z)) //If they leave the station they count as dead for this
return 2
return 0
return 1
datum/objective/mutiny/rp
find_target()
..()
if(target && target.current)
explanation_text = "Assassinate, capture or convert [target.current.real_name], the [target.assigned_role]."
else
explanation_text = "Free Objective"
return target
find_target_by_role(role, role_type=0)
..(role, role_type)
if(target && target.current)
explanation_text = "Assassinate, capture or convert [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]."
else
explanation_text = "Free Objective"
return target
// less violent rev objectives
check_completion()
var/rval = 1
if(target && target.current)
//assume that only carbon mobs can become rev heads for now
if(target.current.stat == DEAD || target.current:handcuffed || !ishuman(target.current))
return 1
// Check if they're converted
if(target in revs.head_revolutionaries)
return 1
var/turf/T = get_turf(target.current)
if(T && isNotStationLevel(T.z)) //If they leave the station they count as dead for this
rval = 2
return 0
return rval
datum/objective/anti_revolution/execute datum/objective/anti_revolution/execute
find_target() find_target()
..() ..()
@@ -933,3 +870,38 @@ datum/objective/heist/salvage
/datum/objective/cult/sacrifice/check_completion() /datum/objective/cult/sacrifice/check_completion()
return (target && cult && !cult.sacrificed.Find(target)) return (target && cult && !cult.sacrificed.Find(target))
/datum/objective/rev/find_target()
..()
if(target && target.current)
explanation_text = "Assassinate, capture or convert [target.current.real_name], the [target.assigned_role]."
else
explanation_text = "Free Objective"
return target
/datum/objective/rev/find_target_by_role(role, role_type=0)
..(role, role_type)
if(target && target.current)
explanation_text = "Assassinate, capture or convert [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]."
else
explanation_text = "Free Objective"
return target
/datum/objective/rev/check_completion()
var/rval = 1
if(target && target.current)
var/mob/living/carbon/human/H = target.current
if(!istype(H))
return 1
if(H.stat == DEAD || H.restrained())
return 1
// Check if they're converted
if(target in revs.current_antagonists)
return 1
var/turf/T = get_turf(H)
if(T && isNotStationLevel(T.z)) //If they leave the station they count as dead for this
rval = 2
return 0
return rval

View File

@@ -2,7 +2,7 @@
name = "Revolution" name = "Revolution"
config_tag = "revolution" config_tag = "revolution"
round_description = "Some crewmembers are attempting to start a revolution!" round_description = "Some crewmembers are attempting to start a revolution!"
extended_round_description = "Revolutionaries - Kill the Captain, HoP, HoS, CE, RD and CMO. Convert other crewmembers (excluding the heads of staff, and security officers) to your cause by flashing them. Protect your leaders.<BR>\nPersonnel - Protect the heads of staff. Kill the leaders of the revolution, and brainwash the other revolutionaries (by beating them in the head)." extended_round_description = "Revolutionaries - Remove the heads of staff from power. Convert other crewmembers to your cause using the 'Convert Bourgeoise' verb. Protect your leaders."
required_players = 4 required_players = 4
required_players_secret = 15 required_players_secret = 15
required_enemies = 3 required_enemies = 3
@@ -11,40 +11,5 @@
uplink_uses = 10 uplink_uses = 10
end_on_antag_death = 1 end_on_antag_death = 1
shuttle_delay = 3 shuttle_delay = 3
antag_tag = MODE_REVOLUTIONARY antag_tags = list(MODE_REVOLUTIONARY, MODE_LOYALIST)
require_all_templates = 1
/datum/game_mode/revolution/New()
if(config && config.rp_rev)
extended_round_description = "Revolutionaries - Remove the heads of staff from power. Convert other crewmembers to your cause using the 'Convert Bourgeoise' verb. Protect your leaders."
/datum/game_mode/revolution/send_intercept()
..()
if(config.announce_revheads)
spawn(54000)
var/intercepttext = ""
command_announcement.Announce("Summary downloaded and printed out at all communications consoles.", "Local agitators have been determined.")
intercepttext = "<FONT size = 3><B>Cent. Com. Update</B> Requested status information:</FONT><HR>"
intercepttext += "We have determined several members of your staff to be political activists. They are:"
for(var/datum/mind/revmind in revs.head_revolutionaries)
intercepttext += "<br>[revmind.current.real_name]"
intercepttext += "<br>Please arrest them at once."
for (var/obj/machinery/computer/communications/comm in world)
if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept)
var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc )
intercept.name = "Cent. Com. Status Summary"
intercept.info = intercepttext
comm.messagetitle.Add("Cent. Com. Status Summary")
comm.messagetext.Add(intercepttext)
spawn(12000)
command_announcement.Announce("Repeating the previous message over intercoms due to urgency. The station has political agitators onboard by the names of [reveal_rev_heads()], please arrest them at once.", "Local agitators have been determined.")
/datum/game_mode/revolution/proc/reveal_rev_heads()
. = ""
for(var/i = 1, i <= revs.head_revolutionaries.len,i++)
var/datum/mind/revmind = revs.head_revolutionaries[i]
if(i < revs.head_revolutionaries.len)
. += "[revmind.current.real_name],"
else
. += "and [revmind.current.real_name]"

View File

@@ -7,5 +7,11 @@
required_enemies = 1 required_enemies = 1
uplink_welcome = "AntagCorp Portable Teleportation Relay:" uplink_welcome = "AntagCorp Portable Teleportation Relay:"
end_on_antag_death = 1 end_on_antag_death = 1
antag_tags = list(MODE_TRAITOR)
antag_scaling_coeff = 10 antag_scaling_coeff = 10
antag_tag = MODE_TRAITOR
/datum/game_mode/traitor/auto
name = "autotraitor"
config_tag = "autotraitor"
round_autoantag = 1
antag_scaling_coeff = 1

View File

@@ -9,4 +9,4 @@
uplink_welcome = "Wizardly Uplink Console:" uplink_welcome = "Wizardly Uplink Console:"
uplink_uses = 10 uplink_uses = 10
end_on_antag_death = 1 end_on_antag_death = 1
antag_tag = MODE_WIZARD antag_tags = list(MODE_WIZARD)

View File

@@ -137,8 +137,7 @@
return return
if(M.brainmob.mind) if(M.brainmob.mind)
cult.remove_antagonist(M.brainmob.mind, 1) clear_antag_roles(M.brainmob.mind, 1)
revs.remove_antagonist(M.brainmob.mind, 1)
user.drop_item() user.drop_item()
P.loc = src P.loc = src

View File

@@ -341,20 +341,10 @@
for(var/datum/objective/O in all_objectives) for(var/datum/objective/O in all_objectives)
// We don't want revs to get objectives that aren't for heads of staff. Letting // We don't want revs to get objectives that aren't for heads of staff. Letting
// them win or lose based on cryo is silly so we remove the objective. // them win or lose based on cryo is silly so we remove the objective.
if(istype(O,/datum/objective/mutiny) && O.target == occupant.mind) if(O.target == occupant.mind)
if(O.owner && O.owner.current)
O.owner.current << "<span class='warning'>You get the feeling your target is no longer within your reach...</span>"
qdel(O) qdel(O)
else if(O.target && istype(O.target,/datum/mind))
if(O.target == occupant.mind)
if(O.owner && O.owner.current)
O.owner.current << "<span class='warning'>You get the feeling your target is no longer within your reach. Time for Plan [pick(list("A","B","C","D","X","Y","Z"))]...</span>"
O.target = null
spawn(1) //This should ideally fire after the occupant is deleted.
if(!O) return
O.find_target()
if(!(O.target))
all_objectives -= O
O.owner.objectives -= O
qdel(O)
//Handle job slot/tater cleanup. //Handle job slot/tater cleanup.
var/job = occupant.mind.assigned_role var/job = occupant.mind.assigned_role

View File

@@ -70,7 +70,7 @@
flick("e_flash", M.flash) flick("e_flash", M.flash)
if(ishuman(M) && ishuman(user) && M.stat!=DEAD) if(ishuman(M) && ishuman(user) && M.stat!=DEAD)
if(user.mind && user.mind in revs.head_revolutionaries) if(user.mind && user.mind in revs.current_antagonists)
var/revsafe = 0 var/revsafe = 0
for(var/obj/item/weapon/implant/loyalty/L in M) for(var/obj/item/weapon/implant/loyalty/L in M)
if(L && L.implanted) if(L && L.implanted)

View File

@@ -211,10 +211,6 @@
user << "\red Sticking a dead [W] into the frame would sort of defeat the purpose." user << "\red Sticking a dead [W] into the frame would sort of defeat the purpose."
return return
if(M.brainmob.mind in revs.head_revolutionaries)
user << "\red The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W]."
return
if(jobban_isbanned(M.brainmob, "Cyborg")) if(jobban_isbanned(M.brainmob, "Cyborg"))
user << "\red This [W] does not seem to fit." user << "\red This [W] does not seem to fit."
return return

View File

@@ -42,10 +42,10 @@ client/verb/JoinResponseTeam()
set name = "Join Response Team" set name = "Join Response Team"
set category = "IC" set category = "IC"
if(!MayRespawn(1)) if(!MayRespawn(1))
usr << "<span class='warning'>You cannot join the response team at this time.</span>" usr << "<span class='warning'>You cannot join the response team at this time.</span>"
return return
if(istype(usr,/mob/dead/observer) || istype(usr,/mob/new_player)) if(istype(usr,/mob/dead/observer) || istype(usr,/mob/new_player))
if(!send_emergency_team) if(!send_emergency_team)
usr << "No emergency response team is currently being sent." usr << "No emergency response team is currently being sent."
@@ -53,7 +53,7 @@ client/verb/JoinResponseTeam()
if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer")) if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer"))
usr << "<font color=red><b>You are jobbanned from the emergency reponse team!" usr << "<font color=red><b>You are jobbanned from the emergency reponse team!"
return return
if(ert.current_antagonists.len >= ert.max_antags) if(ert.current_antagonists.len >= ert.hard_cap)
usr << "The emergency response team is already full!" usr << "The emergency response team is already full!"
return return
ert.create_default(usr) ert.create_default(usr)

View File

@@ -1160,30 +1160,27 @@ proc/admin_notice(var/message, var/rights)
out += "<hr>" out += "<hr>"
if(ticker.mode.antag_tag) if(ticker.mode.antag_tags && ticker.mode.antag_tags.len)
out += "<b>Core antag id:</b> <a href='?src=\ref[ticker.mode];debug_antag=[ticker.mode.antag_tag]'>[ticker.mode.antag_tag]</a>.</br>" out += "<b>Core antag templates:</b></br>"
for(var/antag_tag in ticker.mode.antag_tags)
out += "<a href='?src=\ref[ticker.mode];debug_antag=[antag_tag]'>[antag_tag]</a>.</br>"
if(ticker.mode.round_autoantag) if(ticker.mode.round_autoantag)
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>enabled</a></b> ([ticker.mode.get_antag_prob()]% spawn chance)" out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>enabled</a></b>."
if(ticker.mode.antag_scaling_coeff) if(ticker.mode.antag_scaling_coeff > 0)
out += " (scaling with <a href='?src=\ref[ticker.mode];set=antag_scaling'>[ticker.mode.antag_scaling_coeff]</a>)" out += " (scaling with <a href='?src=\ref[ticker.mode];set=antag_scaling'>[ticker.mode.antag_scaling_coeff]</a>)"
else
out += " (not currently scaling, <a href='?src=\ref[ticker.mode];set=antag_scaling'>set a coefficient</a>)"
out += "<br/>" out += "<br/>"
else else
out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>disabled</a></b>.<br/>" out += "<b>Autotraitor <a href='?src=\ref[ticker.mode];toggle=autotraitor'>disabled</a></b>.<br/>"
out += "<b>All antag ids:</b>" out += "<b>All antag ids:</b>"
if(ticker.mode.antag_templates && ticker.mode.antag_templates.len). if(ticker.mode.antag_templates && ticker.mode.antag_templates.len).
var/playercount = ticker.mode.num_players()
for(var/datum/antagonist/antag in ticker.mode.antag_templates) for(var/datum/antagonist/antag in ticker.mode.antag_templates)
var/cur_max_antags antag.update_current_antag_max()
if(ticker.mode.antag_tag && antag.id == ticker.mode.antag_tag)
cur_max_antags = antag.max_antags_round
else
cur_max_antags = antag.max_antags
if(ticker.mode.antag_scaling_coeff)
cur_max_antags = Clamp((playercount/ticker.mode.antag_scaling_coeff), 1, cur_max_antags)
out += " <a href='?src=\ref[ticker.mode];debug_antag=[antag.id]'>[antag.id]</a>" out += " <a href='?src=\ref[ticker.mode];debug_antag=[antag.id]'>[antag.id]</a>"
out += " ([antag.get_antag_count()]/[cur_max_antags]) " out += " ([antag.get_antag_count()]/[antag.cur_max]) "
out += " <a href='?src=\ref[ticker.mode];remove_antag_type=[antag.id]'>\[-\]</a><br/>" out += " <a href='?src=\ref[ticker.mode];remove_antag_type=[antag.id]'>\[-\]</a><br/>"
else else
out += " None." out += " None."
@@ -1365,3 +1362,46 @@ proc/admin_notice(var/message, var/rights)
tomob.ckey = frommob.ckey tomob.ckey = frommob.ckey
qdel(frommob) qdel(frommob)
return 1 return 1
/datum/admins/proc/force_antag_latespawn()
set category = "Admin"
set name = "Force Template Spawn"
set desc = "Force an antagonist template to spawn."
if (!istype(src,/datum/admins))
src = usr.client.holder
if (!istype(src,/datum/admins))
usr << "Error: you are not an admin!"
return
if(!ticker || !ticker.mode)
usr << "Mode has not started."
return
var/antag_type = input("Choose a template.","Force Latespawn") as null|anything in all_antag_types
if(!antag_type || !all_antag_types[antag_type])
usr << "Aborting."
return
var/datum/antagonist/antag = all_antag_types[antag_type]
message_admins("[key_name(usr)] attempting to force latespawn with template [antag.id].")
antag.attempt_late_spawn()
/datum/admins/proc/force_mode_latespawn()
set category = "Admin"
set name = "Force Mode Spawn"
set desc = "Force autotraitor to proc."
if (!istype(src,/datum/admins))
src = usr.client.holder
if (!istype(src,/datum/admins))
usr << "Error: you are not an admin!"
return
if(!ticker || !ticker.mode)
usr << "Mode has not started."
return
message_admins("[key_name(usr)] attempting to force mode latespawn.")
ticker.mode.next_spawn = 0
ticker.mode.try_latespawn()

View File

@@ -16,6 +16,8 @@ var/list/admin_verbs_admin = list(
/client/proc/invisimin, /*allows our mob to go invisible/visible*/ /client/proc/invisimin, /*allows our mob to go invisible/visible*/
// /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage // /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage
/datum/admins/proc/show_game_mode, /*Configuration window for the current game mode.*/ /datum/admins/proc/show_game_mode, /*Configuration window for the current game mode.*/
/datum/admins/proc/force_mode_latespawn, /*Force the mode to try a latespawn proc*/
/datum/admins/proc/force_antag_latespawn, /*Force a specific template to try a latespawn proc*/
/datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/ /datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/
/datum/admins/proc/toggleguests, /*toggles whether guests can join the current game*/ /datum/admins/proc/toggleguests, /*toggles whether guests can join the current game*/
/datum/admins/proc/announce, /*priority announce something to all clients.*/ /datum/admins/proc/announce, /*priority announce something to all clients.*/

View File

@@ -18,7 +18,7 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
"ninja" = "true", // 10 "ninja" = "true", // 10
"raider" = IS_MODE_COMPILED("heist"), // 11 "raider" = IS_MODE_COMPILED("heist"), // 11
"diona" = 1, // 12 "diona" = 1, // 12
"mutineer" = IS_MODE_COMPILED("mutiny"), // 13 "loyalist" = IS_MODE_COMPILED("revolution"), // 13
"pAI candidate" = 1, // -- TLE // 14 "pAI candidate" = 1, // -- TLE // 14
) )

View File

@@ -34,6 +34,11 @@
/mob/living/simple_animal/borer/roundstart /mob/living/simple_animal/borer/roundstart
roundstart = 1 roundstart = 1
/mob/living/simple_animal/borer/Login()
..()
if(mind)
borers.add_antagonist(mind)
/mob/living/simple_animal/borer/New() /mob/living/simple_animal/borer/New()
..() ..()
@@ -150,11 +155,7 @@
if(!host) return if(!host) return
if(host.mind) if(host.mind)
//If they're not a proper traitor, reset their antag status. borers.remove_antagonist(host.mind)
if(host.mind.special_role == "Borer Thrall")
host << "<span class ='danger'>You are no longer an antagonist.</span>"
borers.hosts -= host.mind
host.mind.special_role = null
src.loc = get_turf(host) src.loc = get_turf(host)

View File

@@ -109,15 +109,9 @@
//Update their traitor status. //Update their traitor status.
if(host.mind) if(host.mind)
if(!host.mind.special_role) borers.add_antagonist_mind(host.mind, 1, borers.faction_role_text, borers.faction_welcome)
borers.hosts |= host.mind
host.mind.special_role = "Borer Thrall"
host << "<span class='danger'>A creeping lassitude surrounds you. Your mind is being invaded by an alien intelligence and that's just fine.</span>"
host << "<span class = 'danger'>You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head.</span>"
show_generic_antag_text(host.mind)
if(istype(M,/mob/living/carbon/human)) if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M var/mob/living/carbon/human/H = M
var/obj/item/organ/I = H.internal_organs_by_name["brain"] var/obj/item/organ/I = H.internal_organs_by_name["brain"]
if(!I) // No brain organ, so the borer moves in and replaces it permanently. if(!I) // No brain organ, so the borer moves in and replaces it permanently.

View File

@@ -573,10 +573,9 @@
#define BE_NINJA 1024 #define BE_NINJA 1024
#define BE_RAIDER 2048 #define BE_RAIDER 2048
#define BE_PLANT 4096 #define BE_PLANT 4096
#define BE_MUTINEER 8192 #define BE_LOYALIST 8192
#define BE_PAI 16384 #define BE_PAI 16384
// TODO: Update to new antagonist system.
var/list/be_special_flags = list( var/list/be_special_flags = list(
"Traitor" = BE_TRAITOR, "Traitor" = BE_TRAITOR,
"Operative" = BE_OPERATIVE, "Operative" = BE_OPERATIVE,
@@ -591,7 +590,7 @@ var/list/be_special_flags = list(
"Ninja" = BE_NINJA, "Ninja" = BE_NINJA,
"Raider" = BE_RAIDER, "Raider" = BE_RAIDER,
"Diona" = BE_PLANT, "Diona" = BE_PLANT,
"Mutineer" = BE_MUTINEER, "Loyalist" = BE_LOYALIST,
"pAI" = BE_PAI "pAI" = BE_PAI
) )
@@ -839,6 +838,7 @@ var/list/be_special_flags = list(
#define MODE_MONKEY "monkey" #define MODE_MONKEY "monkey"
#define MODE_RENEGADE "renegade" #define MODE_RENEGADE "renegade"
#define MODE_REVOLUTIONARY "revolutionary" #define MODE_REVOLUTIONARY "revolutionary"
#define MODE_LOYALIST "loyalist"
#define MODE_MALFUNCTION "malf" #define MODE_MALFUNCTION "malf"
#define MODE_TRAITOR "traitor" #define MODE_TRAITOR "traitor"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

After

Width:  |  Height:  |  Size: 194 KiB