Merge pull request #4930 from Citadel-Station-13/upstream-merge-34236

[MIRROR] Antag Panel / Check antagonists Refactor
This commit is contained in:
deathride58
2018-01-19 19:33:25 +00:00
committed by GitHub
63 changed files with 1224 additions and 1427 deletions

View File

@@ -48,7 +48,10 @@
body += "<br><br>\[ "
body += "<a href='?_src_=vars;[HrefToken()];Vars=[REF(M)]'>VV</a> - "
body += "<a href='?_src_=holder;[HrefToken()];traitor=[REF(M)]'>TP</a> - "
if(M.mind)
body += "<a href='?_src_=holder;[HrefToken()];traitor=[REF(M)]'>TP</a> - "
else
body += "<a href='?_src_=holder;[HrefToken()];initmind=[REF(M)]'>Init Mind</a> - "
body += "<a href='?priv_msg=[M.ckey]'>PM</a> - "
body += "<a href='?_src_=holder;[HrefToken()];subtlemessage=[REF(M)]'>SM</a> - "
body += "<a href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(M)]'>FLW</a> - "
@@ -649,7 +652,7 @@
to_chat(usr, "This mob has no mind!")
return
M.mind.edit_memory()
M.mind.traitor_panel()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Traitor Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -0,0 +1,217 @@
GLOBAL_VAR(antag_prototypes)
//Things to do somewhere in the future (If you're reading this feel free to do any of these)
//Add HrefTokens to these
//Make this template or at least remove + "<br>" with joins where you can grasp the big picture.
//Span classes for the headers, wrap sections in div's and style them.
//Move common admin commands to /mob (maybe integrate with vv dropdown so the list is one thing with some flag where to show it)
//Move objective initialization/editing stuff from mind to objectives and completely remove mind.objectives
/proc/cmp_antagpanel(datum/antagonist/A,datum/antagonist/B)
var/a_cat = initial(A.antagpanel_category)
var/b_cat = initial(B.antagpanel_category)
if(!a_cat && !b_cat)
return sorttext(initial(A.name),initial(B.name))
return sorttext(b_cat,a_cat)
/datum/mind/proc/add_antag_wrapper(antag_type,mob/user)
var/datum/antagonist/new_antag = new antag_type()
new_antag.admin_add(src,user)
//If something gone wrong/admin-add assign another antagonist due to whatever clean it up
if(!new_antag.owner)
qdel(new_antag)
/proc/listtrim(list/L)
for(var/x in L)
if(istext(x) && !x)
L -= x
return L
/datum/antagonist/proc/antag_panel()
var/list/commands = list()
for(var/command in get_admin_commands())
commands += "<a href='?src=[REF(src)];command=[command]'>[command]</a>"
var/command_part = commands.Join(" | ")
var/data_part = antag_panel_data()
var/objective_part = antag_panel_objectives()
var/memory_part = antag_panel_memory()
var/list/parts = listtrim(list(command_part,data_part,objective_part,memory_part))
return parts.Join("<br>")
/datum/antagonist/proc/antag_panel_objectives()
var/result = "<i><b>Objectives</b></i>:<br>"
if (objectives.len == 0)
result += "EMPTY<br>"
else
var/obj_count = 1
for(var/datum/objective/objective in objectives)
result += "<B>[obj_count]</B>: [objective.explanation_text] <a href='?src=[REF(owner)];obj_edit=[REF(objective)]'>Edit</a> <a href='?src=[REF(owner)];obj_delete=[REF(objective)]'>Delete</a> <a href='?src=[REF(owner)];obj_completed=[REF(objective)]'><font color=[objective.completed ? "green" : "red"]>[objective.completed ? "Mark as incomplete" : "Mark as complete"]</font></a><br>"
obj_count++
result += "<a href='?src=[REF(owner)];obj_add=1;target_antag=[REF(src)]'>Add objective</a><br>"
result += "<a href='?src=[REF(owner)];obj_announce=1'>Announce objectives</a><br>"
return result
/datum/antagonist/proc/antag_panel_memory()
var/out = "<b>Memory:</b><br>"
out += antag_memory
out += "<br><a href='?src=[REF(src)];memory_edit=1'>Edit memory</a><br>"
return out
/datum/mind/proc/get_common_admin_commands()
var/common_commands = "<span>Common Commands:</span>"
if(ishuman(current))
common_commands += "<a href='?src=[REF(src)];common=undress'>undress</a>"
else if(iscyborg(current))
var/mob/living/silicon/robot/R = current
if(R.emagged)
common_commands += "<a href='?src=[REF(src)];silicon=Unemag'>Unemag</a>"
else if(isAI(current))
var/mob/living/silicon/ai/A = current
if (A.connected_robots.len)
for (var/mob/living/silicon/robot/R in A.connected_robots)
if (R.emagged)
common_commands += "<a href='?src=[REF(src)];silicon=unemagcyborgs'>Unemag slaved cyborgs</a>"
break
return common_commands
/datum/mind/proc/get_special_statuses()
var/list/result = list()
if(!current)
result += "<span class='bad'>No body!</span>"
if(current && current.isloyal())
result += "<span class='good'>Mindshielded</span>"
//Move these to mob
if(iscyborg(current))
var/mob/living/silicon/robot/robot = current
if (robot.emagged)
result += "<span class='bad'>Emagged</span>"
return result.Join(" | ")
/datum/mind/proc/traitor_panel()
if(!SSticker.HasRoundStarted())
alert("Not before round-start!", "Alert")
return
if(QDELETED(src))
alert("This mind doesn't have a mob, or is deleted! For some reason!", "Edit Memory")
return
var/out = "<B>[name]</B>[(current && (current.real_name!=name))?" (as [current.real_name])":""]<br>"
out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]<br>"
out += "Assigned role: [assigned_role]. <a href='?src=[REF(src)];role_edit=1'>Edit</a><br>"
out += "Faction and special role: <b><font color='red'>[special_role]</font></b><br>"
var/special_statuses = get_special_statuses()
if(length(special_statuses))
out += get_special_statuses() + "<br>"
if(!GLOB.antag_prototypes)
GLOB.antag_prototypes = list()
for(var/antag_type in subtypesof(/datum/antagonist))
var/datum/antagonist/A = new antag_type
var/cat_id = A.antagpanel_category
if(!GLOB.antag_prototypes[cat_id])
GLOB.antag_prototypes[cat_id] = list(A)
else
GLOB.antag_prototypes[cat_id] += A
sortTim(GLOB.antag_prototypes,/proc/cmp_text_asc,associative=TRUE)
var/list/sections = list()
var/list/priority_sections = list()
for(var/antag_category in GLOB.antag_prototypes)
var/category_header = "<i><b>[antag_category]:</b></i>"
var/list/antag_header_parts = list(category_header)
var/datum/antagonist/current_antag
var/list/possible_admin_antags = list()
for(var/datum/antagonist/prototype in GLOB.antag_prototypes[antag_category])
var/datum/antagonist/A = has_antag_datum(prototype.type)
if(A)
//We got the antag
if(!current_antag)
current_antag = A
else
continue //Let's skip subtypes of what we already shown.
else if(prototype.show_in_antagpanel)
if(prototype.can_be_owned(src))
possible_admin_antags += "<a href='?src=[REF(src)];add_antag=[prototype.type]' title='[prototype.type]'>[prototype.name]</a>"
else
possible_admin_antags += "<a class='linkOff'>[prototype.name]</a>"
else
//We don't have it and it shouldn't be shown as an option to be added.
continue
if(!current_antag) //Show antagging options
if(possible_admin_antags.len)
antag_header_parts += "<span class='highlight'>None</span>"
antag_header_parts += possible_admin_antags
else
//If there's no antags to show in this category skip the section completely
continue
else //Show removal and current one
priority_sections |= antag_category
antag_header_parts += "<span class='bad'>[current_antag.name]</span>"
antag_header_parts += "<a href='?src=[REF(src)];remove_antag=[REF(current_antag)]'>Remove</a>"
//We aren't antag of this category, grab first prototype to check the prefs (This is pretty vague but really not sure how else to do this)
var/datum/antagonist/pref_source = current_antag
if(!pref_source)
for(var/datum/antagonist/prototype in GLOB.antag_prototypes[antag_category])
if(!prototype.show_in_antagpanel)
continue
pref_source = prototype
break
if(pref_source.job_rank)
antag_header_parts += pref_source.enabled_in_preferences(src) ? "Enabled in Prefs" : "Disabled in Prefs"
//Traitor : None | Traitor | IAA
// Command1 | Command2 | Command3
// Secret Word : Banana
// Objectives:
// 1.Do the thing [a][b]
// [a][b]
// Memory:
// Uplink Code: 777 Alpha
var/cat_section = antag_header_parts.Join(" | ") + "<br>"
if(current_antag)
cat_section += current_antag.antag_panel()
sections[antag_category] = cat_section
for(var/s in priority_sections)
out += sections[s]
for(var/s in sections - priority_sections)
out += sections[s]
out += "<br>"
//Uplink
if(ishuman(current))
var/uplink_info = "<i><b>Uplink</b></i>:"
var/datum/component/uplink/U = find_syndicate_uplink()
if(U)
uplink_info += "<a href='?src=[REF(src)];common=takeuplink'>take</a>"
if (check_rights(R_FUN, 0))
uplink_info += ", <a href='?src=[REF(src)];common=crystals'>[U.telecrystals]</a> TC"
else
uplink_info += ", [U.telecrystals] TC"
else
uplink_info += "<a href='?src=[REF(src)];common=uplink'>give</a>"
uplink_info += "." //hiel grammar
out += uplink_info + "<br>"
//Common Memory
var/common_memory = "<span>Common Memory:</span>"
common_memory += memory
common_memory += "<a href='?src=[REF(src)];memory_edit=1'>Edit Memory</a>"
out += common_memory + "<br>"
//Other stuff
out += get_common_admin_commands()
var/datum/browser/panel = new(usr, "traitorpanel", "", 600, 600)
panel.set_content(out)
panel.open()
return

