Merge pull request #4930 from Citadel-Station-13/upstream-merge-34236
[MIRROR] Antag Panel / Check antagonists Refactor
This commit is contained in:
@@ -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!
|
||||
|
||||
|
||||
|
||||
217
code/modules/admin/antag_panel.dm
Normal file
217
code/modules/admin/antag_panel.dm
Normal 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
|
||||
212
code/modules/admin/check_antagonists.dm
Normal file
212
code/modules/admin/check_antagonists.dm
Normal 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!")
|
||||
@@ -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")
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) // ????
|
||||
|
||||
|
||||
|
||||
@@ -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)]"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -407,7 +407,6 @@
|
||||
D.Devolve()
|
||||
|
||||
/datum/chemical_reaction/mix_virus/neuter_virus
|
||||
|
||||
name = "Neuter Virus"
|
||||
id = "neutervirus"
|
||||
required_reagents = list("formaldehyde" = 1)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user