Antag Panel / Check antagonists Refactor (#34236)

* Antag Panel & Friends Refactor

* Prettfying

* Removes abduction also blob from default configs.

* Ninja fixes

* Ninjafix

* First draft of the new check_antags

* I love coding without compiler

* Yes

* Fixes

* Check_antags part  2

* Fixes and cleanup

* Okay should be good now.

* Adds simple no move & no tc syndie for events

* Integrates toggle objective pr

* Why i even bother.

* Offer mob shows all antags

* Some minor visual stuff

* Proper name for the helper
This commit is contained in:
AnturK
2018-01-19 15:43:23 +01:00
committed by Jordan Brown
parent f12c3c0283
commit e38e6b8fa4
63 changed files with 1218 additions and 1431 deletions

View File

@@ -4,8 +4,6 @@
#define ANTAG_DATUM_CLOCKCULT_SILENT /datum/antagonist/clockcult/silent
#define ANTAG_DATUM_DEVIL /datum/antagonist/devil
#define ANTAG_DATUM_NINJA /datum/antagonist/ninja
#define ANTAG_DATUM_NINJA_FRIENDLY /datum/antagonist/ninja/friendly
#define ANTAG_DATUM_NINJA_RANDOM /datum/antagonist/ninja/randomAllegiance/
#define ANTAG_DATUM_TRAITOR /datum/antagonist/traitor
#define ANTAG_DATUM_TRAITOR_HUMAN /datum/antagonist/traitor/human
#define ANTAG_DATUM_TRAITOR_AI /datum/antagonist/traitor/AI

View File

@@ -42,7 +42,7 @@ GLOBAL_LIST_INIT(special_roles, list(
ROLE_NINJA,
ROLE_MONKEY = /datum/game_mode/monkey,
ROLE_REVENANT,
ROLE_ABDUCTOR = /datum/game_mode/abduction,
ROLE_ABDUCTOR,
ROLE_DEVIL = /datum/game_mode/devil,
ROLE_SERVANT_OF_RATVAR = /datum/game_mode/clockwork_cult
))

View File

@@ -26,6 +26,9 @@
var/list/team_ids = list()
for(var/datum/antagonist/A in GLOB.antagonists)
if(!A.owner)
continue
var/list/antag_info = list()
antag_info["key"] = A.owner.key
antag_info["name"] = A.owner.name
@@ -41,8 +44,6 @@
team_ids[T] = team_gid++
antag_info["team"]["id"] = team_ids[T]
if(!A.owner)
continue
if(A.objectives.len)
for(var/datum/objective/O in A.objectives)
var/result = O.check_completion() ? "SUCCESS" : "FAIL"
@@ -368,6 +369,8 @@
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

View File

@@ -1,24 +1,33 @@
#define ABDUCTOR_MAX_TEAMS 4
/datum/antagonist/abductor
name = "Abductor"
roundend_category = "abductors"
antagpanel_category = "Abductor"
job_rank = ROLE_ABDUCTOR
show_in_antagpanel = FALSE //should only show subtypes
var/datum/team/abductor_team/team
var/sub_role
var/outfit
var/landmark_type
var/greet_text
/datum/antagonist/abductor/agent
name = "Abductor Agent"
sub_role = "Agent"
outfit = /datum/outfit/abductor/agent
landmark_type = /obj/effect/landmark/abductor/agent
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
show_in_antagpanel = TRUE
/datum/antagonist/abductor/scientist
name = "Abductor Scientist"
sub_role = "Scientist"
outfit = /datum/outfit/abductor/scientist
landmark_type = /obj/effect/landmark/abductor/scientist
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
show_in_antagpanel = TRUE
/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team)
if(!new_team)
@@ -33,6 +42,7 @@
/datum/antagonist/abductor/on_gain()
SSticker.mode.abductors += owner
owner.special_role = "[name] [sub_role]"
owner.assigned_role = "[name] [sub_role]"
owner.objectives += team.objectives
finalize_abductor()
return ..()
@@ -72,11 +82,48 @@
var/datum/species/abductor/A = H.dna.species
A.scientist = TRUE
/datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin)
var/list/current_teams = list()
for(var/datum/team/abductor_team/T in get_all_teams(/datum/team/abductor_team))
current_teams[T.name] = T
var/choice = input(admin,"Add to which team ?") as null|anything in (current_teams + "new team")
if (choice == "new team")
team = new
else if(choice in current_teams)
team = current_teams[choice]
else
return
new_owner.add_antag_datum(src)
log_admin("[key_name(usr)] made [key_name(new_owner.current)] [name] on [choice]!")
message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner.current)] [name] on [choice] !")
/datum/antagonist/abductor/get_admin_commands()
. = ..()
.["Equip"] = CALLBACK(src,.proc/admin_equip)
/datum/antagonist/abductor/proc/admin_equip(mob/admin)
if(!ishuman(owner.current))
to_chat(admin, "<span class='warning'>This only works on humans!</span>")
return
var/mob/living/carbon/human/H = owner.current
var/gear = alert(admin,"Agent or Scientist Gear","Gear","Agent","Scientist")
if(gear)
if(gear=="Agent")
H.equipOutfit(/datum/outfit/abductor/agent)
else
H.equipOutfit(/datum/outfit/abductor/scientist)
/datum/team/abductor_team
member_name = "abductor"
var/team_number
var/list/datum/mind/abductees = list()
var/static/team_count = 1
/datum/team/abductor_team/New()
..()
team_number = team_count++
name = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names
add_objective(new/datum/objective/experiment)
/datum/team/abductor_team/is_solo()
return FALSE
@@ -105,10 +152,10 @@
return result.Join("<br>")
/datum/antagonist/abductee
name = "Abductee"
roundend_category = "abductees"
antagpanel_category = "Abductee"
/datum/antagonist/abductee/on_gain()
give_objective()

View File

@@ -12,12 +12,15 @@ GLOBAL_LIST_EMPTY(antagonists)
var/job_rank
var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted.
var/list/objectives = list()
var/antag_memory = ""//These will be removed with antag datum
/datum/antagonist/New(datum/mind/new_owner)
//Antag panel properties
var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind
var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED
/datum/antagonist/New()
GLOB.antagonists += src
typecache_datum_blacklist = typecacheof(typecache_datum_blacklist)
if(new_owner)
owner = new_owner
/datum/antagonist/Destroy()
GLOB.antagonists -= src
@@ -36,6 +39,11 @@ GLOBAL_LIST_EMPTY(antagonists)
if(is_type_in_typecache(src, A.typecache_datum_blacklist))
return FALSE
//This will be called in add_antag_datum before owner assignment.
//Should return antag datum without owner.
/datum/antagonist/proc/specialization(datum/mind/new_owner)
return src
/datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body)
remove_innate_effects(old_body)
apply_innate_effects(new_body)
@@ -131,18 +139,82 @@ GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist/proc/roundend_report_footer()
return
//ADMIN TOOLS
//Called when using admin tools to give antag status
/datum/antagonist/proc/admin_add(datum/mind/new_owner,mob/admin)
message_admins("[key_name_admin(admin)] made [new_owner.current] into [name].")
log_admin("[key_name(admin)] made [new_owner.current] into [name].")
new_owner.add_antag_datum(src)
//Called when removing antagonist using admin tools
/datum/antagonist/proc/admin_remove(mob/user)
if(!user)
return
message_admins("[key_name_admin(user)] has removed [name] antagonist status from [owner.current].")
log_admin("[key_name(user)] has removed [name] antagonist status from [owner.current].")
on_removal()
//gamemode/proc/is_mode_antag(antagonist/A) => TRUE/FALSE
//Additional data to display in antagonist panel section
//nuke disk code, genome count, etc
/datum/antagonist/proc/antag_panel_data()
return ""
/datum/antagonist/proc/enabled_in_preferences(datum/mind/M)
if(job_rank)
if(M.current && M.current.client && (job_rank in M.current.client.prefs.be_special))
return TRUE
else
return FALSE
return TRUE
// List if ["Command"] = CALLBACK(), user will be appeneded to callback arguments on execution
/datum/antagonist/proc/get_admin_commands()
. = list()
/datum/antagonist/Topic(href,href_list)
if(!check_rights(R_ADMIN))
return
//Antag memory edit
if (href_list["memory_edit"])
edit_memory(usr)
owner.traitor_panel()
return
//Some commands might delete/modify this datum clearing or changing owner
var/datum/mind/persistent_owner = owner
var/commands = get_admin_commands()
for(var/admin_command in commands)
if(href_list["command"] == admin_command)
var/datum/callback/C = commands[admin_command]
C.Invoke(usr)
persistent_owner.traitor_panel()
return
/datum/antagonist/proc/edit_memory(mob/user)
var/new_memo = copytext(trim(input(user,"Write new memory", "Memory", antag_memory) as null|message),1,MAX_MESSAGE_LEN)
if (isnull(new_memo))
return
antag_memory = new_memo
//Should probably be on ticker or job ss ?
/proc/get_antagonists(antag_type,specific = FALSE)
. = list()
for(var/datum/antagonist/A in GLOB.antagonists)
if(!specific && istype(A,antag_type) || specific && A.type == antag_type)
if(!A.owner)
continue
if(!antag_type || !specific && istype(A,antag_type) || specific && A.type == antag_type)
. += A.owner
//This datum will autofill the name with special_role
//Used as placeholder for minor antagonists, please create proper datums for these
/datum/antagonist/auto_custom
show_in_antagpanel = FALSE
antagpanel_category = "Other"
/datum/antagonist/auto_custom/on_gain()
..()
@@ -156,5 +228,20 @@ GLOBAL_LIST_EMPTY(antagonists)
already_registered_objectives |= A.objectives
objectives = owner.objectives - already_registered_objectives
/datum/antagonist/auto_custom/antag_listing_name()
return ..() + "([name])"
//This one is created by admin tools for custom objectives
/datum/antagonist/custom
antagpanel_category = "Custom"
/datum/antagonist/custom/admin_add(datum/mind/new_owner,mob/admin)
var/custom_name = stripped_input(admin, "Custom antagonist name:", "Custom antag", "Antagonist")
if(custom_name)
name = custom_name
else
return
..()
/datum/antagonist/custom/antag_listing_name()
return ..() + "([name])"

View File

@@ -1,6 +1,7 @@
/datum/antagonist/blob
name = "Blob"
roundend_category = "blobs"
antagpanel_category = "Blob"
job_rank = ROLE_BLOB
var/datum/action/innate/blobpop/pop_action
@@ -57,3 +58,10 @@
owner.mind.transfer_to(B)
old_body.gib()
B.place_blob_core(blobtag.point_rate_human_blob, pop_override = TRUE)
/datum/antagonist/blob/antag_listing_status()
. = ..()
if(owner && owner.current)
var/mob/camera/blob/B = owner.current
if(istype(B))
. += "(Progress: [B.blobs_legit.len]/[B.blobwincount])"

View File

@@ -1,12 +1,10 @@
/datum/antagonist/brother
name = "Brother"
antagpanel_category = "Brother"
job_rank = ROLE_BROTHER
var/special_role = "blood brother"
var/datum/team/brother_team/team
/datum/antagonist/brother/New(datum/mind/new_owner)
return ..()
/datum/antagonist/brother/create_team(datum/team/brother_team/new_team)
if(!new_team)
return
@@ -36,7 +34,7 @@
if(!owner.current || !team || !team.meeting_area)
return
to_chat(owner.current, "<B>Your designated meeting area:</B> [team.meeting_area]")
owner.store_memory("<b>Meeting Area</b>: [team.meeting_area]")
antag_memory += "<b>Meeting Area</b>: [team.meeting_area]<br>"
/datum/antagonist/brother/greet()
var/brother_text = ""
@@ -56,15 +54,42 @@
/datum/antagonist/brother/proc/finalize_brother()
SSticker.mode.update_brother_icons_added(owner)
/datum/antagonist/brother/admin_add(datum/mind/new_owner,mob/admin)
//show list of possible brothers
var/list/candidates = list()
for(var/mob/living/L in GLOB.alive_mob_list)
if(!L.mind || L.mind == new_owner || !can_be_owned(L.mind))
continue
candidates[L.mind.name] = L.mind
var/choice = input(admin,"Choose the blood brother.", "Brother") as null|anything in candidates
if(!choice)
return
var/datum/mind/bro = candidates[choice]
var/datum/team/brother_team/T = new
T.add_member(new_owner)
T.add_member(bro)
T.pick_meeting_area()
T.forge_brother_objectives()
new_owner.add_antag_datum(ANTAG_DATUM_BROTHER,T)
bro.add_antag_datum(ANTAG_DATUM_BROTHER, T)
T.update_name()
message_admins("[key_name_admin(admin)] made [new_owner.current] and [bro.current] into blood brothers.")
log_admin("[key_name(admin)] made [new_owner.current] and [bro.current] into blood brothers.")
/datum/team/brother_team
name = "brotherhood"
member_name = "blood brother"
var/meeting_area
var/static/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library")
/datum/team/brother_team/is_solo()
return FALSE
/datum/team/brother_team/proc/pick_meeting_area()
meeting_area = pick(meeting_areas)
meeting_areas -= meeting_area
/datum/team/brother_team/proc/update_name()
var/list/last_names = list()
for(var/datum/mind/M in members)
@@ -123,3 +148,6 @@
add_objective(new/datum/objective/assassinate, TRUE)
else
add_objective(new/datum/objective/steal, TRUE)
/datum/team/brother_team/antag_listing_name()
return "[name] blood brothers"

