diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index c6b0edcff49..200dccdfe7a 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -43,7 +43,8 @@ var/Tickcomp = 0 var/socket_talk = 0 // use socket_talk to communicate with other processes var/list/resource_urls = null - + var/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round. + var/antag_hud_restricted = 0 // Ghosts that turn on Antagovision cannot rejoin the round. var/list/mode_names = list() var/list/modes = list() // allowed modes var/list/votable_modes = list() // votable modes @@ -384,6 +385,12 @@ if("tickcomp") Tickcomp = 1 + if("allow_antag_hud") + config.antag_hud_allowed = 1 + + if("antag_hud_restricted") + config.antag_hud_restricted = 1 + if("humans_need_surnames") humans_need_surnames = 1 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 423c322d28b..11b62690948 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -120,7 +120,9 @@ var/list/admin_verbs_server = list( /datum/admins/proc/toggle_space_ninja, /client/proc/toggle_random_events, /client/proc/check_customitem_activity, - /client/proc/delbook + /client/proc/delbook, + /client/proc/toggle_antagHUD_use, + /client/proc/toggle_antagHUD_restrictions ) var/list/admin_verbs_debug = list( /client/proc/cmd_admin_list_open_jobs, diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 776ac5c9db2..6b3957657f8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -568,7 +568,7 @@ //Non-Human (Green) counter = 0 jobs += "" - jobs += "" + jobs += "" for(var/jobPos in nonhuman_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) @@ -591,6 +591,11 @@ else jobs += "" + if(jobban_isbanned(M, "AntagHUD")) + jobs += "" + else + jobs += "" + jobs += "
Non-human Positions
Non-human Positions
pAIAntagHUDAntagHUD
" //Antagonist (Orange) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 2777dbeeea8..9439f3e36f9 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -408,6 +408,89 @@ Traitors and the like can also be revived with the previous role mostly intact. feedback_add_details("admin_verb","RSPCH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return new_character +/client/proc/get_ghosts(var/notify = 0,var/what = 2) + // what = 1, return ghosts ass list. + // what = 2, return mob list + + var/list/mobs = list() + var/list/ghosts = list() + var/list/sortmob = sortAtom(mob_list) // get the mob list. + /var/any=0 + for(var/mob/dead/observer/M in sortmob) + mobs.Add(M) //filter it where it's only ghosts + any = 1 //if no ghosts show up, any will just be 0 + if(!any) + if(notify) + src << "There doesn't appear to be any ghosts for you to select." + return + + for(var/mob/M in mobs) + var/name = M.name + ghosts[name] = M //get the name of the mob for the popup list + if(what==1) + return ghosts + else + return mobs + +/client/proc/toggle_antagHUD_use() + set category = "Server" + set name = "Toggle antagHUD usage" + set desc = "Toggles antagHUD usage for observers" + + if(!holder) + src << "Only administrators may use this command." + var/action="" + if(config.antag_hud_allowed) + for(var/mob/dead/observer/g in get_ghosts()) + if(!g.client.holder) //Remove the verb from non-admin ghosts + g.verbs -= /mob/dead/observer/verb/toggle_antagHUD + if(g.antagHUD) + g.antagHUD = 0 // Disable it on those that have it enabled + g.has_enabled_antagHUD = 2 // We'll allow them to respawn + g << "\red The Administrator has disabled AntagHUD " + config.antag_hud_allowed = 0 + src << "\red AntagHUD usage has been disabled" + action = "disabled" + else + for(var/mob/dead/observer/g in get_ghosts()) + if(!g.client.holder) // Add the verb back for all non-admin ghosts + g.verbs += /mob/dead/observer/verb/toggle_antagHUD + g << "\blue The Administrator has enabled AntagHUD " // Notify all observers they can now use AntagHUD + config.antag_hud_allowed = 1 + action = "enabled" + src << "\blue AntagHUD usage has been enabled" + + + log_admin("[key_name(usr)] has [action] antagHUD usage for observers") + message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1) + + +/client/proc/toggle_antagHUD_restrictions() + set category = "Server" + set name = "Toggle antagHUD Restrictions" + set desc = "Restricts players that have used antagHUD from being able to join this round." + if(!holder) + src << "Only administrators may use this command." + var/action="" + if(config.antag_hud_restricted) + for(var/mob/dead/observer/g in get_ghosts()) + g << "\blue The administrator has lifted restrictions on joining the round if you use AntagHUD" + action = "lifted restrictions" + config.antag_hud_restricted = 0 + src << "\blue AntagHUD restrictions have been lifted" + else + for(var/mob/dead/observer/g in get_ghosts()) + g << "\red The administrator has placed restrictions on joining the round if you use AntagHUD" + g << "\red Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions " + g.antagHUD = 0 + g.has_enabled_antagHUD = 0 + action = "placed restrictions" + config.antag_hud_restricted = 1 + src << "\red AntagHUD restrictions have been enabled" + + log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD") + message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1) + /client/proc/cmd_admin_add_freeform_ai_law() set category = "Fun" set name = "Add Custom AI law" diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 095b0539b37..027b2c9082a 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -18,6 +18,7 @@ //Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot. universal_speak = 1 var/atom/movable/following = null + var/medHUD = 0 /mob/dead/observer/New(mob/body) sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF see_invisible = SEE_INVISIBLE_OBSERVER @@ -69,12 +70,123 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body Works together with spawning an observer, noted above. */ + +/mob/dead/observer/Life() + ..() + if(!loc) return + if(!client) return 0 + + + if(client.images.len) + for(var/image/hud in client.images) + if(copytext(hud.icon_state,1,4) == "hud") + client.images.Remove(hud) + if(antagHUD) + var/list/target_list = list() + for(var/mob/living/target in oview(src)) + if( target.mind&&(target.mind.special_role||issilicon(target)) ) + target_list += target + if(target_list.len) + assess_targets(target_list, src) + if(medHUD) + process_medHUD(src) + + +// Direct copied from medical HUD glasses proc, used to determine what health bar to put over the targets head. +/mob/dead/proc/RoundHealth(var/health) + switch(health) + if(100 to INFINITY) + return "health100" + if(70 to 100) + return "health80" + if(50 to 70) + return "health60" + if(30 to 50) + return "health40" + if(18 to 30) + return "health25" + if(5 to 18) + return "health10" + if(1 to 5) + return "health1" + if(-99 to 0) + return "health0" + else + return "health-100" + return "0" + + +// Pretty much a direct copy of Medical HUD stuff, except will show ill if they are ill instead of also checking for known illnesses. + +/mob/dead/proc/process_medHUD(var/mob/M) + var/client/C = M.client + var/image/holder + for(var/mob/living/carbon/human/patient in oview(M)) + var/foundVirus = 0 + if(patient.virus2.len) + foundVirus = 1 + if(!C) return + holder = patient.hud_list[HEALTH_HUD] + if(patient.stat == 2) + holder.icon_state = "hudhealth-100" + else + holder.icon_state = "hud[RoundHealth(patient.health)]" + C.images += holder + + holder = patient.hud_list[STATUS_HUD] + if(patient.stat == 2) + holder.icon_state = "huddead" + else if(patient.status_flags & XENO_HOST) + holder.icon_state = "hudxeno" + else if(foundVirus) + holder.icon_state = "hudill" + else + holder.icon_state = "hudhealthy" + C.images += holder + + +/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U) + var/icon/tempHud = 'icons/mob/hud.dmi' + for(var/mob/living/target in target_list) + if(iscarbon(target)) + switch(target.mind.special_role) + if("traitor","Syndicate") + U.client.images += image(tempHud,target,"hudsyndicate") + if("Revolutionary") + U.client.images += image(tempHud,target,"hudrevolutionary") + if("Head Revolutionary") + U.client.images += image(tempHud,target,"hudheadrevolutionary") + if("Cultist") + U.client.images += image(tempHud,target,"hudcultist") + if("Changeling") + U.client.images += image(tempHud,target,"hudchangeling") + if("Wizard","Fake Wizard") + U.client.images += image(tempHud,target,"hudwizard") + if("Hunter","Sentinel","Drone","Queen") + U.client.images += image(tempHud,target,"hudalien") + if("Death Commando") + U.client.images += image(tempHud,target,"huddeathsquad") + if("Ninja") + U.client.images += image(tempHud,target,"hudninja") + else//If we don't know what role they have but they have one. + U.client.images += image(tempHud,target,"hudunknown1") + else//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud. + var/mob/living/silicon/silicon_target = target + if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))||silicon_target.mind.special_role=="traitor") + if(isrobot(silicon_target))//Different icons for robutts and AI. + U.client.images += image(tempHud,silicon_target,"hudmalborg") + else + U.client.images += image(tempHud,silicon_target,"hudmalai") + return 1 + /mob/proc/ghostize(var/can_reenter_corpse = 1) if(key) var/mob/dead/observer/ghost = new(src) //Transfer safety to observer spawning proc. ghost.can_reenter_corpse = can_reenter_corpse ghost.timeofdeath = src.timeofdeath //BS12 EDIT ghost.key = key + if(!ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed. + ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing! return ghost /* @@ -164,6 +276,47 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp mind.current.key = key return 1 +/mob/dead/observer/verb/toggle_medHUD() + set category = "Ghost" + set name = "Toggle MedicHUD" + set desc = "Toggles Medical HUD allowing you to see how everyone is doing" + if(!client) + return + if(medHUD) + medHUD = 0 + src << "\blue Medical HUD Disabled" + else + medHUD = 1 + src << "\blue Medical HUD Enabled" + +/mob/dead/observer/verb/toggle_antagHUD() + set category = "Ghost" + set name = "Toggle AntagHUD" + set desc = "Toggles AntagHUD allowing you to see who is the antagonist" + if(!config.antag_hud_allowed && !client.holder) + src << "\red Admins have disabled this for this round." + return + if(!client) + return + var/mob/dead/observer/M = src + if(jobban_isbanned(M, "AntagHUD")) + src << "\red You have been banned from using this feature" + return + if(config.antag_hud_restricted && !M.has_enabled_antagHUD &&!client.holder) + var/response = alert(src, "If you turn this on, you will not be able to take any part in the round.","Are you sure you want to turn this feature on?","Yes","No") + if(response == "No") return + M.can_reenter_corpse = 0 + if(M in respawnable_list) + respawnable_list -= M + if(!M.has_enabled_antagHUD && !client.holder) + M.has_enabled_antagHUD = 1 + if(M.antagHUD) + M.antagHUD = 0 + src << "\blue AntagHUD Disabled" + else + M.antagHUD = 1 + src << "\blue AntagHUD Enabled" + /mob/dead/observer/proc/dead_tele() set category = "Ghost" set name = "Teleport" diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm index f8c014278c2..d078a854ba8 100644 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -26,7 +26,9 @@ spawn(600) reset_search() proc/request_player() - for(var/mob/dead/observer/O in player_list) + for(var/mob/O in respawnable_list) + if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted) + continue if(jobban_isbanned(O, "pAI")) continue if(O.client) diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm index 3928ebb2080..05536c0d176 100644 --- a/code/modules/mob/living/silicon/pai/recruit.dm +++ b/code/modules/mob/living/silicon/pai/recruit.dm @@ -190,7 +190,9 @@ var/datum/paiController/paiController // Global handler for pAI candidates user << browse(dat, "window=findPai") proc/requestRecruits() - for(var/mob/dead/observer/O in player_list) + for(var/mob/O in respawnable_list) + if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted) + continue if(jobban_isbanned(O, "pAI")) continue if(asked.Find(O.key)) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 8af29e57db9..ca463db09bc 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -160,6 +160,8 @@ var/move_on_shuttle = 1 // Can move on the shuttle. + var/has_enabled_antagHUD = 0 + var/antagHUD = 0 //Generic list for proc holders. Only way I can see to enable certain verbs/procs. Should be modified if needed. var/proc_holder_list[] = list()//Right now unused. //Also unlike the spell list, this would only store the object in contents, not an object in itself. diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index de86597e26a..29efa7398cd 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -133,6 +133,8 @@ client.prefs.real_name = random_name(client.prefs.gender) observer.real_name = client.prefs.real_name observer.name = observer.real_name + if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed. + observer.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing! observer.key = key respawnable_list += observer del(src) diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 66aab85d812..9853c592755 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