View File

@@ -0,0 +1,212 @@
//I wish we had interfaces sigh, and i'm not sure giving team and antag common root is a better solution here
//Name shown on antag list
/datum/antagonist/proc/antag_listing_name()
if(!owner)
return "Unassigned"
if(owner.current)
return "<a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(owner.current)]'>[owner.current.real_name]</a>"
else
return "<a href='?_src_=vars;[HrefToken()];Vars=[REF(owner)]'>[owner.name]</a>"
//Whatever interesting things happened to the antag admins should know about
//Include additional information about antag in this part
/datum/antagonist/proc/antag_listing_status()
if(!owner)
return "(Unassigned)"
if(!owner.current)
return "<font color=red>(Body destroyed)</font>"
else
if(owner.current.stat == DEAD)
return "<font color=red>(DEAD)</font>"
else if(!owner.current.client)
return "(No client)"
//Builds the common FLW PM TP commands part
//Probably not going to be overwritten by anything but you never know
/datum/antagonist/proc/antag_listing_commands()
if(!owner)
return
var/list/parts = list()
parts += "<a href='?priv_msg=[ckey(owner.key)]'>PM</a>"
if(owner.current) //There's body to follow
parts += "<a href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(owner.current)]'>FLW</a>"
else
parts += ""
parts += "<a href='?_src_=holder;[HrefToken()];traitor=[REF(owner)]'>Show Objective</a>"
return parts //Better as one cell or two/three
//Builds table row for the antag
// Jim (Status) FLW PM TP
/datum/antagonist/proc/antag_listing_entry()
var/list/parts = list()
parts += antag_listing_name()
parts += antag_listing_status()
parts += antag_listing_commands()
return "<tr><td>[parts.Join("</td><td>")]</td></tr>"
/datum/team/proc/get_team_antags(antag_type,specific = FALSE)
. = list()
for(var/datum/antagonist/A in GLOB.antagonists)
if(A.get_team() == src && (!antag_type || !specific && istype(A,antag_type) || specific && A.type == antag_type))
. += A
//Builds section for the team
/datum/team/proc/antag_listing_entry()
//NukeOps:
// Jim (Status) FLW PM TP
// Joe (Status) FLW PM TP
//Disk:
// Deep Space FLW
var/list/parts = list()
parts += "<b>[antag_listing_name()]</b><br>"
parts += "<table cellspacing=5>"
for(var/datum/antagonist/A in get_team_antags())
parts += A.antag_listing_entry()
parts += "</table>"
parts += antag_listing_footer()
return parts.Join()
/datum/team/proc/antag_listing_name()
return name
/datum/team/proc/antag_listing_footer()
return
//Moves them to the top of the list if TRUE
/datum/antagonist/proc/is_gamemode_hero()
return FALSE
/datum/team/proc/is_gamemode_hero()
return FALSE
/datum/admins/proc/build_antag_listing()
var/list/sections = list()
var/list/priority_sections = list()
var/list/all_teams = list()
var/list/all_antagonists = list()
for(var/datum/antagonist/A in GLOB.antagonists)
if(!A.owner)
continue
all_teams |= A.get_team()
all_antagonists += A
for(var/datum/team/T in all_teams)
for(var/datum/antagonist/X in all_antagonists)
if(X.get_team() == T)
all_antagonists -= X
if(T.is_gamemode_hero())
priority_sections += T.antag_listing_entry()
else
sections += T.antag_listing_entry()
sortTim(all_antagonists, /proc/cmp_antag_category)
var/current_category
var/list/current_section = list()
for(var/i in 1 to all_antagonists.len)
var/datum/antagonist/current_antag = all_antagonists[i]
var/datum/antagonist/next_antag
if(i < all_antagonists.len)
next_antag = all_antagonists[i+1]
if(!current_category)
current_category = current_antag.roundend_category
current_section += "<b>[capitalize(current_category)]</b><br>"
current_section += "<table cellspacing=5>"
current_section += current_antag.antag_listing_entry() // Name - (Traitor) - FLW | PM | TP
if(!next_antag || next_antag.roundend_category != current_antag.roundend_category) //End of section
current_section += "</table>"
if(current_antag.is_gamemode_hero())
priority_sections += current_section.Join()
else
sections += current_section.Join()
current_section.Cut()
current_category = null
var/list/all_sections = priority_sections + sections
return all_sections.Join("<br>")
/datum/admins/proc/check_antagonists()
if (SSticker.HasRoundStarted())
var/dat = "<html><head><title>Round Status</title></head><body><h1><B>Round Status</B></h1>"
if(SSticker.mode.replacementmode)
dat += "Former Game Mode: <B>[SSticker.mode.name]</B><BR>"
dat += "Replacement Game Mode: <B>[SSticker.mode.replacementmode.name]</B><BR>"
else
dat += "Current Game Mode: <B>[SSticker.mode.name]</B><BR>"
dat += "Round Duration: <B>[DisplayTimeText(world.time - SSticker.round_start_time)]</B><BR>"
dat += "<B>Emergency shuttle</B><BR>"
if(EMERGENCY_IDLE_OR_RECALLED)
dat += "<a href='?_src_=holder;[HrefToken()];call_shuttle=1'>Call Shuttle</a><br>"
else
var/timeleft = SSshuttle.emergency.timeLeft()
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
dat += "ETA: <a href='?_src_=holder;[HrefToken()];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
dat += "<a href='?_src_=holder;[HrefToken()];call_shuttle=2'>Send Back</a><br>"
else
dat += "ETA: <a href='?_src_=holder;[HrefToken()];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
dat += "<B>Continuous Round Status</B><BR>"
dat += "<a href='?_src_=holder;[HrefToken()];toggle_continuous=1'>[CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]</a>"
if(CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag])
dat += ", <a href='?_src_=holder;[HrefToken()];toggle_midround_antag=1'>[CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]</a><BR>"
else
dat += "<BR>"
if(CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag])
dat += "Time limit: <a href='?_src_=holder;[HrefToken()];alter_midround_time_limit=1'>[CONFIG_GET(number/midround_antag_time_check)] minutes into round</a><BR>"
dat += "Living crew limit: <a href='?_src_=holder;[HrefToken()];alter_midround_life_limit=1'>[CONFIG_GET(number/midround_antag_life_check) * 100]% of crew alive</a><BR>"
dat += "If limits past: <a href='?_src_=holder;[HrefToken()];toggle_noncontinuous_behavior=1'>[SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"]</a><BR>"
dat += "<a href='?_src_=holder;[HrefToken()];end_round=[REF(usr)]'>End Round Now</a><br>"
dat += "<a href='?_src_=holder;[HrefToken()];delay_round_end=1'>[SSticker.delay_end ? "End Round Normally" : "Delay Round End"]</a>"
var/connected_players = GLOB.clients.len
var/lobby_players = 0
var/observers = 0
var/observers_connected = 0
var/living_players = 0
var/living_players_connected = 0
var/living_players_antagonist = 0
var/brains = 0
var/other_players = 0
var/living_skipped = 0
var/drones = 0
for(var/mob/M in GLOB.mob_list)
if(M.ckey)
if(isnewplayer(M))
lobby_players++
continue
else if(M.stat != DEAD && M.mind && !isbrain(M))
if(isdrone(M))
drones++
continue
if(is_centcom_level(M.z))
living_skipped++
continue
living_players++
if(M.mind.special_role)
living_players_antagonist++
if(M.client)
living_players_connected++
else if(M.stat == DEAD || isobserver(M))
observers++
if(M.client)
observers_connected++
else if(isbrain(M))
brains++
else
other_players++
dat += "<BR><b><font color='blue' size='3'>Players:|[connected_players - lobby_players] ingame|[connected_players] connected|[lobby_players] lobby|</font></b>"
dat += "<BR><b><font color='green'>Living Players:|[living_players_connected] active|[living_players - living_players_connected] disconnected|[living_players_antagonist] antagonists|</font></b>"
dat += "<BR><b><font color='#bf42f4'>SKIPPED \[On centcom Z-level\]: [living_skipped] living players|[drones] living drones|</font></b>"
dat += "<BR><b><font color='red'>Dead/Observing players:|[observers_connected] active|[observers - observers_connected] disconnected|[brains] brains|</font></b>"
if(other_players)
dat += "<BR><span class='userdanger'>[other_players] players in invalid state or the statistics code is bugged!</span>"
dat += "<br><br>"
dat += build_antag_listing()
dat += "</body></html>"
usr << browse(dat, "window=roundstatus;size=500x500")
else
alert("The game hasn't started yet!")