View File

@@ -5,6 +5,7 @@
/datum/antagonist/changeling
name = "Changeling"
roundend_category = "changelings"
antagpanel_category = "Changeling"
job_rank = ROLE_CHANGELING
var/you_are_greet = TRUE
@@ -40,11 +41,6 @@
var/static/list/all_powers = typecacheof(/obj/effect/proc_holder/changeling,TRUE)
/datum/antagonist/changeling/New()
. = ..()
generate_name()
create_actions()
/datum/antagonist/changeling/Destroy()
QDEL_NULL(cellular_emporium)
QDEL_NULL(emporium_action)
@@ -68,6 +64,8 @@
emporium_action = new(cellular_emporium)
/datum/antagonist/changeling/on_gain()
generate_name()
create_actions()
reset_powers()
create_initial_profile()
if(give_objectives)
@@ -340,6 +338,9 @@
owner.announce_objectives()
/datum/antagonist/changeling/farewell()
to_chat(owner.current, "<span class='userdanger'>You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!</span>")
/datum/antagonist/changeling/proc/forge_team_objectives()
if(GLOB.changeling_team_objective_type)
var/datum/objective/changeling_team_objective/team_objective = new GLOB.changeling_team_objective_type
@@ -436,6 +437,25 @@
hud.leave_hud(owner.current)
set_antag_hud(owner.current, null)
/datum/antagonist/changeling/admin_add(datum/mind/new_owner,mob/admin)
. = ..()
to_chat(new_owner.current, "<span class='boldannounce'>Our powers have awoken. A flash of memory returns to us...we are [changelingID], a changeling!</span>")
/datum/antagonist/changeling/get_admin_commands()
. = ..()
if(stored_profiles.len && (owner.current.real_name != first_prof.name))
.["Transform to initial appearance."] = CALLBACK(src,.proc/admin_restore_appearance)
/datum/antagonist/changeling/proc/admin_restore_appearance(mob/admin)
if(!stored_profiles.len || !iscarbon(owner.current))
to_chat(admin, "<span class='danger'>Resetting DNA failed!</span>")
else
var/mob/living/carbon/C = owner.current
first_prof.dna.transfer_identity(C, transfer_SE=1)
C.real_name = first_prof.name
C.updateappearance(mutcolor_update=1)
C.domutcheck()
// Profile
/datum/changelingprofile
@@ -510,3 +530,9 @@
parts += "<span class='redtext'>The changeling has failed.</span>"
return parts.Join("<br>")
/datum/antagonist/changeling/antag_listing_name()
return ..() + "([changelingID])"
/datum/antagonist/changeling/xenobio/antag_listing_name()
return ..() + "(Xenobio)"

View File

@@ -2,6 +2,7 @@
/datum/antagonist/clockcult
name = "Clock Cultist"
roundend_category = "clock cultists"
antagpanel_category = "Clockcult"
job_rank = ROLE_SERVANT_OF_RATVAR
var/datum/action/innate/hierophant/hierophant_network = new()
var/datum/team/clockcult/clock_team
@@ -9,6 +10,7 @@
/datum/antagonist/clockcult/silent
silent = TRUE
show_in_antagpanel = FALSE //internal
/datum/antagonist/clockcult/Destroy()
qdel(hierophant_network)
@@ -21,6 +23,8 @@
if(!new_team && make_team)
//TODO blah blah same as the others, allow multiple
for(var/datum/antagonist/clockcult/H in GLOB.antagonists)
if(!H.owner)
continue
if(H.clock_team)
clock_team = H.clock_team
return
@@ -33,28 +37,7 @@
/datum/antagonist/clockcult/can_be_owned(datum/mind/new_owner)
. = ..()
if(.)
if(iscyborg(new_owner.current))
var/mob/living/silicon/robot/R = new_owner.current
if(R.deployed)
var/mob/living/silicon/ai/AI = R.mainframe
R.undeploy()
to_chat(AI, "<span class='userdanger'>Anomaly Detected. Returned to core!</span>") //The AI needs to be in its core to properly be converted
. = is_eligible_servant(new_owner.current)
if(!silent && new_owner.current)
if(.)
to_chat(new_owner.current, "<span class='heavy_brass'>The world before you suddenly glows a brilliant yellow. [issilicon(new_owner.current) ? "You cannot compute this truth!" : \
"Your mind is racing!"] You hear the whooshing steam and cl[pick("ank", "ink", "unk", "ang")]ing cogs of a billion billion machines, and all at once it comes to you.<br>\
Ratvar, the Clockwork Justiciar, [GLOB.ratvar_awakens ? "has been freed from his eternal prison" : "lies in exile, derelict and forgotten in an unseen realm"].</span>")
flash_color(new_owner.current, flash_color = list("#BE8700", "#BE8700", "#BE8700", rgb(0,0,0)), flash_time = 50)
else
new_owner.current.visible_message("<span class='boldwarning'>[new_owner.current] seems to resist an unseen force!</span>", null, null, 7, new_owner.current)
to_chat(new_owner.current, "<span class='heavy_brass'>The world before you suddenly glows a brilliant yellow. [issilicon(new_owner.current) ? "You cannot compute this truth!" : \
"Your mind is racing!"] You hear the whooshing steam and cl[pick("ank", "ink", "unk", "ang")]ing cogs of a billion billion machines, and the sound</span> <span class='boldwarning'>\
is a meaningless cacophony.</span><br>\
<span class='userdanger'>You see an abomination of rusting parts[GLOB.ratvar_awakens ? ", and it is here.<br>It is too late" : \
" in an endless grey void.<br>It cannot be allowed to escape"].</span>")
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/clockcultalr.ogg', 40, TRUE, frequency = 100000, pressure_affected = FALSE)
flash_color(new_owner.current, flash_color = list("#BE8700", "#BE8700", "#BE8700", rgb(0,0,0)), flash_time = 5)
/datum/antagonist/clockcult/greet()
if(!owner.current || silent)
@@ -85,7 +68,7 @@
to_chat(current, "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>")
..()
to_chat(current, "<b>This is Ratvar's will:</b> [CLOCKCULT_OBJECTIVE]")
owner.memory += "<b>Ratvar's will:</b> [CLOCKCULT_OBJECTIVE]<br>" //Memorize the objectives
antag_memory += "<b>Ratvar's will:</b> [CLOCKCULT_OBJECTIVE]<br>" //Memorize the objectives
/datum/antagonist/clockcult/apply_innate_effects(mob/living/mob_override)
. = ..()
@@ -178,13 +161,32 @@
owner.current.visible_message("<span class='deconversion_message'>[owner] seems to have remembered their true allegiance!</span>", ignored_mob = owner.current)
to_chat(owner, "<span class='userdanger'>A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.</span>")
owner.current.log_message("<font color=#BE8700>Has renounced the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
owner.wipe_memory()
owner.special_role = null
if(iscyborg(owner.current))
to_chat(owner.current, "<span class='warning'>Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.</span>")
. = ..()
/datum/antagonist/clockcult/admin_add(datum/mind/new_owner,mob/admin)
add_servant_of_ratvar(new_owner.current, TRUE)
message_admins("[key_name_admin(admin)] has made [new_owner.current] into a servant of Ratvar.")
log_admin("[key_name(admin)] has made [new_owner.current] into a servant of Ratvar.")
/datum/antagonist/clockcult/admin_remove(mob/user)
remove_servant_of_ratvar(owner.current, TRUE)
message_admins("[key_name_admin(user)] has removed clockwork servant status from [owner.current].")
log_admin("[key_name(user)] has removed clockwork servant status from [owner.current].")
/datum/antagonist/clockcult/get_admin_commands()
. = ..()
.["Give slab"] = CALLBACK(src,.proc/admin_give_slab)
/datum/antagonist/clockcult/proc/admin_give_slab(mob/admin)
if(!SSticker.mode.equip_servant(owner.current))
to_chat(admin, "<span class='warning'>Failed to outfit [owner.current]!</span>")
else
to_chat(admin, "<span class='notice'>Successfully gave [owner.current] servant equipment!</span>")
/datum/team/clockcult
name = "Clockcult"
var/list/objective

View File

@@ -3,6 +3,7 @@
/datum/antagonist/cult
name = "Cultist"
roundend_category = "cultists"
antagpanel_category = "Cult"
var/datum/action/innate/cult/comm/communion = new
var/datum/action/innate/cult/mastervote/vote = new
job_rank = ROLE_CULTIST
@@ -18,6 +19,8 @@
if(!new_team)
//todo remove this and allow admin buttons to create more than one cult
for(var/datum/antagonist/cult/H in GLOB.antagonists)
if(!H.owner)
continue
if(H.cult_team)
cult_team = H.cult_team
return
@@ -127,7 +130,6 @@
/datum/antagonist/cult/on_removal()
remove_objectives()
owner.wipe_memory()
SSticker.mode.cult -= owner
SSticker.mode.update_cult_icons_removed(owner)
if(!silent)
@@ -138,11 +140,36 @@
owner.current.client.images -= cult_team.blood_target_image
. = ..()
/datum/antagonist/cult/admin_add(datum/mind/new_owner,mob/admin)
give_equipment = FALSE
new_owner.add_antag_datum(src)
message_admins("[key_name_admin(admin)] has cult'ed [new_owner.current].")
log_admin("[key_name(admin)] has cult'ed [new_owner.current].")
/datum/antagonist/cult/admin_remove(mob/user)
message_admins("[key_name_admin(user)] has decult'ed [owner.current].")
log_admin("[key_name(user)] has decult'ed [owner.current].")
SSticker.mode.remove_cultist(owner,silent=TRUE) //disgusting
/datum/antagonist/cult/get_admin_commands()
. = ..()
.["Tome"] = CALLBACK(src,.proc/admin_give_tome)
.["Amulet"] = CALLBACK(src,.proc/admin_give_amulet)
/datum/antagonist/cult/proc/admin_give_tome(mob/admin)
if(equip_cultist(owner.current,1))
to_chat(admin, "<span class='danger'>Spawning tome failed!</span>")
/datum/antagonist/cult/proc/admin_give_amulet(mob/admin)
if (equip_cultist(owner.current))
to_chat(admin, "<span class='danger'>Spawning amulet failed!</span>")
/datum/antagonist/cult/master
ignore_implant = TRUE
show_in_antagpanel = FALSE //Feel free to add this later
var/datum/action/innate/cult/master/finalreck/reckoning = new
var/datum/action/innate/cult/master/cultmark/bloodmark = new
var/datum/action/innate/cult/master/pulse/throwing = new
ignore_implant = TRUE
/datum/antagonist/cult/master/Destroy()
QDEL_NULL(reckoning)
@@ -297,3 +324,6 @@
parts += printplayerlist(members)
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
/datum/team/cult/is_gamemode_hero()
return SSticker.mode.name == "cult"

View File

@@ -1,8 +1,9 @@
/datum/antagonist/traitor
name = "Traitor"
roundend_category = "traitors"
antagpanel_category = "Traitor"
job_rank = ROLE_TRAITOR
var/should_specialise = FALSE //do we split into AI and human, set to true on inital assignment only
var/should_specialise = TRUE //do we split into AI and human, set to true on inital assignment only
var/ai_datum = ANTAG_DATUM_TRAITOR_AI
var/human_datum = ANTAG_DATUM_TRAITOR_HUMAN
var/special_role = "traitor"
@@ -10,23 +11,28 @@
var/give_objectives = TRUE
var/should_give_codewords = TRUE
/datum/antagonist/traitor/human
show_in_antagpanel = FALSE
should_specialise = FALSE
var/should_equip = TRUE
/datum/antagonist/traitor/AI
/datum/antagonist/traitor/proc/specialise()
silent = TRUE
if(owner.current && isAI(owner.current))
owner.add_antag_datum(ai_datum)
/datum/antagonist/traitor/AI
show_in_antagpanel = FALSE
should_specialise = FALSE
/datum/antagonist/traitor/specialization(datum/mind/new_owner)
if(should_specialise)
if(new_owner.current && isAI(new_owner.current))
return new ai_datum()
else
return new human_datum()
else
owner.add_antag_datum(human_datum)
on_removal()
return ..()
/datum/antagonist/traitor/on_gain()
if(should_specialise)
specialise()
return
SSticker.mode.traitors += owner
owner.special_role = special_role
if(give_objectives)
@@ -49,8 +55,6 @@
traitor_mob.dna.add_mutation(CLOWNMUT)
/datum/antagonist/traitor/on_removal()
if(should_specialise)
return ..()//we never did any of this anyway
SSticker.mode.traitors -= owner
for(var/O in objectives)
owner.objectives -= O
@@ -79,6 +83,7 @@
/datum/antagonist/traitor/proc/forge_traitor_objectives()
return
/datum/antagonist/traitor/human/forge_traitor_objectives()
var/is_hijacker = prob(10)
var/martyr_chance = prob(20)
@@ -229,8 +234,8 @@
to_chat(traitor_mob, "<B>Code Phrase</B>: <span class='danger'>[GLOB.syndicate_code_phrase]</span>")
to_chat(traitor_mob, "<B>Code Response</B>: <span class='danger'>[GLOB.syndicate_code_response]</span>")
traitor_mob.mind.store_memory("<b>Code Phrase</b>: [GLOB.syndicate_code_phrase]")
traitor_mob.mind.store_memory("<b>Code Response</b>: [GLOB.syndicate_code_response]")
antag_memory += "<b>Code Phrase</b>: [GLOB.syndicate_code_phrase]<br>"
antag_memory += "<b>Code Response</b>: [GLOB.syndicate_code_response]<br>"
to_chat(traitor_mob, "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe.")
@@ -249,7 +254,7 @@
return
/datum/antagonist/traitor/human/equip(var/silent = FALSE)
owner.equip_traitor(employer, silent)
owner.equip_traitor(employer, silent, src)
/datum/antagonist/traitor/human/proc/assign_exchange_role()
//set faction
@@ -340,3 +345,6 @@
/datum/antagonist/traitor/roundend_report_footer()
return "<br><b>The code phrases were:</b> <span class='codephrase'>[GLOB.syndicate_code_phrase]</span><br>\
<b>The code responses were:</b> <span class='codephrase'>[GLOB.syndicate_code_response]</span><br>"
/datum/antagonist/traitor/is_gamemode_hero()
return SSticker.mode.name == "traitor"

View File

@@ -87,6 +87,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/datum/antagonist/devil
name = "Devil"
roundend_category = "devils"
antagpanel_category = "Devil"
job_rank = ROLE_DEVIL
//Don't delete upon mind destruction, otherwise soul re-selling will break.
delete_on_mind_deletion = FALSE
@@ -111,17 +112,35 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/obj/effect/proc_holder/spell/targeted/summon_dancefloor))
var/ascendable = FALSE
/datum/antagonist/devil/can_be_owned(datum/mind/new_owner)
. = ..()
return . && (ishuman(new_owner.current) || iscyborg(new_owner.current))
/datum/antagonist/devil/New()
..()
truename = randomDevilName()
ban = randomdevilban()
bane = randomdevilbane()
obligation = randomdevilobligation()
banish = randomdevilbanish()
GLOB.allDevils[lowertext(truename)] = src
/datum/antagonist/devil/get_admin_commands()
. = ..()
.["Toggle ascendable"] = CALLBACK(src,.proc/admin_toggle_ascendable)
/datum/antagonist/devil/proc/admin_toggle_ascendable(mob/admin)
ascendable = !ascendable
message_admins("[key_name_admin(admin)] set [owner.current] devil ascendable to [ascendable]")
log_admin("[key_name_admin(admin)] set [owner.current] devil ascendable to [ascendable])")
/datum/antagonist/devil/admin_add(datum/mind/new_owner,mob/admin)
switch(alert(admin,"Should the devil be able to ascend",,"Yes","No","Cancel"))
if("Yes")
ascendable = TRUE
if("No")
ascendable = FALSE
else
return
new_owner.add_antag_datum(src)
message_admins("[key_name_admin(admin)] has devil'ed [new_owner.current]. [ascendable ? "(Ascendable)":""]")
log_admin("[key_name(admin)] has devil'ed [new_owner.current]. [ascendable ? "(Ascendable)":""]")
/datum/antagonist/devil/antag_listing_name()
return ..() + "([truename])"
/proc/devilInfo(name)
if(GLOB.allDevils[lowertext(name)])
return GLOB.allDevils[lowertext(name)]
@@ -480,7 +499,14 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
.=..()
/datum/antagonist/devil/on_gain()
owner.store_memory("Your devilic true name is [truename]<br>[GLOB.lawlorify[LAW][ban]]<br>You may not use violence to coerce someone into selling their soul.<br>You may not directly and knowingly physically harm a devil, other than yourself.<br>[GLOB.lawlorify[LAW][bane]]<br>[GLOB.lawlorify[LAW][obligation]]<br>[GLOB.lawlorify[LAW][banish]]<br>")
truename = randomDevilName()
ban = randomdevilban()
bane = randomdevilbane()
obligation = randomdevilobligation()
banish = randomdevilbanish()
GLOB.allDevils[lowertext(truename)] = src
antag_memory += "Your devilic true name is [truename]<br>[GLOB.lawlorify[LAW][ban]]<br>You may not use violence to coerce someone into selling their soul.<br>You may not directly and knowingly physically harm a devil, other than yourself.<br>[GLOB.lawlorify[LAW][bane]]<br>[GLOB.lawlorify[LAW][obligation]]<br>[GLOB.lawlorify[LAW][banish]]<br>"
if(issilicon(owner.current))
var/mob/living/silicon/robot_devil = owner.current
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")

View File

@@ -5,32 +5,31 @@
#define TRAITOR_AGENT_ROLE "Syndicate External Affairs Agent"
/datum/antagonist/traitor/internal_affairs
name = "Internal Affairs Agent"
human_datum = ANTAG_DATUM_IAA_HUMAN
ai_datum = ANTAG_DATUM_IAA_AI
antagpanel_category = "IAA"
/datum/antagonist/traitor/AI/internal_affairs
name = "Internal Affairs Agent"
employer = "Nanotrasen"
special_role = "internal affairs agent"
antagpanel_category = "IAA"
var/syndicate = FALSE
var/last_man_standing = FALSE
var/list/datum/mind/targets_stolen
/datum/antagonist/traitor/AI/internal_affairs/custom
silent = TRUE
should_give_codewords = FALSE
give_objectives = FALSE
/datum/antagonist/traitor/human/internal_affairs
name = "Internal Affairs Agent"
employer = "Nanotrasen"
special_role = "internal affairs agent"
antagpanel_category = "IAA"
var/syndicate = FALSE
var/last_man_standing = FALSE
var/list/datum/mind/targets_stolen
/datum/antagonist/traitor/human/internal_affairs/proc/give_pinpointer()
if(owner && owner.current)
owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer)
@@ -292,6 +291,7 @@
/datum/antagonist/traitor/AI/internal_affairs/greet()
greet_iaa()
/datum/antagonist/traitor/human/internal_affairs/greet()
greet_iaa()

View File

@@ -7,7 +7,15 @@
name = "Monkey"
job_rank = ROLE_MONKEY
roundend_category = "monkeys"
antagpanel_category = "Monkey"
var/datum/team/monkey/monkey_team
var/monkey_only = TRUE
/datum/antagonist/monkey/can_be_owned(datum/mind/new_owner)
return ..() && (!monkey_only || ismonkey(new_owner.current))
/datum/antagonist/monkey/get_team()
return monkey_team
/datum/antagonist/monkey/on_gain()
. = ..()
@@ -29,13 +37,15 @@
SEND_SOUND(owner.current, sound('sound/ambience/antag/monkey.ogg'))
/datum/antagonist/monkey/on_removal()
. = ..()
owner.special_role = null
SSticker.mode.ape_infectees -= owner
var/datum/disease/D = (/datum/disease/transformation/jungle_fever in owner.current.viruses)
var/datum/disease/transformation/jungle_fever/D = locate() in owner.current.viruses
if(D)
D.cure()
D.remove_virus()
qdel(D)
. = ..()
/datum/antagonist/monkey/create_team(datum/team/monkey/new_team)
if(!new_team)
@@ -50,15 +60,45 @@
stack_trace("Wrong team type passed to [type] initialization.")
monkey_team = new_team
/datum/antagonist/monkey/get_team()
return monkey_team
/datum/antagonist/monkey/proc/forge_objectives()
objectives |= monkey_team.objectives
owner.objectives |= objectives
/datum/antagonist/monkey/admin_remove(mob/admin)
var/mob/living/carbon/monkey/M = owner.current
if(istype(M))
switch(alert(admin, "Humanize?", "Humanize", "Yes", "No"))
if("Yes")
if(admin == M)
admin = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
else
M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
if("No")
//nothing
else
return
. = ..()
/datum/antagonist/monkey/leader
name = "Monkey Leader"
monkey_only = FALSE
/datum/antagonist/monkey/leader/admin_add(datum/mind/new_owner,mob/admin)
var/mob/living/carbon/human/H = new_owner.current
if(istype(H))
switch(alert(admin, "Monkeyize?", "Monkeyize", "Yes", "No"))
if("Yes")
if(admin == H)
admin = H.monkeyize()
else
H.monkeyize()
if("No")
//nothing
else
return
new_owner.add_antag_datum(src)
log_admin("[key_name(admin)] made [key_name(new_owner.current)] a monkey leader!")
message_admins("[key_name_admin(admin)] made [key_name_admin(new_owner.current)] a monkey leader!")
/datum/antagonist/monkey/leader/on_gain()
. = ..()
@@ -68,11 +108,12 @@
owner.special_role = "Monkey Leader"
/datum/antagonist/monkey/leader/on_removal()
. = ..()
SSticker.mode.ape_leaders -= owner
var/obj/item/organ/heart/H = new
H.Insert(owner.current, drop_if_replaced = FALSE) //replace freedom heart with normal heart
. = ..()
/datum/antagonist/monkey/leader/greet()
to_chat(owner, "<B><span class='notice'>You are the Jungle Fever patient zero!!</B></span>")
to_chat(owner, "<b>You have been planted onto this station by the Animal Rights Consortium.</b>")

View File

@@ -1,31 +1,27 @@
/datum/antagonist/ninja
name = "Ninja"
antagpanel_category = "Ninja"
job_rank = ROLE_NINJA
var/helping_station = 0
var/helping_station = FALSE
var/give_objectives = TRUE
var/give_equipment = TRUE
/datum/antagonist/ninja/friendly
helping_station = 1
/datum/antagonist/ninja/friendly/noobjective
give_objectives = FALSE
/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
update_ninja_icons_added(M)
/datum/antagonist/ninja/New(datum/mind/new_owner)
if(new_owner && !ishuman(new_owner.current))//It's fine if we aren't passed a mind, but if we are, they have to be human.
throw EXCEPTION("Only humans and/or humanoids may be ninja'ed")
..(new_owner)
/datum/antagonist/ninja/randomAllegiance/New(datum/mind/new_owner)
..(new_owner)
helping_station = rand(0,1)
/datum/antagonist/ninja/remove_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
update_ninja_icons_removed(M)
/datum/antagonist/ninja/proc/equip_space_ninja(mob/living/carbon/human/H = owner.current)
return H.equipOutfit(/datum/outfit/ninja)
/datum/antagonist/ninja/proc/addMemories()
owner.store_memory("I am an elite mercenary assassin of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!")
owner.store_memory("Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!")
owner.store_memory("Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.")
antag_memory += "I am an elite mercenary assassin of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!<br>"
antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!<br>"
antag_memory += "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.<br>"
/datum/antagonist/ninja/proc/addObjectives(quantity = 6)
var/list/possible_targets = list()
@@ -103,11 +99,6 @@
datum.on_removal()
return TRUE
/proc/add_ninja(mob/living/carbon/human/H, type = ANTAG_DATUM_NINJA_RANDOM)
if(!H || !H.mind)
return FALSE
return H.mind.add_antag_datum(type)
/proc/is_ninja(mob/living/M)
return M && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_NINJA)
@@ -123,3 +114,42 @@
if(give_objectives)
addObjectives()
addMemories()
if(give_equipment)
equip_space_ninja(owner.current)
. = ..()
/datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin)
var/adj
switch(input("What kind of ninja?", "Ninja") as null|anything in list("Random","Syndicate","Nanotrasen","No objectives"))
if("Random")
helping_station = pick(TRUE,FALSE)
adj = ""
if("Syndicate")
helping_station = FALSE
adj = "syndie"
if("Nanotrasen")
helping_station = TRUE
adj = "friendly"
if("No objectives")
give_objectives = FALSE
adj = "objectiveless"
else
return
new_owner.assigned_role = "Space Ninja"
new_owner.special_role = "Space Ninja"
new_owner.add_antag_datum(src)
message_admins("[key_name_admin(admin)] has [adj] ninja'ed [new_owner.current].")
log_admin("[key_name(admin)] has [adj] ninja'ed [new_owner.current].")
/datum/antagonist/ninja/antag_listing_name()
return ..() + "(Ninja)"
/datum/antagonist/ninja/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/antagonist/ninja/proc/update_ninja_icons_removed(var/mob/living/carbon/human/ninja)
var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA]
ninjahud.leave_hud(ninja)
set_antag_hud(ninja, null)

View File