View File

@@ -307,342 +307,4 @@
</body></html>
"}
usr << browse(dat, "window=players;size=600x480")
/datum/admins/proc/check_antagonists()
if (SSticker.HasRoundStarted())
var/dat = "<html><head><title>Round Status</title></head><body><h1><B>Round Status</B></h1>"
if(SSticker.mode.replacementmode)
dat += "Former Game Mode: <B>[SSticker.mode.name]</B><BR>"
dat += "Replacement Game Mode: <B>[SSticker.mode.replacementmode.name]</B><BR>"
else
dat += "Current Game Mode: <B>[SSticker.mode.name]</B><BR>"
dat += "Round Duration: <B>[DisplayTimeText(world.time - SSticker.round_start_time)]</B><BR>"
dat += "<B>Emergency shuttle</B><BR>"
if(EMERGENCY_IDLE_OR_RECALLED)
dat += "<a href='?_src_=holder;[HrefToken()];call_shuttle=1'>Call Shuttle</a><br>"
else
var/timeleft = SSshuttle.emergency.timeLeft()
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
dat += "ETA: <a href='?_src_=holder;[HrefToken()];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
dat += "<a href='?_src_=holder;[HrefToken()];call_shuttle=2'>Send Back</a><br>"
else
dat += "ETA: <a href='?_src_=holder;[HrefToken()];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
dat += "<B>Continuous Round Status</B><BR>"
dat += "<a href='?_src_=holder;[HrefToken()];toggle_continuous=1'>[CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]</a>"
if(CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag])
dat += ", <a href='?_src_=holder;[HrefToken()];toggle_midround_antag=1'>[CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]</a><BR>"
else
dat += "<BR>"
if(CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag])
dat += "Time limit: <a href='?_src_=holder;[HrefToken()];alter_midround_time_limit=1'>[CONFIG_GET(number/midround_antag_time_check)] minutes into round</a><BR>"
dat += "Living crew limit: <a href='?_src_=holder;[HrefToken()];alter_midround_life_limit=1'>[CONFIG_GET(number/midround_antag_life_check) * 100]% of crew alive</a><BR>"
dat += "If limits past: <a href='?_src_=holder;[HrefToken()];toggle_noncontinuous_behavior=1'>[SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"]</a><BR>"
dat += "<a href='?_src_=holder;[HrefToken()];end_round=[REF(usr)]'>End Round Now</a><br>"
dat += "<a href='?_src_=holder;[HrefToken()];delay_round_end=1'>[SSticker.delay_end ? "End Round Normally" : "Delay Round End"]</a>"
var/connected_players = GLOB.clients.len
var/lobby_players = 0
var/observers = 0
var/observers_connected = 0
var/living_players = 0
var/living_players_connected = 0
var/living_players_antagonist = 0
var/brains = 0
var/other_players = 0
var/living_skipped = 0
var/drones = 0
for(var/mob/M in GLOB.mob_list)
if(M.ckey)
if(isnewplayer(M))
lobby_players++
continue
else if(M.stat != DEAD && M.mind && !isbrain(M))
if(isdrone(M))
drones++
continue
if(is_centcom_level(M.z))
living_skipped++
continue
living_players++
if(M.mind.special_role)
living_players_antagonist++
if(M.client)
living_players_connected++
else if((M.stat == DEAD )||(isobserver(M)))
observers++
if(M.client)
observers_connected++
else if(isbrain(M))
brains++
else
other_players++
dat += "<BR><b><font color='blue' size='3'>Players:|[connected_players - lobby_players] ingame|[connected_players] connected|[lobby_players] lobby|</font></b>"
dat += "<BR><b><font color='green'>Living Players:|[living_players_connected] active|[living_players - living_players_connected] disconnected|[living_players_antagonist] antagonists|</font></b>"
dat += "<BR><b><font color='#bf42f4'>SKIPPED \[On centcom Z-level\]: [living_skipped] living players|[drones] living drones|</font></b>"
dat += "<BR><b><font color='red'>Dead/Observing players:|[observers_connected] active|[observers - observers_connected] disconnected|[brains] brains|</font></b>"
if(other_players)
dat += "<BR><span class='userdanger'>[other_players] players in invalid state or the statistics code is bugged!</span>"
dat += "<BR>"
var/list/nukeops = get_antagonists(/datum/antagonist/nukeop)
if(nukeops.len)
dat += "<br><table cellspacing=5><tr><td><B>Syndicates</B></td><td></td></tr>"
for(var/datum/mind/N in nukeops)
var/mob/M = N.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></tr>"
else
dat += "<tr><td><i><a href='?_src_=vars;[HrefToken()];Vars=[REF(N)]'>[N.name]([N.key])</a> Nuclear Operative Body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
dat += "</table><br><table><tr><td><B>Nuclear Disk(s)</B></td></tr>"
for(var/obj/item/disk/nuclear/N in GLOB.poi_list)
dat += "<tr><td>[N.name], "
var/atom/disk_loc = N.loc
while(!isturf(disk_loc))
if(ismob(disk_loc))
var/mob/M = disk_loc
dat += "carried by <a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a> "
if(isobj(disk_loc))
var/obj/O = disk_loc
dat += "in \a [O.name] "
disk_loc = disk_loc.loc
dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])</td></tr>"
dat += "</table>"
var/list/revs = get_antagonists(/datum/antagonist/rev)
if(revs.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Revolutionaries</B></td><td></td></tr>"
for(var/datum/mind/N in get_antagonists(/datum/antagonist/rev/head))
var/mob/M = N.current
if(!M)
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=[REF(N)]'>[N.name]([N.key])</a><i>Head Revolutionary body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a> <b>(Leader)</b>[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></tr>"
for(var/datum/mind/N in get_antagonists(/datum/antagonist/rev,TRUE))
var/mob/M = N.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></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 SSjob.get_living_heads())
var/mob/M = N.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>"
var/turf/mob_loc = get_turf(M)
dat += "<td>[mob_loc.loc]</td></tr>"
else
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=[REF(N)]'>[N.name]([N.key])</a><i>Head body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
dat += "</table>"
var/list/lings = get_antagonists(/datum/antagonist/changeling)
if(lings.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Changelings</B></td><td></td><td></td></tr>"
for(var/datum/mind/changeling in lings)
var/datum/antagonist/changeling/lingantag = changeling.has_antag_datum(/datum/antagonist/changeling)
var/mob/M = changeling.current
if(M)
dat += "<tr><td>[lingantag.changelingID]([lingantag.name]) as <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(changeling)]'>[changeling.name]([changeling.key])</a><i>Changeling body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[changeling.key]'>PM</A></td></tr>"
dat += "</table>"
if(SSticker.mode.wizards.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Wizards</B></td><td></td><td></td></tr>"
for(var/datum/mind/wizard in SSticker.mode.wizards)
var/mob/M = wizard.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(wizard)]'>[wizard.name]([wizard.key])</a><i>Wizard body destroyed!</i></td></tr>"
dat += "<td><A href='?priv_msg=[wizard.key]'>PM</A></td></tr>"
dat += "</table>"
if(SSticker.mode.apprentices.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Apprentice</B></td><td></td><td></td></tr>"
for(var/datum/mind/apprentice in SSticker.mode.apprentices)
var/mob/M = apprentice.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(apprentice)]'>[apprentice.name]([apprentice.key])</a><i>Apprentice body destroyed!!</i></td></tr>"
dat += "<td><A href='?priv_msg=[apprentice.key]'>PM</A></td></tr>"
dat += "</table>"
if(SSticker.mode.cult.len)
dat += "<br><table cellspacing=5><tr><td><B>Cultists</B></td><td></td></tr>"
for(var/datum/mind/N in SSticker.mode.cult)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a>[N.has_antag_datum(ANTAG_DATUM_CULT_MASTER) ? "<i><font color=red> \[Master\]</font></i>" : ""][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></tr>"
dat += "</table>"
if(SSticker.mode.servants_of_ratvar.len)
dat += "<br><table cellspacing=5><tr><td><B>Servants of Ratvar</B></td><td></td></tr>"
for(var/datum/mind/N in SSticker.mode.servants_of_ratvar)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</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></tr>"
dat += "</table>"
if(SSticker.mode.traitors.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Traitors</B></td><td></td><td></td></tr>"
for(var/datum/mind/traitor in SSticker.mode.traitors)
var/mob/M = traitor.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(traitor)]'>[traitor.name]([traitor.key])</a><i>Traitor body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[traitor.key]'>PM</A></td></tr>"
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/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)
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)
var/mob/M = abductor.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(abductor)]'>[abductor.name]([abductor.key])</a><i>Abductor body destroyed!</i></td></tr>"
dat += "<td><A href='?priv_msg=[abductor.key]'>PM</A></td>"
dat += "</table>"
dat += "<br><table cellspacing=5><tr><td><B>Abductees</B></td><td></td><td></td></tr>"
for(var/obj/machinery/abductor/experiment/E in GLOB.machines)
for(var/datum/mind/abductee in E.abductee_minds)
var/mob/M = abductee.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(abductee)]'>[abductee.name]([abductee.key])</a><i>Abductee body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[abductee.key]'>PM</A></td></tr>"
dat += "</table>"
if(SSticker.mode.devils.len)
dat += "<br><table cellspacing=5><tr><td><B>devils</B></td><td></td><td></td></tr>"
for(var/X in SSticker.mode.devils)
var/datum/mind/devil = X
var/mob/M = devil.current
var/datum/antagonist/devil/devilinfo = devil.has_antag_datum(ANTAG_DATUM_DEVIL)
if(M)
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name] : [devilinfo.truename]</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()];traitor=[REF(M)]'>Show Objective</A></td></tr>"
dat += "<td><A HREF='?_src_=holder;[HrefToken()];admincheckdevilinfo=[REF(M)]'>Show all devil info</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=[REF(devil)]'>[devil.name] : [devilinfo.truename] ([devil.key])</a><i>devil body destroyed!</i></td></tr>"
dat += "<td><A href='?priv_msg=[devil.key]'>PM</A></td>"
dat += "</table>"
if(SSticker.mode.sintouched.len)
dat += "<br><table cellspacing=5><tr><td><B>sintouched</B></td><td></td><td></td></tr>"
for(var/X in SSticker.mode.sintouched)
var/datum/mind/sintouched = X
var/mob/M = sintouched.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()];traitor=[REF(M)]'>Show Objective</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=[REF(sintouched)]'>[sintouched.name]([sintouched.key])</a><i>sintouched body destroyed!</i></td></tr>"
dat += "<td><A href='?priv_msg=[sintouched.key]'>PM</A></td>"
dat += "</table>"
var/list/blob_minds = list()
for(var/mob/camera/blob/B in GLOB.mob_list)
blob_minds |= B.mind
if(blob_minds.len)
dat += "<br><table cellspacing=5><tr><td><B>Blob</B></td><td></td><td></td></tr>"
for(var/datum/mind/blob in blob_minds)
var/mob/camera/blob/M = blob.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></tr>"
dat += "<tr><td><i>Progress: [M.blobs_legit.len]/[M.blobwincount]</i></td></tr>"
else
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=[REF(blob)]'>[blob.name]([blob.key])</a><i>Blob not found!</i></td>"
dat += "<td><A href='?priv_msg=[blob.key]'>PM</A></td></tr>"
dat += "</table>"
var/list/pirates = get_antagonists(/datum/antagonist/pirate)
if(pirates.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Pirates</B></td><td></td></tr>"
for(var/datum/mind/N in pirates)
var/mob/M = N.current
if(!M)
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[N]'>[N.name]([N.key])</a><i>No body.</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
else
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></tr>"
dat += "</table>"
if(istype(SSticker.mode, /datum/game_mode/monkey))
var/datum/game_mode/monkey/mode = SSticker.mode
dat += "<br><table cellspacing=5><tr><td><B>Monkey</B></td><td></td><td></td></tr>"
for(var/datum/mind/eek in mode.ape_infectees)
var/mob/M = eek.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></tr>"
else
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=[REF(eek)]'>[eek.name]([eek.key])</a><i>Monkey not found!</i></td>"
dat += "<td><A href='?priv_msg=[eek.key]'>PM</A></td></tr>"
dat += "</table>"
dat += "</body></html>"
usr << browse(dat, "window=roundstatus;size=420x500")
else
alert("The game hasn't started yet!")
usr << browse(dat, "window=players;size=600x480")

View File

@@ -345,7 +345,7 @@
continue
if(is_special_character(H))
continue
var/datum/antagonist/traitor/human/T = new(H.mind)
var/datum/antagonist/traitor/human/T = new()
T.give_objectives = FALSE
var/datum/objective/new_objective = new
new_objective.owner = H

View File

@@ -1894,10 +1894,24 @@
var/mob/M = locate(href_list["traitor"])
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob.")
var/datum/mind/D = M
if(!istype(D))
to_chat(usr, "This can only be used on instances of type /mob and /mind")
return
else
D.traitor_panel()
else
show_traitor_panel(M)
else if(href_list["initmind"])
if(!check_rights(R_ADMIN))
return
show_traitor_panel(M)
var/mob/M = locate(href_list["initmind"])
if(!ismob(M) || M.mind)
to_chat(usr, "This can only be used on instances on mindless mobs")
return
M.mind_initialize()
else if(href_list["create_object"])
if(!check_rights(R_SPAWN))
return

View File

@@ -306,7 +306,6 @@
door.open()
//Assign antag status and the mission
SSticker.mode.traitors += Commando.mind
Commando.mind.special_role = "deathsquad"
var/datum/objective/missionobj = new
@@ -361,7 +360,6 @@
newmob.equipOutfit(/datum/outfit/centcom_official)
//Assign antag status and the mission
SSticker.mode.traitors += newmob.mind
newmob.mind.special_role = "official"
var/datum/objective/missionobj = new
@@ -469,7 +467,6 @@
door.open()
//Assign antag status and the mission
SSticker.mode.traitors += ERTOperative.mind
ERTOperative.mind.special_role = "ERT"
var/datum/objective/missionobj = new

View File

@@ -26,7 +26,6 @@ GLOBAL_VAR_INIT(highlander, FALSE)
addtimer(CALLBACK(src, .proc/only_one), 420)
/mob/living/carbon/human/proc/make_scottish()
SSticker.mode.traitors += mind
mind.special_role = "highlander"
dna.species.species_traits |= NOGUNS //nice try jackass

View File

@@ -113,7 +113,6 @@
if("To Kill")
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
to_chat(user, "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart.")
SSticker.mode.traitors += user.mind
user.mind.special_role = "traitor"
var/datum/objective/hijack/hijack = new

View File

@@ -4,7 +4,7 @@
weight = 10
max_occurrences = 1
min_players = 20
gamemode_blacklist = list("nuclear","wizard","revolution","abduction")
gamemode_blacklist = list("nuclear","wizard","revolution")
/datum/round_event/ghost_role/abductor
minimum_required = 2
@@ -17,20 +17,18 @@
if(candidates.len < 2)
return NOT_ENOUGH_PLAYERS
var/datum/game_mode/abduction/GM
if(SSticker.mode.config_tag == "abduction")
GM = SSticker.mode
else
GM = new
var/mob/living/carbon/human/agent = makeBody(pick_n_take(candidates))
var/mob/living/carbon/human/scientist = makeBody(pick_n_take(candidates))
var/team = GM.make_abductor_team(agent.mind, scientist.mind)
if(!team)
var/datum/team/abductor_team/T = new
if(T.team_number > ABDUCTOR_MAX_TEAMS)
return MAP_ERROR
log_game("[scientist.mind.key] (ckey) has been selected as [T.name] abductor scientist.")
log_game("[agent.mind.key] (ckey) has been selected as [T.name] abductor agent.")
GM.post_setup_team(team)
scientist.mind.add_antag_datum(ANTAG_DATUM_ABDUCTOR_SCIENTIST, T)
agent.mind.add_antag_datum(ANTAG_DATUM_ABDUCTOR_AGENT, T)
spawned_mobs += list(agent, scientist)
return SUCCESSFUL_SPAWN

View File

@@ -46,17 +46,11 @@
var/datum/objective/martyr/normiesgetout = new
normiesgetout.owner = L.mind
L.mind.special_role = "heartbreaker"
SSticker.mode.traitors |= L.mind
L.mind.objectives += normiesgetout
L.mind.add_antag_datum(/datum/antagonist/auto_custom)
/proc/forge_valentines_objective(mob/living/lover,mob/living/date)
SSticker.mode.traitors |= lover.mind
lover.mind.special_role = "valentine"
var/datum/objective/protect/protect_objective = new /datum/objective/protect
protect_objective.owner = lover.mind
protect_objective.target = date.mind

View File

@@ -34,7 +34,6 @@
player_mind.transfer_to(S)
player_mind.assigned_role = "Nightmare"
player_mind.special_role = "Nightmare"
SSticker.mode.traitors += player_mind
player_mind.add_antag_datum(/datum/antagonist/auto_custom)
S.set_species(/datum/species/shadow/nightmare)
playsound(S, 'sound/magic/ethereal_exit.ogg', 50, 1, -1)

View File

@@ -38,11 +38,10 @@
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
if(H.mind)
var/datum/mind/M = H.mind
if(M.assigned_role && !(M in SSticker.mode.traitors))
if(M.assigned_role && !(M.has_antag_datum(/datum/antagonist)))
for(var/job in jobs_to_revolt)
if(M.assigned_role == job)
citizens += H
SSticker.mode.traitors += M
M.special_role = "separatist"
M.add_antag_datum(/datum/antagonist/auto_custom)
H.log_message("<font color='red'>Was made into a separatist, long live [nation]!</font>", INDIVIDUAL_ATTACK_LOG)

View File

@@ -60,8 +60,6 @@
/obj/item/greentext/process()
if(new_holder && is_centcom_level(new_holder.z))//you're winner!
to_chat(new_holder, "<font color='green'>At last it feels like victory is assured!</font>")
if(!(new_holder in SSticker.mode.traitors))
SSticker.mode.traitors += new_holder.mind
new_holder.mind.special_role = "winner"
var/datum/objective/O = new /datum/objective("Succeed")
O.completed = 1 //YES!

View File

@@ -27,7 +27,7 @@
var/datum/antagonist/wizard/master = M.has_antag_datum(/datum/antagonist/wizard)
if(!master.wiz_team)
master.create_wiz_team()
var/datum/antagonist/wizard/apprentice/imposter/imposter = new(I.mind)
var/datum/antagonist/wizard/apprentice/imposter/imposter = new()
imposter.master = M
imposter.wiz_team = master.wiz_team
master.wiz_team.add_member(imposter)

View File

@@ -49,7 +49,6 @@
if(mind)
if(!mind.special_role)
mind.special_role = "traitor"
SSticker.mode.traitors += mind
mind.add_antag_datum(/datum/antagonist/auto_custom) // ????

View File

@@ -990,7 +990,6 @@
.["Toggle Godmode"] = "?_src_=vars;[HrefToken()];godmode=[REF(src)]"
.["Drop Everything"] = "?_src_=vars;[HrefToken()];drop_everything=[REF(src)]"
.["Regenerate Icons"] = "?_src_=vars;[HrefToken()];regenerateicons=[REF(src)]"
.["Make Space Ninja"] = "?_src_=vars;[HrefToken()];ninja=[REF(src)]"
.["Show player panel"] = "?_src_=vars;[HrefToken()];mob_player_panel=[REF(src)]"
.["Toggle Build Mode"] = "?_src_=vars;[HrefToken()];build_mode=[REF(src)]"
.["Assume Direct Control"] = "?_src_=vars;[HrefToken()];direct_control=[REF(src)]"

View File

@@ -448,6 +448,10 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
poll_message = "[poll_message] Job:[M.mind.assigned_role]."
if(M.mind && M.mind.special_role)
poll_message = "[poll_message] Status:[M.mind.special_role]."
else if(M.mind)
var/datum/antagonist/A = M.mind.has_antag_datum(/datum/antagonist/)
if(A)
poll_message = "[poll_message] Status:[A.name]."
var/list/mob/dead/observer/candidates = pollCandidatesForMob(poll_message, "pAI", null, FALSE, 100, M)
var/mob/dead/observer/theghost = null

View File

@@ -28,7 +28,6 @@ Contents:
/datum/round_event/ghost_role/ninja/setup()
helping_station = rand(0,1)
/datum/round_event/ghost_role/ninja/kill()
if(!success_spawn && control)
control.occurrences--
@@ -57,22 +56,21 @@ Contents:
var/key = selected_candidate.key
//Prepare ninja player mind
var/datum/mind/Mind = create_ninja_mind(key)
var/datum/mind/Mind = new /datum/mind(key)
Mind.assigned_role = "Space Ninja"
Mind.special_role = "Space Ninja"
Mind.active = 1
//generate objectives - You'll generally get 6 objectives (Ninja is meant to be hardmode!)
//spawn the ninja and assign the candidate
var/mob/living/carbon/human/Ninja = create_space_ninja(spawn_loc)
Mind.transfer_to(Ninja)
var/datum/antagonist/ninja/ninjadatum = add_ninja(Ninja)
ninjadatum.equip_space_ninja()
var/datum/antagonist/ninja/ninjadatum = new
ninjadatum.helping_station = pick(TRUE,FALSE)
Mind.add_antag_datum(ninjadatum)
if(Ninja.mind != Mind) //something has gone wrong!
throw EXCEPTION("Ninja created with incorrect mind")
SSticker.mode.update_ninja_icons_added(Ninja)
spawned_mobs += Ninja
message_admins("[key_name_admin(Ninja)] has been made into a ninja by an event.")
log_game("[key_name(Ninja)] was spawned as a ninja by an event.")
@@ -88,23 +86,4 @@ Contents:
A.real_name = "[pick(GLOB.ninja_titles)] [pick(GLOB.ninja_names)]"
A.copy_to(new_ninja)
new_ninja.dna.update_dna_identity()
return new_ninja
/proc/create_ninja_mind(key)
var/datum/mind/Mind = new /datum/mind(key)
Mind.assigned_role = "Space Ninja"
Mind.special_role = "Space Ninja"
SSticker.mode.traitors |= Mind //Adds them to current traitor list. TODO : Remove this in admin tools refeactor.
return Mind
/datum/game_mode/proc/update_ninja_icons_added(var/mob/living/carbon/human/ninja)
var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA]
ninjahud.join_hud(ninja)
set_antag_hud(ninja, "ninja")
/datum/game_mode/proc/update_ninja_icons_removed(datum/mind/ninja_mind)
var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA]
ninjahud.leave_hud(ninja_mind.current)
set_antag_hud(ninja_mind.current, null)
return new_ninja