@@ -11,6 +11,7 @@
/datum/antagonist/nukeop
name = "Nuclear Operative"
roundend_category = "syndicate operatives" //just in case
antagpanel_category = "NukeOp"
job_rank = ROLE_OPERATIVE
var/datum/team/nuclear/nuke_team
var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team.
@@ -85,7 +86,7 @@
/datum/antagonist/nukeop/proc/memorize_code()
if(nuke_team && nuke_team.tracked_nuke && nuke_team.memorized_code)
owner.store_memory("<B>[nuke_team.tracked_nuke] Code</B>: [nuke_team.memorized_code]", 0, 0)
antag_memory += "<B>[nuke_team.tracked_nuke] Code</B>: [nuke_team.memorized_code]<br>"
to_chat(owner, "The nuclear authorization code is: <B>[nuke_team.memorized_code]</B>")
else
to_chat(owner, "Unfortunately the syndicate was unable to provide you with nuclear authorization code.")
@@ -107,6 +108,8 @@
if(!new_team)
if(!always_new_team)
for(var/datum/antagonist/nukeop/N in GLOB.antagonists)
if(!N.owner)
continue
if(N.nuke_team)
nuke_team = N.nuke_team
return
@@ -118,6 +121,32 @@
stack_trace("Wrong team type passed to [type] initialization.")
nuke_team = new_team
/datum/antagonist/nukeop/admin_add(datum/mind/new_owner,mob/admin)
new_owner.assigned_role = "Syndicate"
new_owner.add_antag_datum(src)
message_admins("[key_name_admin(admin)] has nuke op'ed [new_owner.current].")
log_admin("[key_name(admin)] has nuke op'ed [new_owner.current].")
/datum/antagonist/nukeop/get_admin_commands()
. = ..()
.["Send to base"] = CALLBACK(src,.proc/admin_send_to_base)
.["Tell code"] = CALLBACK(src,.proc/admin_tell_code)
/datum/antagonist/nukeop/proc/admin_send_to_base(mob/admin)
owner.current.forceMove(pick(GLOB.nukeop_start))
/datum/antagonist/nukeop/proc/admin_tell_code(mob/admin)
var/code
for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines)
if (length(bombue.r_code) <= 5 && bombue.r_code != initial(bombue.r_code))
code = bombue.r_code
break
if (code)
antag_memory += "<B>Syndicate Nuclear Bomb Code</B>: [code]<br>"
to_chat(owner.current, "The nuclear authorization code is: <B>[code]</B>")
else
to_chat(admin, "<span class='danger'>No valid nuke found!</span>")
/datum/antagonist/nukeop/leader
name = "Nuclear Operative Leader"
nukeop_outfit = /datum/outfit/syndicate/leader
@@ -201,6 +230,10 @@
stack_trace("Station self destruct ot found during lone op team creation.")
nuke_team.memorized_code = null
/datum/antagonist/nukeop/reinforcement
send_to_spawnpoint = FALSE
nukeop_outfit = /datum/outfit/syndicate/no_crystals
/datum/team/nuclear
var/syndicate_name
var/obj/machinery/nuclearbomb/tracked_nuke
@@ -316,3 +349,31 @@
parts += text
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
/datum/team/nuclear/antag_listing_name()
if(syndicate_name)
return "[syndicate_name] Syndicates"
else
return "Syndicates"
/datum/team/nuclear/antag_listing_entry()
var/disk_report = "<b>Nuclear Disk(s)</b><br>"
disk_report += "<table cellspacing=5>"
for(var/obj/item/disk/nuclear/N in GLOB.poi_list)
disk_report += "<tr><td>[N.name], "
var/atom/disk_loc = N.loc
while(!isturf(disk_loc))
if(ismob(disk_loc))
var/mob/M = disk_loc
disk_report += "carried by <a href='?_src_=holder;[HrefToken()];adminplayeropts=[REF(M)]'>[M.real_name]</a> "
if(isobj(disk_loc))
var/obj/O = disk_loc
disk_report += "in \a [O.name] "
disk_loc = disk_loc.loc
disk_report += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])</td><td><a href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(N)]'>FLW</a></td></tr>"
disk_report += "</table>"
var/common_part = ..()
return common_part + disk_report
/datum/team/nuclear/is_gamemode_hero()
return SSticker.mode.name == "nuclear emergency"

View File

@@ -2,6 +2,7 @@
name = "Space Pirate"
job_rank = ROLE_TRAITOR
roundend_category = "space pirates"
antagpanel_category = "Pirate"
var/datum/team/pirate/crew
/datum/antagonist/pirate/greet()
@@ -15,6 +16,8 @@
/datum/antagonist/pirate/create_team(datum/team/pirate/new_team)
if(!new_team)
for(var/datum/antagonist/pirate/P in GLOB.antagonists)
if(!P.owner)
continue
if(P.crew)
crew = P.crew
return

View File

@@ -4,16 +4,20 @@
/datum/antagonist/rev
name = "Revolutionary"
roundend_category = "revolutionaries" // if by some miracle revolutionaries without revolution happen
antagpanel_category = "Revolution"
job_rank = ROLE_REV
var/hud_type = "rev"
var/datum/team/revolution/rev_team
/datum/antagonist/rev/can_be_owned(datum/mind/new_owner)
. = ..()
if(new_owner.assigned_role in GLOB.command_positions)
return FALSE
if(new_owner.unconvertable)
return FALSE
if(.)
if(new_owner.assigned_role in GLOB.command_positions)
return FALSE
if(new_owner.unconvertable)
return FALSE
if(new_owner.current && new_owner.current.isloyal())
return FALSE
/datum/antagonist/rev/apply_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
@@ -26,9 +30,6 @@
/datum/antagonist/rev/proc/equip_rev()
return
/datum/antagonist/rev/New()
. = ..()
/datum/antagonist/rev/on_gain()
. = ..()
create_objectives()
@@ -47,6 +48,8 @@
if(!new_team)
//For now only one revolution at a time
for(var/datum/antagonist/rev/head/H in GLOB.antagonists)
if(!H.owner)
continue
if(H.rev_team)
rev_team = H.rev_team
return
@@ -73,12 +76,73 @@
var/datum/mind/old_owner = owner
silent = TRUE
owner.remove_antag_datum(/datum/antagonist/rev)
var/datum/antagonist/rev/head/new_revhead = new(old_owner)
var/datum/antagonist/rev/head/new_revhead = new()
new_revhead.silent = TRUE
old_owner.add_antag_datum(new_revhead,old_team)
new_revhead.silent = FALSE
to_chat(old_owner, "<span class='userdanger'>You have proved your devotion to revolution! You are a head revolutionary now!</span>")
/datum/antagonist/rev/get_admin_commands()
. = ..()
.["Promote"] = CALLBACK(src,.proc/admin_promote)
/datum/antagonist/rev/proc/admin_promote(mob/admin)
var/datum/mind/O = owner
promote()
message_admins("[key_name_admin(admin)] has head-rev'ed [O].")
log_admin("[key_name(admin)] has head-rev'ed [O].")
/datum/antagonist/rev/head/admin_add(datum/mind/new_owner,mob/admin)
give_flash = TRUE
give_hud = TRUE
remove_clumsy = TRUE
new_owner.add_antag_datum(src)
message_admins("[key_name_admin(admin)] has head-rev'ed [new_owner.current].")
log_admin("[key_name(admin)] has head-rev'ed [new_owner.current].")
to_chat(new_owner.current, "<span class='userdanger'>You are a member of the revolutionaries' leadership now!</span>")
/datum/antagonist/rev/head/get_admin_commands()
. = ..()
. -= "Promote"
.["Take flash"] = CALLBACK(src,.proc/admin_take_flash)
.["Give flash"] = CALLBACK(src,.proc/admin_give_flash)
.["Repair flash"] = CALLBACK(src,.proc/admin_repair_flash)
.["Demote"] = CALLBACK(src,.proc/admin_demote)
/datum/antagonist/rev/head/proc/admin_take_flash(mob/admin)
var/list/L = owner.current.get_contents()
var/obj/item/device/assembly/flash/flash = locate() in L
if (!flash)
to_chat(admin, "<span class='danger'>Deleting flash failed!</span>")
return
qdel(flash)
/datum/antagonist/rev/head/proc/admin_give_flash(mob/admin)
//This is probably overkill but making these impact state annoys me
var/old_give_flash = give_flash
var/old_give_hud = give_hud
var/old_remove_clumsy = remove_clumsy
give_flash = TRUE
give_hud = FALSE
remove_clumsy = FALSE
equip_rev()
give_flash = old_give_flash
give_hud = old_give_hud
remove_clumsy = old_remove_clumsy
/datum/antagonist/rev/head/proc/admin_repair_flash(mob/admin)
var/list/L = owner.current.get_contents()
var/obj/item/device/assembly/flash/flash = locate() in L
if (!flash)
to_chat(admin, "<span class='danger'>Repairing flash failed!</span>")
else
flash.crit_fail = 0
flash.update_icon()
/datum/antagonist/rev/head/proc/admin_demote(datum/mind/target,mob/user)
message_admins("[key_name_admin(user)] has demoted [owner.current] from head revolutionary.")
log_admin("[key_name(user)] has demoted [owner.current] from head revolutionary.")
demote()
/datum/antagonist/rev/head
name = "Head Revolutionary"
@@ -87,6 +151,9 @@
var/give_flash = FALSE
var/give_hud = TRUE
/datum/antagonist/rev/head/antag_listing_name()
return ..() + "(Leader)"
/datum/antagonist/rev/proc/update_rev_icons_added(mob/living/M)
var/datum/atom_hud/antag/revhud = GLOB.huds[ANTAG_HUD_REV]
revhud.join_hud(M)
@@ -105,8 +172,6 @@
var/mob/living/carbon/C = candidate //Check to see if the potential rev is implanted
if(!istype(C)) //Can't convert simple animals
return FALSE
if(C.isloyal())
return FALSE
return TRUE
/datum/antagonist/rev/proc/add_revolutionary(datum/mind/rev_mind,stun = TRUE)
@@ -127,7 +192,7 @@
var/old_team = rev_team
silent = TRUE
owner.remove_antag_datum(/datum/antagonist/rev/head)
var/datum/antagonist/rev/new_rev = new /datum/antagonist/rev(old_owner)
var/datum/antagonist/rev/new_rev = new /datum/antagonist/rev()
new_rev.silent = TRUE
old_owner.add_antag_datum(new_rev,old_team)
new_rev.silent = FALSE
@@ -280,3 +345,24 @@
result += "</div>"
return result.Join()
/datum/team/revolution/antag_listing_entry()
var/common_part = ..()
var/heads_report = "<b>Heads of Staff</b><br>"
heads_report += "<table cellspacing=5>"
for(var/datum/mind/N in SSjob.get_living_heads())
var/mob/M = N.current
if(M)
heads_report += "<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>"
heads_report += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
heads_report += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(M)]'>FLW</a></td>"
var/turf/mob_loc = get_turf(M)
heads_report += "<td>[mob_loc.loc]</td></tr>"
else
heads_report += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=[REF(N)]'>[N.name]([N.key])</a><i>Head body destroyed!</i></td>"
heads_report += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
heads_report += "</table>"
return common_part + heads_report
/datum/team/revolution/is_gamemode_hero()
return SSticker.mode.name == "revolution"

View File

@@ -6,6 +6,7 @@
/datum/antagonist/wizard
name = "Space Wizard"
roundend_category = "wizards/witches"
antagpanel_category = "Wizard"
job_rank = ROLE_WIZARD
var/give_objectives = TRUE
var/strip = TRUE //strip before equipping
@@ -167,6 +168,14 @@
update_wiz_icons_removed(M)
M.faction -= "wizard"
/datum/antagonist/wizard/get_admin_commands()
. = ..()
.["Send to Lair"] = CALLBACK(src,.proc/admin_send_to_lair)
/datum/antagonist/wizard/proc/admin_send_to_lair(mob/admin)
owner.current.forceMove(pick(GLOB.wizardstart))
/datum/antagonist/wizard/apprentice
name = "Wizard Apprentice"
hud_version = "apprentice"

View File

@@ -740,28 +740,6 @@
src.give_disease(M)
href_list["datumrefresh"] = href_list["give_spell"]
else if(href_list["ninja"])
if(!check_rights(R_FUN))
return
var/mob/living/carbon/human/M = locate(href_list["ninja"]) in GLOB.carbon_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
if(tgalert(usr, "Are you sure you want to make [M] into a ninja?", "Confirmation", "Yes", "No") == "No")
return
if(!M.mind)
M.mind_initialize()
var/datum/antagonist/ninja/hiyah = M.mind.has_antag_datum(/datum/antagonist/ninja)
if(!hiyah)
hiyah = add_ninja(M)
if(hiyah)
hiyah.equip_space_ninja()
href_list["datumrefresh"] = href_list["ninja"]
else if(href_list["gib"])
if(!check_rights(R_FUN))
return

View File

@@ -88,7 +88,7 @@
stage5 = list("<span class='warning'>You feel like monkeying around.</span>")
/datum/disease/transformation/jungle_fever/do_disease_transformation(mob/living/carbon/affected_mob)
if(affected_mob.mind && !is_monkey(affected_mob))
if(affected_mob.mind && !is_monkey(affected_mob.mind))
add_monkey(affected_mob.mind)
if(ishuman(affected_mob))
var/mob/living/carbon/monkey/M = affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)

View File

@@ -140,10 +140,16 @@
if(!istype(A))
return
else
A = new datum_type_or_instance(src, team)
A = new datum_type_or_instance()
//Choose snowflake variation if antagonist handles it
var/datum/antagonist/S = A.specialization(src)
if(S && S != A)
qdel(A)
A = S
if(!A.can_be_owned(src))
qdel(A)
return
A.owner = src
LAZYADD(antag_datums, A)
A.create_team(team)
var/datum/team/antag_team = A.get_team()
@@ -242,7 +248,7 @@
SSticker.mode.update_traitor_icons_removed(src)
SSticker.mode.update_cult_icons_removed(src)
/datum/mind/proc/equip_traitor(var/employer = "The Syndicate", var/silent = FALSE)
/datum/mind/proc/equip_traitor(employer = "The Syndicate", silent = FALSE, datum/antagonist/uplink_owner)
if(!current)
return
var/mob/living/carbon/human/traitor_mob = current
@@ -289,27 +295,32 @@
. = 0
else
uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key)
var/unlock_note
if(uplink_loc == R)
R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
if(!silent)
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Radio Frequency:</B> [format_frequency(R.traitor_frequency)] ([R.name]).")
unlock_note = "<B>Radio Frequency:</B> [format_frequency(R.traitor_frequency)] ([R.name])."
else if(uplink_loc == PDA)
PDA.lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
if(!silent)
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Uplink Passcode:</B> [PDA.lock_code] ([PDA.name]).")
unlock_note = "<B>Uplink Passcode:</B> [PDA.lock_code] ([PDA.name])."
else if(uplink_loc == P)
P.traitor_unlock_degrees = rand(1, 360)
if(!silent)
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Uplink Degrees:</B> [P.traitor_unlock_degrees] ([P.name]).")
unlock_note = "<B>Uplink Degrees:</B> [P.traitor_unlock_degrees] ([P.name])."
if(uplink_owner)
uplink_owner.antag_memory += unlock_note + "<br>"
else
traitor_mob.mind.store_memory(unlock_note)
//Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does.
@@ -326,7 +337,7 @@
else if(is_nuclear_operative(creator))
var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)
var/datum/antagonist/nukeop/N = new(src)
var/datum/antagonist/nukeop/N = new()
N.send_to_spawnpoint = FALSE
N.nukeop_outfit = null
add_antag_datum(N,converter.nuke_team)
@@ -347,6 +358,10 @@
var/output = "<B>[current.real_name]'s Memories:</B><br>"
output += memory
for(var/datum/antagonist/A in antag_datums)
output += A.antag_memory
if(objectives.len)
output += "<B>Objectives:</B>"
var/obj_count = 1
@@ -364,396 +379,21 @@
else if(objectives.len || memory)
to_chat(recipient, "<i>[output]</i>")
/datum/mind/proc/edit_memory()
if(!SSticker.HasRoundStarted())
alert("Not before round-start!", "Alert")
return
if(QDELETED(src) || QDELETED(current))
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/list/sections = list(
"traitor", // "traitorchan",
"changeling",
"nuclear",
"wizard",
"revolution",
"cult",
"clockcult",
"abductor",
"devil",
"ninja",
"monkey"
)
var/text = ""
/** TRAITOR ***/
text = "traitor"
if (SSticker.mode.config_tag=="traitor" || SSticker.mode.config_tag=="traitorchan" || SSticker.mode.config_tag=="traitorbro")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (src in SSticker.mode.traitors)
text += "<b>TRAITOR</b> | <a href='?src=[REF(src)];traitor=clear'>loyal</a>"
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=[REF(src)];traitor=autoobjectives'>Randomize</a>!"
else
text += "<a href='?src=[REF(src)];traitor=traitor'>traitor</a> | <b>LOYAL</b>"
if(current && current.client && (ROLE_TRAITOR in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["traitor"] = text
if(ishuman(current) || ismonkey(current))
/** BROTHER **/
text = "brother"
if(SSticker.mode.config_tag == "traitorbro")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(src in SSticker.mode.brothers)
text += "<b>Brother</b> | <a href='?src=[REF(src)];brother=clear'>no</a>"
if(current && current.client && (ROLE_BROTHER in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["brother"] = text
/** CHANGELING ***/
text = "changeling"
if (SSticker.mode.config_tag=="changeling" || SSticker.mode.config_tag=="traitorchan")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
if(C)
text += "<b>[C.name]</b> | <a href='?src=[REF(src)];changeling=clear'>No</a>"
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=[REF(src)];changeling=autoobjectives'>Randomize!</a>"
if(C.stored_profiles.len && (current.real_name != C.first_prof.name) )
text += "<br><a href='?src=[REF(src)];changeling=initialdna'>Transform to initial appearance.</a>"
else
text += "<a href='?src=[REF(src)];changeling=changeling'>yes</a> | <b>NO</b>"
if(current && current.client && (ROLE_CHANGELING in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["changeling"] = text
/** MONKEY ***/
text = "monkey"
if (SSticker.mode.config_tag=="monkey")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (ishuman(current))
if(is_monkey_leader(src))
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <a href='?src=[REF(src)];monkey=infected'>infected</a> <b>LEADER</b> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
else
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <a href='?src=[REF(src)];monkey=infected'>infected</a> | <a href='?src=[REF(src)];monkey=leader'>leader</a> | <b>HUMAN</b> | other"
else if(ismonkey(current))
var/found = FALSE
for(var/datum/disease/transformation/jungle_fever/JF in current.viruses)
found = TRUE
break
var/isLeader = is_monkey_leader(src)
if(isLeader)
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <a href='?src=[REF(src)];monkey=infected'>infected</a> <b>LEADER</b> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
else if(found)
text += "<a href='?src=[REF(src)];monkey=healthy'>healthy</a> | <b>INFECTED</b> | <a href='?src=[REF(src)];monkey=leader'>leader</a> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
else
text += "<b>HEALTHY</b> | <a href='?src=[REF(src)];monkey=infected'>infected</a> | <a href='?src=[REF(src)];monkey=leader'>leader</a> | <a href='?src=[REF(src)];monkey=human'>human</a> | other"
else
text += "healthy | infected | leader | human | <b>OTHER</b>"
if(current && current.client && (ROLE_MONKEY in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["monkey"] = text
if(ishuman(current))
/** NUCLEAR ***/
text = "nuclear"
if (SSticker.mode.config_tag=="nuclear")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
var/datum/antagonist/nukeop/N = has_antag_datum(/datum/antagonist/nukeop,TRUE)
if(N)
text += "<b>OPERATIVE</b> | <a href='?src=[REF(src)];nuclear=clear'>nanotrasen</a>"
text += "<br><a href='?src=[REF(src)];nuclear=lair'>To shuttle</a>, <a href='?src=[REF(src)];common=undress'>undress</a>, <a href='?src=[REF(src)];nuclear=dressup'>dress up</a>."
var/code
for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines)
if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
code = bombue.r_code
break
if (code)
text += " Code is [code]. <a href='?src=[REF(src)];nuclear=tellcode'>tell the code.</a>"
else
text += "<a href='?src=[REF(src)];nuclear=nuclear'>operative</a> | <b>NANOTRASEN</b>"
if(current && current.client && (ROLE_OPERATIVE in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["nuclear"] = text
/** WIZARD ***/
text = "wizard"
if (SSticker.mode.config_tag=="wizard")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (has_antag_datum(/datum/antagonist/wizard))
text += "<b>YES</b> | <a href='?src=[REF(src)];wizard=clear'>no</a>"
text += "<br><a href='?src=[REF(src)];wizard=lair'>To lair</a>, <a href='?src=[REF(src)];common=undress'>undress</a>"
else
text += "<a href='?src=[REF(src)];wizard=wizard'>yes</a> | <b>NO</b>"
if(current && current.client && (ROLE_WIZARD in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["wizard"] = text
/** REVOLUTION ***/
text = "revolution"
if (SSticker.mode.config_tag=="revolution")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (assigned_role in GLOB.command_positions)
text += "<b>HEAD</b> | not mindshielded | employee | headrev | rev"
else if (has_antag_datum(/datum/antagonist/rev/head))
var/datum/antagonist/rev/head = has_antag_datum(/datum/antagonist/rev/head)
var/last_healthy_headrev = TRUE
for(var/datum/mind/I in head.rev_team.head_revolutionaries())
if(I == src)
continue
var/mob/M = I.current
if(M && is_station_level(M.z) && !M.stat)
last_healthy_headrev = FALSE
break
text += "head | not mindshielded | <a href='?src=[REF(src)];revolution=clear'>employee</a> | <b>[last_healthy_headrev ? "<font color='red'>LAST </font> " : ""]HEADREV</b> | <a href='?src=[REF(src)];revolution=rev'>rev</a>"
text += "<br>Flash: <a href='?src=[REF(src)];revolution=flash'>give</a>"
var/list/L = current.get_contents()
var/obj/item/device/assembly/flash/flash = locate() in L
if (flash)
if(!flash.crit_fail)
text += " | <a href='?src=[REF(src)];revolution=takeflash'>take</a>."
else
text += " | <a href='?src=[REF(src)];revolution=takeflash'>take</a> | <a href='?src=[REF(src)];revolution=repairflash'>repair</a>."
else
text += "."
text += " <a href='?src=[REF(src)];revolution=reequip'>Reequip</a> (gives traitor uplink)."
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=[REF(src)];revolution=autoobjectives'>Set to kill all heads</a>."
else if(current.isloyal())
text += "head | <b>MINDSHIELDED</b> | employee | <a href='?src=[REF(src)];revolution=headrev'>headrev</a> | rev"
else if (has_antag_datum(/datum/antagonist/rev))
text += "head | not mindshielded | <a href='?src=[REF(src)];revolution=clear'>employee</a> | <a href='?src=[REF(src)];revolution=headrev'>headrev</a> | <b>REV</b>"
else
text += "head | not mindshielded | <b>EMPLOYEE</b> | <a href='?src=[REF(src)];revolution=headrev'>headrev</a> | <a href='?src=[REF(src)];revolution=rev'>rev</a>"
if(current && current.client && (ROLE_REV in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["revolution"] = text
/** ABDUCTION **/
text = "abductor"
if(SSticker.mode.config_tag == "abductor")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(src in SSticker.mode.abductors)
text += "<b>Abductor</b> | <a href='?src=[REF(src)];abductor=clear'>human</a>"
text += " | <a href='?src=[REF(src)];common=undress'>undress</a> | <a href='?src=[REF(src)];abductor=equip'>equip</a>"
if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["abductor"] = text
/** DEVIL ***/
text = "devil"
if(SSticker.mode.config_tag == "devil")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
var/datum/antagonist/devil/devilinfo = has_antag_datum(ANTAG_DATUM_DEVIL)
if(devilinfo)
if(!devilinfo.ascendable)
text += "<b>DEVIL</b> | <a href='?src=[REF(src)];devil=ascendable_devil'>ascendable devil</a> | sintouched | <a href='?src=[REF(src)];devil=clear'>human</a>"
else
text += "<a href='?src=[REF(src)];devil=devil'>DEVIL</a> | <b>ASCENDABLE DEVIL</b> | sintouched | <a href='?src=[REF(src)];devil=clear'>human</a>"
else if(src in SSticker.mode.sintouched)
text += "devil | ascendable devil | <b>SINTOUCHED</b> | <a href='?src=[REF(src)];devil=clear'>human</a>"
else
text += "<a href='?src=[REF(src)];devil=devil'>devil</a> | <a href='?src=[REF(src)];devil=ascendable_devil'>ascendable devil</a> | <a href='?src=[REF(src)];devil=sintouched'>sintouched</a> | <b>HUMAN</b>"
if(current && current.client && (ROLE_DEVIL in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["devil"] = text
/** NINJA ***/
text = "ninja"
if(SSticker.mode.config_tag == "ninja")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
var/datum/antagonist/ninja/ninjainfo = has_antag_datum(ANTAG_DATUM_NINJA)
if(ninjainfo)
if(ninjainfo.helping_station)
text += "<a href='?src=[REF(src)];ninja=clear'>employee</a> | syndicate | <b>NANOTRASEN</b> | <b><a href='?src=[REF(src)];ninja=equip'>EQUIP</a></b>"
else
text += "<a href='?src=[REF(src)];ninja=clear'>employee</a> | <b>SYNDICATE</b> | nanotrasen | <b><a href='?src=[REF(src)];ninja=equip'>EQUIP</a></b>"
else
text += "<b>EMPLOYEE</b> | <a href='?src=[REF(src)];ninja=syndicate'>syndicate</a> | <a href='?src=[REF(src)];ninja=nanotrasen'>nanotrasen</a> | <a href='?src=[REF(src)];ninja=random'>random allegiance</a>"
if(current && current.client && (ROLE_NINJA in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["ninja"] = text
if(!issilicon(current))
/** CULT ***/
text = "cult"
if (SSticker.mode.config_tag=="cult")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(iscultist(current))
text += "not mindshielded | <a href='?src=[REF(src)];cult=clear'>employee</a> | <b>CULTIST</b>"
text += "<br>Give <a href='?src=[REF(src)];cult=tome'>tome</a> | <a href='?src=[REF(src)];cult=amulet'>amulet</a>."
else if(is_convertable_to_cult(current))
text += "not mindshielded | <b>EMPLOYEE</b> | <a href='?src=[REF(src)];cult=cultist'>cultist</a>"
else
text += "[!current.isloyal() ? "not mindshielded" : "<b>MINDSHIELDED</b>"] | <b>EMPLOYEE</b> | <i>cannot serve Nar-Sie</i>"
if(current && current.client && (ROLE_CULTIST in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["cult"] = text
if(ishuman(current) || issilicon(current))
/** CLOCKWORK CULT **/
text = "clockwork cult"
if(SSticker.mode.config_tag == "clockwork cult")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(is_servant_of_ratvar(current))
text += "not mindshielded | <a href='?src=[REF(src)];clockcult=clear'>employee</a> | <b>SERVANT</b>"
text += "<br><a href='?src=[REF(src)];clockcult=slab'>Equip</a>"
else if(is_eligible_servant(current))
text += "not mindshielded | <b>EMPLOYEE</b> | <a href='?src=[REF(src)];clockcult=servant'>servant</a>"
else
text += "[!current.isloyal() ? "not mindshielded" : "<b>MINDSHIELDED</b>"] | <b>EMPLOYEE</b> | <i>cannot serve Ratvar</i>"
if(current && current.client && (ROLE_SERVANT_OF_RATVAR in current.client.prefs.be_special))
text += " | Enabled in Prefs"
else
text += " | Disabled in Prefs"
sections["clockcult"] = text
/** SILICON ***/
if(issilicon(current))
text = "silicon"
var/mob/living/silicon/robot/robot = current
if (istype(robot) && robot.emagged)
text += "<br>Cyborg: Is emagged! <a href='?src=[REF(src)];silicon=unemag'>Unemag!</a><br>0th law: [robot.laws.zeroth]"
var/mob/living/silicon/ai/ai = current
if (istype(ai) && ai.connected_robots.len)
var/n_e_robots = 0
for (var/mob/living/silicon/robot/R in ai.connected_robots)
if (R.emagged)
n_e_robots++
text += "<br>[n_e_robots] of [ai.connected_robots.len] slaved cyborgs are emagged. <a href='?src=[REF(src)];silicon=unemagcyborgs'>Unemag</a>"
if (SSticker.mode.config_tag == "traitorchan")
if (sections["traitor"])
out += sections["traitor"]+"<br>"
if (sections["changeling"])
out += sections["changeling"]+"<br><br>"
sections -= "traitor"
sections -= "changeling"
else
if (sections[SSticker.mode.config_tag])
out += sections[SSticker.mode.config_tag]+"<br><br>"
sections -= SSticker.mode.config_tag
for (var/i in sections)
if (sections[i])
out += sections[i]+"<br>"
if(((src in SSticker.mode.traitors) || is_nuclear_operative(current)) && ishuman(current))
text = "Uplink: <a href='?src=[REF(src)];common=uplink'>give</a>"
var/datum/component/uplink/U = find_syndicate_uplink()
if(U)
text += " | <a href='?src=[REF(src)];common=takeuplink'>take</a>"
if (check_rights(R_FUN, 0))
text += ", <a href='?src=[REF(src)];common=crystals'>[U.telecrystals]</a> TC"
else
text += ", [U.telecrystals] TC"
text += "." //hiel grammar
out += text
out += "<br><br>"
out += "<b>Memory:</b><br>"
out += memory
out += "<br><a href='?src=[REF(src)];memory_edit=1'>Edit memory</a><br>"
out += "Objectives:<br>"
if (objectives.len == 0)
out += "EMPTY<br>"
else
var/obj_count = 1
for(var/datum/objective/objective in objectives)
out += "<B>[obj_count]</B>: [objective.explanation_text] <a href='?src=[REF(src)];obj_edit=[REF(objective)]'>Edit</a> <a href='?src=[REF(src)];obj_delete=[REF(objective)]'>Delete</a> <a href='?src=[REF(src)];obj_completed=[REF(objective)]'><font color=[objective.completed ? "green" : "red"]>[objective.completed ? "Mark as incomplete" : "Mark as complete"]</font></a><br>"
obj_count++
out += "<a href='?src=[REF(src)];obj_add=1'>Add objective</a><br><br>"
out += "<a href='?src=[REF(src)];obj_announce=1'>Announce objectives</a><br><br>"
var/datum/browser/popup = new(usr, "edit_memory", "", 600, 600)
popup.set_content(out)
popup.open()
//usr << browse(out, "window=edit_memory[src];size=575x600")
/datum/mind/Topic(href, href_list)
if(!check_rights(R_ADMIN))
return
var/self_antagging = usr == current
if(href_list["add_antag"])
add_antag_wrapper(text2path(href_list["add_antag"]),usr)
if(href_list["remove_antag"])
var/datum/antagonist/A = locate(href_list["remove_antag"]) in antag_datums
if(!istype(A))
to_chat(usr,"<span class='warning'>Invalid antagonist ref to be removed.</span>")
return
A.admin_remove(usr)
if (href_list["role_edit"])
var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in get_all_jobs()
if (!new_role)
@@ -771,8 +411,6 @@
var/objective_pos
var/def_value
var/datum/antagonist/target_antag
if (href_list["obj_edit"])
@@ -786,7 +424,7 @@
objective_pos = A.objectives.Find(objective)
break
if(!target_antag) //Shouldn't happen
if(!target_antag) //Shouldn't happen anymore
stack_trace("objective without antagonist found")
objective_pos = objectives.Find(objective)
@@ -796,19 +434,25 @@
if(!def_value)//If it's a custom objective, it will be an empty string.
def_value = "custom"
else
switch(antag_datums.len)
if(0)
target_antag = add_antag_datum(/datum/antagonist/custom)
if(1)
target_antag = antag_datums[1]
else
var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", def_value) as null|anything in antag_datums + "(new custom antag)"
if (QDELETED(target))
return
else if(target == "(new custom antag)")
//We're adding this objective
if(href_list["target_antag"])
var/datum/antagonist/X = locate(href_list["target_antag"]) in antag_datums
if(X)
target_antag = X
if(!target_antag)
switch(antag_datums.len)
if(0)
target_antag = add_antag_datum(/datum/antagonist/custom)
if(1)
target_antag = antag_datums[1]
else
target_antag = target
var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", def_value) as null|anything in antag_datums + "(new custom antag)"
if (QDELETED(target))
return
else if(target == "(new custom antag)")
target_antag = add_antag_datum(/datum/antagonist/custom)
else
target_antag = target
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom")
if (!new_obj_type)
@@ -957,344 +601,6 @@
objective.completed = !objective.completed
log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective.explanation_text]")
else if (href_list["revolution"])
switch(href_list["revolution"])
if("clear")
remove_rev()
message_admins("[key_name_admin(usr)] has de-rev'ed [current].")
log_admin("[key_name(usr)] has de-rev'ed [current].")
if("rev")
if(has_antag_datum(/datum/antagonist/rev/head))
var/datum/antagonist/rev/head/head = has_antag_datum(/datum/antagonist/rev/head)
head.demote()
else if(!has_antag_datum(/datum/antagonist/rev))
add_antag_datum(/datum/antagonist/rev)
special_role = "Revolutionary"
message_admins("[key_name_admin(usr)] has rev'ed [current].")
log_admin("[key_name(usr)] has rev'ed [current].")
else
return
if("headrev")
if(has_antag_datum(/datum/antagonist/rev))
var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev)
rev.promote()
else if(!has_antag_datum(/datum/antagonist/rev/head))
//what about the team here.
var/datum/antagonist/rev/head/new_head = new /datum/antagonist/rev/head(src)
new_head.give_flash = TRUE
new_head.give_hud = TRUE
new_head.remove_clumsy = TRUE
add_antag_datum(new_head)
to_chat(current, "<span class='userdanger'>You are a member of the revolutionaries' leadership now!</span>")
else
return
special_role = "Head Revolutionary"
message_admins("[key_name_admin(usr)] has head-rev'ed [current].")
log_admin("[key_name(usr)] has head-rev'ed [current].")
if("flash")
var/datum/antagonist/rev/head/head = has_antag_datum(/datum/antagonist/rev/head)
if(!head.equip_rev())
to_chat(usr, "<span class='danger'>Spawning flash failed!</span>")
if("takeflash")
var/list/L = current.get_contents()
var/obj/item/device/assembly/flash/flash = locate() in L
if (!flash)
to_chat(usr, "<span class='danger'>Deleting flash failed!</span>")
qdel(flash)
if("repairflash")
var/list/L = current.get_contents()
var/obj/item/device/assembly/flash/flash = locate() in L
if (!flash)
to_chat(usr, "<span class='danger'>Repairing flash failed!</span>")
else
flash.crit_fail = 0
flash.update_icon()
else if (href_list["cult"])
switch(href_list["cult"])
if("clear")
remove_cultist()
message_admins("[key_name_admin(usr)] has de-cult'ed [current].")
log_admin("[key_name(usr)] has de-cult'ed [current].")
if("cultist")
if(!(src in SSticker.mode.cult))
SSticker.mode.add_cultist(src, 0)
message_admins("[key_name_admin(usr)] has cult'ed [current].")
log_admin("[key_name(usr)] has cult'ed [current].")
if("tome")
var/datum/antagonist/cult/C = has_antag_datum(/datum/antagonist/cult,TRUE)
if (C.equip_cultist(current,1))
to_chat(usr, "<span class='danger'>Spawning tome failed!</span>")
if("amulet")
var/datum/antagonist/cult/C = has_antag_datum(/datum/antagonist/cult,TRUE)
if (C.equip_cultist(current))
to_chat(usr, "<span class='danger'>Spawning amulet failed!</span>")
else if(href_list["clockcult"])
switch(href_list["clockcult"])
if("clear")
remove_servant_of_ratvar(current, TRUE)
message_admins("[key_name_admin(usr)] has removed clockwork servant status from [current].")
log_admin("[key_name(usr)] has removed clockwork servant status from [current].")
if("servant")
if(!is_servant_of_ratvar(current))
add_servant_of_ratvar(current, TRUE)
message_admins("[key_name_admin(usr)] has made [current] into a servant of Ratvar.")
log_admin("[key_name(usr)] has made [current] into a servant of Ratvar.")
if("slab")
if(!SSticker.mode.equip_servant(current))
to_chat(usr, "<span class='warning'>Failed to outfit [current]!</span>")
else
to_chat(usr, "<span class='notice'>Successfully gave [current] servant equipment!</span>")
else if (href_list["wizard"])
switch(href_list["wizard"])
if("clear")
remove_wizard()
log_admin("[key_name(usr)] has de-wizard'ed [current].")
if("wizard")
if(!has_antag_datum(/datum/antagonist/wizard))
special_role = "Wizard"
add_antag_datum(/datum/antagonist/wizard)
message_admins("[key_name_admin(usr)] has wizard'ed [current].")
log_admin("[key_name(usr)] has wizard'ed [current].")
if("lair")
current.forceMove(pick(GLOB.wizardstart))
else if (href_list["changeling"])
switch(href_list["changeling"])
if("clear")
remove_antag_datum(/datum/antagonist/changeling)
special_role = null
to_chat(current, "<span class='userdanger'>You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!</span>")
message_admins("[key_name_admin(usr)] has de-changeling'ed [current].")
log_admin("[key_name(usr)] has de-changeling'ed [current].")
if("changeling")
var/datum/antagonist/changeling/C = make_Changling()
to_chat(current, "<span class='boldannounce'>Our powers have awoken. A flash of memory returns to us...we are [C.changelingID], a changeling!</span>")
message_admins("[key_name_admin(usr)] has changeling'ed [current].")
log_admin("[key_name(usr)] has changeling'ed [current].")
if("autoobjectives")
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
if(C)
C.forge_objectives()
to_chat(usr, "<span class='notice'>The objectives for changeling [key] have been generated. You can edit them and anounce manually.</span>")
if("initialdna")
var/datum/antagonist/changeling/ling = has_antag_datum(/datum/antagonist/changeling)
if( !ling || !ling.stored_profiles.len || !iscarbon(current))
to_chat(usr, "<span class='danger'>Resetting DNA failed!</span>")
else
var/mob/living/carbon/C = current
ling.first_prof.dna.transfer_identity(C, transfer_SE=1)
C.real_name = ling.first_prof.name
C.updateappearance(mutcolor_update=1)
C.domutcheck()
else if (href_list["nuclear"])
switch(href_list["nuclear"])
if("clear")
remove_nukeop()
to_chat(current, "<span class='userdanger'>You have been brainwashed! You are no longer a syndicate operative!</span>")
message_admins("[key_name_admin(usr)] has de-nuke op'ed [current].")
log_admin("[key_name(usr)] has de-nuke op'ed [current].")
if("nuclear")
if(!has_antag_datum(/datum/antagonist/nukeop,TRUE))
add_antag_datum(/datum/antagonist/nukeop)
special_role = "Syndicate"
assigned_role = "Syndicate"
message_admins("[key_name_admin(usr)] has nuke op'ed [current].")
log_admin("[key_name(usr)] has nuke op'ed [current].")
if("lair")
current.forceMove(pick(GLOB.nukeop_start))
if("tellcode")
var/code
for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines)
if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN")
code = bombue.r_code
break
if (code)
store_memory("<B>Syndicate Nuclear Bomb Code</B>: [code]", 0, 0)
to_chat(current, "The nuclear authorization code is: <B>[code]</B>")
else
to_chat(usr, "<span class='danger'>No valid nuke found!</span>")
else if (href_list["traitor"])
switch(href_list["traitor"])
if("clear")
to_chat(current, "<span class='userdanger'>You have been brainwashed!</span>")
remove_traitor()
message_admins("[key_name_admin(usr)] has de-traitor'ed [current].")
log_admin("[key_name(usr)] has de-traitor'ed [current].")
SSticker.mode.update_traitor_icons_removed(src)
if("traitor")
if(!(src in SSticker.mode.traitors))
message_admins("[key_name_admin(usr)] has traitor'ed [current].")
log_admin("[key_name(usr)] has traitor'ed [current].")
make_Traitor()
if("autoobjectives")
var/datum/antagonist/traitor/traitordatum = has_antag_datum(ANTAG_DATUM_TRAITOR)
if(!traitordatum)
message_admins("[key_name_admin(usr)] has traitor'ed [current] as part of autoobjectives.")
log_admin("[key_name(usr)] has traitor'ed [current] as part of autoobjectives.")
make_Traitor()
else
log_admin("[key_name(usr)] has forged objectives for [current] as part of autoobjectives.")
traitordatum.forge_traitor_objectives()
to_chat(usr, "<span class='notice'>The objectives for traitor [key] have been generated. You can edit them and anounce manually.</span>")
else if(href_list["devil"])
var/datum/antagonist/devil/devilinfo = has_antag_datum(ANTAG_DATUM_DEVIL)
switch(href_list["devil"])
if("clear")
if(src in SSticker.mode.devils)
remove_devil(current)
message_admins("[key_name_admin(usr)] has de-devil'ed [current].")
log_admin("[key_name(usr)] has de-devil'ed [current].")
if(src in SSticker.mode.sintouched)
SSticker.mode.sintouched -= src
message_admins("[key_name_admin(usr)] has de-sintouch'ed [current].")
log_admin("[key_name(usr)] has de-sintouch'ed [current].")
if("devil")
if(devilinfo)
devilinfo.ascendable = FALSE
message_admins("[key_name_admin(usr)] has made [current] unable to ascend as a devil.")
log_admin("[key_name(usr)] has made [current] unable to ascend as a devil.")
return
if(!ishuman(current) && !iscyborg(current))
to_chat(usr, "<span class='warning'>This only works on humans and cyborgs!</span>")
return
add_devil(current, FALSE)
message_admins("[key_name_admin(usr)] has devil'ed [current].")
log_admin("[key_name(usr)] has devil'ed [current].")
if("ascendable_devil")
if(devilinfo)
devilinfo.ascendable = TRUE
message_admins("[key_name_admin(usr)] has made [current] able to ascend as a devil.")
log_admin("[key_name(usr)] has made [current] able to ascend as a devil.")
return
if(!ishuman(current) && !iscyborg(current))
to_chat(usr, "<span class='warning'>This only works on humans and cyborgs!</span>")
return
add_devil(current, TRUE)
message_admins("[key_name_admin(usr)] has devil'ed [current]. The devil has been marked as ascendable.")
log_admin("[key_name(usr)] has devil'ed [current]. The devil has been marked as ascendable.")
if("sintouched")
if(ishuman(current))
var/mob/living/carbon/human/H = current
H.influenceSin()
message_admins("[key_name_admin(usr)] has sintouch'ed [current].")
else
to_chat(usr, "<span class='warning'>This only works on humans!</span>")
return
else if(href_list["ninja"])
var/datum/antagonist/ninja/ninjainfo = has_antag_datum(ANTAG_DATUM_NINJA)
switch(href_list["ninja"])
if("clear")
remove_ninja(current)
message_admins("[key_name_admin(usr)] has de-ninja'ed [current].")
log_admin("[key_name(usr)] has de-ninja'ed [current].")
if("equip")
ninjainfo.equip_space_ninja()
return
if("nanotrasen")
add_ninja(current, ANTAG_DATUM_NINJA_FRIENDLY)
message_admins("[key_name_admin(usr)] has friendly ninja'ed [current].")
log_admin("[key_name(usr)] has friendly ninja'ed [current].")
if("syndicate")
add_ninja(current, ANTAG_DATUM_NINJA)
message_admins("[key_name_admin(usr)] has syndie ninja'ed [current].")
log_admin("[key_name(usr)] has syndie ninja'ed [current].")
if("random")
add_ninja(current)
message_admins("[key_name_admin(usr)] has random ninja'ed [current].")
log_admin("[key_name(usr)] has random ninja'ed [current].")
else if(href_list["abductor"])
switch(href_list["abductor"])
if("clear")
to_chat(usr, "Not implemented yet. Sorry!")
//SSticker.mode.update_abductor_icons_removed(src)
if("equip")
if(!ishuman(current))
to_chat(usr, "<span class='warning'>This only works on humans!</span>")
return
var/mob/living/carbon/human/H = current
var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist")
if(gear)
if(gear=="Agent")
H.equipOutfit(/datum/outfit/abductor/agent)
else
H.equipOutfit(/datum/outfit/abductor/scientist)
else if (href_list["monkey"])
var/mob/living/L = current
if (L.notransform)
return
switch(href_list["monkey"])
if("healthy")
if (check_rights(R_ADMIN))
var/mob/living/carbon/human/H = current
var/mob/living/carbon/monkey/M = current
if (istype(H))
log_admin("[key_name(usr)] attempting to monkeyize [key_name(current)]")
message_admins("<span class='notice'>[key_name_admin(usr)] attempting to monkeyize [key_name_admin(current)]</span>")
src = null
M = H.monkeyize()
src = M.mind
else if (istype(M) && length(M.viruses))
for(var/thing in M.viruses)
var/datum/disease/D = thing
D.cure(FALSE)
if("leader")
if(check_rights(R_ADMIN, 0))
add_monkey_leader(src)
log_admin("[key_name(usr)] made [key_name(current)] a monkey leader!")
message_admins("[key_name_admin(usr)] made [key_name_admin(current)] a monkey leader!")
if("infected")
if(check_rights(R_ADMIN, 0))
var/mob/living/carbon/human/H = current
var/mob/living/carbon/monkey/M = current
add_monkey(src)
if (istype(H))
log_admin("[key_name(usr)] attempting to monkeyize and infect [key_name(current)]")
message_admins("<span class='notice'>[key_name_admin(usr)] attempting to monkeyize and infect [key_name_admin(current)]</span>")
src = null
M = H.monkeyize()
src = M.mind
current.ForceContractDisease(new /datum/disease/transformation/jungle_fever)
else if (istype(M))
current.ForceContractDisease(new /datum/disease/transformation/jungle_fever)
if("human")
if (check_rights(R_ADMIN, 0))
var/mob/living/carbon/human/H = current
var/mob/living/carbon/monkey/M = current
if (istype(M))
for(var/datum/disease/transformation/jungle_fever/JF in M.viruses)
JF.cure(0)
stoplag() //because deleting of virus is doing throught spawn(0) //What
remove_monkey(src)
log_admin("[key_name(usr)] attempting to humanize [key_name(current)]")
message_admins("<span class='notice'>[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]</span>")
H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
if(H)
src = H.mind
else if (href_list["brother"])
switch(href_list["brother"])
if("clear")
remove_brother()
log_admin("[key_name(usr)] has de-brother'ed [current].")
SSticker.mode.update_brother_icons_removed(src)
else if (href_list["silicon"])
switch(href_list["silicon"])
if("unemag")
@@ -1340,7 +646,10 @@
else if (href_list["obj_announce"])
announce_objectives()
edit_memory()
//Something in here might have changed your mob
if(self_antagging && (!usr || !usr.client) && current.client)
usr = current
traitor_panel()
/datum/mind/proc/announce_objectives()
var/obj_count = 1
@@ -1363,9 +672,7 @@
/datum/mind/proc/make_Traitor()
if(!(has_antag_datum(ANTAG_DATUM_TRAITOR)))
var/datum/antagonist/traitor/T = new(src)
T.should_specialise = TRUE
add_antag_datum(T)
add_antag_datum(/datum/antagonist/traitor)
/datum/mind/proc/make_Changling()
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
@@ -1389,7 +696,7 @@
to_chat(current, "<font color=\"purple\"><b><i>Assist your new bretheren in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.</b></i></font>")
/datum/mind/proc/make_Rev()
var/datum/antagonist/rev/head/head = new(src)
var/datum/antagonist/rev/head/head = new()
head.give_flash = TRUE
head.give_hud = TRUE
add_antag_datum(head)

View File

@@ -74,7 +74,7 @@
M.key = C.key
var/datum/mind/app_mind = M.mind
var/datum/antagonist/wizard/apprentice/app = new(app_mind)
var/datum/antagonist/wizard/apprentice/app = new()
app.master = user
app.school = kind
@@ -136,7 +136,7 @@
C.prefs.copy_to(M)
M.key = C.key
var/datum/antagonist/nukeop/new_op = new(M.mind)
var/datum/antagonist/nukeop/new_op = new()
new_op.send_to_spawnpoint = FALSE
new_op.nukeop_outfit = /datum/outfit/syndicate/no_crystals
@@ -188,7 +188,7 @@
R.key = C.key
var/datum/antagonist/nukeop/new_borg = new(R.mind)
var/datum/antagonist/nukeop/new_borg = new()
new_borg.send_to_spawnpoint = FALSE
R.mind.add_antag_datum(new_borg,creator_op.nuke_team)
R.mind.special_role = "Syndicate Cyborg"
@@ -235,7 +235,6 @@
S.key = C.key
S.mind.assigned_role = S.name
S.mind.special_role = S.name
SSticker.mode.traitors += S.mind
var/datum/objective/assassinate/new_objective
if(user)
new_objective = new /datum/objective/assassinate

View File

@@ -32,3 +32,15 @@
report += printplayerlist(members)
return report.Join("<br>")
//Get all teams [of type team_type]
//TODO move these to some antag helpers file with get_antagonists
/proc/get_all_teams(team_type)
. = list()
for(var/V in GLOB.antagonists)
var/datum/antagonist/A = V
if(!A.owner)
continue
var/datum/team/T = A.get_team()
if(!team_type || istype(T,team_type))
. |= T

View File

@@ -18,8 +18,6 @@
var/const/min_team_size = 2
traitors_required = FALSE //Only teams are possible
var/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library")
/datum/game_mode/traitor/bros/pre_setup()
if(CONFIG_GET(flag/protect_roles_from_antagonist))
restricted_jobs += protected_jobs
@@ -51,8 +49,7 @@
/datum/game_mode/traitor/bros/post_setup()
for(var/datum/team/brother_team/team in pre_brother_teams)
team.meeting_area = pick(meeting_areas)
meeting_areas -= team.meeting_area
team.pick_meeting_area()
team.forge_brother_objectives()
for(var/datum/mind/M in team.members)
M.add_antag_datum(ANTAG_DATUM_BROTHER, team)

View File

@@ -70,7 +70,7 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
for(var/datum/mind/changeling in changelings)
log_game("[changeling.key] (ckey) has been selected as a changeling")
var/datum/antagonist/changeling/new_antag = new(changeling)
var/datum/antagonist/changeling/new_antag = new()
new_antag.team_mode = TRUE
changeling.add_antag_datum(new_antag)
..()

View File

@@ -78,12 +78,12 @@
recent_speech[spoken_memory] = say_log[spoken_memory]
if(recent_speech.len)
user.mind.store_memory("<B>Some of [target]'s speech patterns, we should study these to better impersonate them!</B>")
changeling.antag_memory += "<B>Some of [target]'s speech patterns, we should study these to better impersonate them!</B><br>"
to_chat(user, "<span class='boldnotice'>Some of [target]'s speech patterns, we should study these to better impersonate them!</span>")
for(var/spoken_memory in recent_speech)
user.mind.store_memory("\"[recent_speech[spoken_memory]]\"")
changeling.antag_memory += "\"[recent_speech[spoken_memory]]\"<br>"
to_chat(user, "<span class='notice'>\"[recent_speech[spoken_memory]]\"</span>")
user.mind.store_memory("<B>We have no more knowledge of [target]'s speech patterns.</B>")
changeling.antag_memory += "<B>We have no more knowledge of [target]'s speech patterns.</B><br>"
to_chat(user, "<span class='boldnotice'>We have no more knowledge of [target]'s speech patterns.</span>")

View File

@@ -74,8 +74,35 @@ Credit where due:
var/datum/antagonist/clockcult/C = new update_type(L.mind)
C.make_team = create_team
C.show_in_roundend = create_team //tutorial scarabs begone
if(iscyborg(L))
var/mob/living/silicon/robot/R = L
if(R.deployed)
var/mob/living/silicon/ai/AI = R.mainframe
R.undeploy()
to_chat(AI, "<span class='userdanger'>Anomaly Detected. Returned to core!</span>") //The AI needs to be in its core to properly be converted
. = L.mind.add_antag_datum(C)
if(!silent && L)
if(.)
to_chat(L, "<span class='heavy_brass'>The world before you suddenly glows a brilliant yellow. [issilicon(L) ? "You cannot compute this truth!" : \
"Your mind is racing!"] You hear the whooshing steam and cl[pick("ank", "ink", "unk", "ang")]ing cogs of a billion billion machines, and all at once it comes to you.<br>\
Ratvar, the Clockwork Justiciar, [GLOB.ratvar_awakens ? "has been freed from his eternal prison" : "lies in exile, derelict and forgotten in an unseen realm"].</span>")
flash_color(L, flash_color = list("#BE8700", "#BE8700", "#BE8700", rgb(0,0,0)), flash_time = 50)
else
L.visible_message("<span class='boldwarning'>[L] seems to resist an unseen force!</span>", null, null, 7, L)
to_chat(L, "<span class='heavy_brass'>The world before you suddenly glows a brilliant yellow. [issilicon(L) ? "You cannot compute this truth!" : \
"Your mind is racing!"] You hear the whooshing steam and cl[pick("ank", "ink", "unk", "ang")]ing cogs of a billion billion machines, and the sound</span> <span class='boldwarning'>\
is a meaningless cacophony.</span><br>\
<span class='userdanger'>You see an abomination of rusting parts[GLOB.ratvar_awakens ? ", and it is here.<br>It is too late" : \
" in an endless grey void.<br>It cannot be allowed to escape"].</span>")
L.playsound_local(get_turf(L), 'sound/ambience/antag/clockcultalr.ogg', 40, TRUE, frequency = 100000, pressure_affected = FALSE)
flash_color(L, flash_color = list("#BE8700", "#BE8700", "#BE8700", rgb(0,0,0)), flash_time = 5)
/proc/remove_servant_of_ratvar(mob/L, silent = FALSE)
if(!L || !L.mind)
return

View File

@@ -38,7 +38,8 @@
/obj/structure/destructible/clockwork/eminence_spire/attack_ghost(mob/user)
if(!IsAdminGhost(user))
return
var/datum/antagonist/clockcult/random_cultist = locate() in GLOB.antagonists //if theres no cultists new team without eminence will be created anyway.
var/datum/antagonist/clockcult/random_cultist = locate() in get_antagonists(/datum/antagonist/clockcult) //if theres no cultists new team without eminence will be created anyway.
if(random_cultist && random_cultist.clock_team && random_cultist.clock_team.eminence)
to_chat(user, "<span class='warning'>There's already an Eminence - too late!</span>")
return

View File

@@ -99,7 +99,7 @@
if (!istype(cult_mind))
return 0
var/datum/antagonist/cult/new_cultist = new(cult_mind)
var/datum/antagonist/cult/new_cultist = new()
new_cultist.give_equipment = equip
if(cult_mind.add_antag_datum(new_cultist))

View File

@@ -338,6 +338,7 @@
return ..()
/datum/action/innate/cult/master/pulse/Destroy()
PM.attached_action = null //What the fuck is even going on here.
QDEL_NULL(PM)
return ..()

View File

@@ -1,92 +1,6 @@
/datum/game_mode
var/list/datum/mind/abductors = list()
/datum/game_mode/abduction
name = "abduction"
config_tag = "abduction"
antag_flag = ROLE_ABDUCTOR
false_report_weight = 1
recommended_enemies = 2
required_players = 15
maximum_players = 50
var/max_teams = 4
var/list/datum/team/abductor_team/abductor_teams = list()
var/finished = FALSE
var/static/team_count = 0
/datum/game_mode/abduction/announce()
to_chat(world, "<B>The current game mode is - Abduction!</B>")
to_chat(world, "There are alien <b>abductors</b> sent to [station_name()] to perform nefarious experiments!")
to_chat(world, "<b>Abductors</b> - kidnap the crew and replace their organs with experimental ones.")
to_chat(world, "<b>Crew</b> - don't get abducted and stop the abductors.")
/datum/game_mode/abduction/pre_setup()
var/num_teams = max(1, min(max_teams, round(num_players() / CONFIG_GET(number/abductor_scaling_coeff))))
var/possible_teams = max(1, round(antag_candidates.len / 2))
num_teams = min(num_teams, possible_teams)
for(var/i = 1 to num_teams)
if(!make_abductor_team())
return FALSE
return TRUE
/datum/game_mode/abduction/proc/make_abductor_team(datum/mind/agent, datum/mind/scientist)
team_count++ //TODO: Fix the edge case of abductor game mode rolling twice+ and failing to setup on first time.
var/team_number = team_count
if(team_number > max_teams)
return //or should it try to stuff them in anway ?
var/datum/team/abductor_team/team = new
team.team_number = team_number
team.name = "Mothership [pick(GLOB.possible_changeling_IDs)]" //TODO Ensure unique and actual alieny names
team.add_objective(new/datum/objective/experiment)
if(antag_candidates.len < (!agent + !scientist))
return
if(!scientist)
scientist = pick(antag_candidates)
antag_candidates -= scientist
team.members |= scientist
scientist.assigned_role = "Abductor Scientist"
scientist.special_role = "Abductor Scientist"
log_game("[scientist.key] (ckey) has been selected as [team.name] abductor scientist.")
if(!agent)
agent = pick(antag_candidates)
antag_candidates -= agent
team.members |= agent
agent.assigned_role = "Abductor Agent"
agent.special_role = "Abductor Agent"
log_game("[agent.key] (ckey) has been selected as [team.name] abductor agent.")
abductor_teams += team
return team
/datum/game_mode/abduction/post_setup()
for(var/datum/team/abductor_team/team in abductor_teams)
post_setup_team(team)
return ..()
//Used for create antag buttons
/datum/game_mode/abduction/proc/post_setup_team(datum/team/abductor_team/team)
for(var/datum/mind/M in team.members)
if(M.assigned_role == "Abductor Scientist")
M.add_antag_datum(ANTAG_DATUM_ABDUCTOR_SCIENTIST, team)
else
M.add_antag_datum(ANTAG_DATUM_ABDUCTOR_AGENT, team)
/datum/game_mode/abduction/check_finished()
if(!finished)
for(var/datum/team/abductor_team/team in abductor_teams)
for(var/datum/objective/O in team.objectives)
if(O.check_completion())
SSshuttle.emergency.request(null, set_coefficient = 0.5)
finished = TRUE
return ..()
return ..()
// LANDMARKS
/obj/effect/landmark/abductor
var/team_number = 1
@@ -119,7 +33,3 @@
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_ABDUCTOR]
hud.leave_hud(alien_mind.current)
set_antag_hud(alien_mind.current, null)
/datum/game_mode/abduction/generate_report()
return "Nearby spaceships report crewmembers having been [pick("kidnapped", "abducted", "captured")] and [pick("tortured", "experimented on", "probed", "implanted")] by mysterious \
grey humanoids, before being sent back. Be advised that the kidnapped crewmembers behave strangely upon return to duties."

View File

@@ -226,7 +226,6 @@
player_mind.transfer_to(S)
player_mind.assigned_role = "Morph"
player_mind.special_role = "Morph"
SSticker.mode.traitors |= player_mind
player_mind.add_antag_datum(/datum/antagonist/auto_custom)
to_chat(S, S.playstyle_string)
SEND_SOUND(S, sound('sound/magic/mutate.ogg'))

View File

@@ -86,7 +86,6 @@
to_chat(src, "<b>Objective #2</b>: [objective2.explanation_text]")
mind.assigned_role = "revenant"
mind.special_role = "Revenant"
SSticker.mode.traitors |= mind //Necessary for announcing
mind.add_antag_datum(/datum/antagonist/auto_custom)
AddSpell(new /obj/effect/proc_holder/spell/targeted/night_vision/revenant(null))
AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))

View File

@@ -37,7 +37,6 @@
player_mind.transfer_to(S)
player_mind.assigned_role = "Slaughter Demon"
player_mind.special_role = "Slaughter Demon"
SSticker.mode.traitors |= player_mind
player_mind.add_antag_datum(/datum/antagonist/auto_custom)
to_chat(S, S.playstyle_string)
to_chat(S, "<B>You are currently not currently in the same plane of existence as the station. Blood Crawl near a blood pool to manifest.</B>")

View File

@@ -96,7 +96,7 @@
for(var/datum/mind/rev_mind in headrev_candidates)
log_game("[rev_mind.key] (ckey) has been selected as a head rev")
var/datum/antagonist/rev/head/new_head = new(rev_mind)
var/datum/antagonist/rev/head/new_head = new()
new_head.give_flash = TRUE
new_head.give_hud = TRUE
new_head.remove_clumsy = TRUE

View File

@@ -61,8 +61,7 @@
/datum/game_mode/traitor/post_setup()
for(var/datum/mind/traitor in pre_traitors)
var/datum/antagonist/traitor/new_antag = new antag_datum(traitor)
new_antag.should_specialise = TRUE
var/datum/antagonist/traitor/new_antag = new antag_datum()
addtimer(CALLBACK(traitor, /datum/mind.proc/add_antag_datum, new_antag), rand(10,100))
if(!exchange_blue)
exchange_blue = -1 //Block latejoiners from getting exchange objectives
@@ -82,8 +81,7 @@
add_latejoin_traitor(character.mind)
/datum/game_mode/traitor/proc/add_latejoin_traitor(datum/mind/character)
var/datum/antagonist/traitor/new_antag = new antag_datum(character)
new_antag.should_specialise = TRUE
var/datum/antagonist/traitor/new_antag = new antag_datum()
character.add_antag_datum(new_antag)
/datum/game_mode/traitor/generate_report()

View File

@@ -39,7 +39,6 @@
user.dna.add_mutation(COLDRES)
user.dna.add_mutation(TK)
SSticker.mode.traitors += user.mind
user.mind.special_role = "Avatar of the Wish Granter"
var/datum/objective/hijack/hijack = new

View File

@@ -35,7 +35,7 @@
/obj/item/device/doorCharge/examine(mob/user)
..()
if(user.mind in SSticker.mode.traitors) //No nuke ops because the device is excluded from nuclear
if(user.mind && user.mind.has_antag_datum(/datum/antagonist/traitor)) //No nuke ops because the device is excluded from nuclear
to_chat(user, "A small explosive device that can be used to sabotage airlocks to cause an explosion upon opening. To apply, remove the airlock's maintenance panel and place it within.")
else
to_chat(user, "A small, suspicious object that feels lukewarm when held.")

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

@@ -308,341 +308,3 @@
"}
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!")

View File

@@ -344,7 +344,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

@@ -1888,9 +1888,23 @@
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))

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
GM.post_setup_team(team)
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.")
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

@@ -47,7 +47,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

@@ -982,7 +982,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.")
@@ -89,22 +87,3 @@ Contents:
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)

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

@@ -323,7 +323,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

View File

@@ -112,8 +112,6 @@ CONTINUOUS CULT
CONTINUOUS CLOCKWORK_CULT
CONTINUOUS CHANGELING
CONTINUOUS WIZARD
CONTINUOUS BLOB
CONTINUOUS ABDUCTION
#CONTINUOUS MONKEY
##Note: do not toggle continuous off for these modes, as they have no antagonists and would thus end immediately!
@@ -136,8 +134,6 @@ MIDROUND_ANTAG CULT
MIDROUND_ANTAG CLOCKWORK_CULT
MIDROUND_ANTAG CHANGELING
MIDROUND_ANTAG WIZARD
MIDROUND_ANTAG BLOB
MIDROUND_ANTAG ABDUCTION
#MIDROUND_ANTAG MONKEY
## Uncomment these for overrides of the minimum / maximum number of players in a round type.
@@ -176,9 +172,6 @@ MIDROUND_ANTAG ABDUCTION
#MIN_POP WIZARD 20
#MAX_POP WIZARD -1
#MIN_POP BLOB 25
#MAX_POP BLOB -1
#MIN_POP MONKEY 20
#MAX_POP MONKEY -1

View File

@@ -1113,8 +1113,10 @@
#include "code\modules\admin\admin_ranks.dm"
#include "code\modules\admin\admin_verbs.dm"
#include "code\modules\admin\adminmenu.dm"
#include "code\modules\admin\antag_panel.dm"
#include "code\modules\admin\banjob.dm"
#include "code\modules\admin\chat_commands.dm"
#include "code\modules\admin\check_antagonists.dm"
#include "code\modules\admin\create_mob.dm"
#include "code\modules\admin\create_object.dm"
#include "code\modules\admin\create_poll.dm"