View File

@@ -49,6 +49,8 @@
GLOB.cult_narsie = src
var/list/all_cults = list()
for(var/datum/antagonist/cult/C in GLOB.antagonists)
if(!C.owner)
continue
all_cults |= C.cult_team
for(var/datum/team/cult/T in all_cults)
deltimer(T.blood_target_reset_timer)

View File

@@ -407,7 +407,6 @@
D.Devolve()
/datum/chemical_reaction/mix_virus/neuter_virus
name = "Neuter Virus"
id = "neutervirus"
required_reagents = list("formaldehyde" = 1)

View File

@@ -93,7 +93,7 @@ GLOBAL_VAR_INIT(summon_magic_triggered, FALSE)
if(iswizard(H) || H.mind.special_role == "survivalist")
return
if(prob(GLOB.summon_guns_triggered) && !(H.mind in SSticker.mode.traitors))
if(prob(GLOB.summon_guns_triggered) && !(H.mind.has_antag_datum(/datum/antagonist)))
SSticker.mode.traitors += H.mind
var/datum/objective/steal_five_of_type/summon_guns/guns = new
@@ -125,7 +125,7 @@ GLOBAL_VAR_INIT(summon_magic_triggered, FALSE)
if(iswizard(H) || H.mind.special_role == "survivalist")
return
if(prob(GLOB.summon_magic_triggered) && !(H.mind in SSticker.mode.traitors))
if(prob(GLOB.summon_magic_triggered) && !(H.mind.has_antag_datum(/datum/antagonist)))
var/datum/objective/steal_five_of_type/summon_magic/magic = new
magic.owner = H.mind
H.mind.objectives += magic