Files
Bubberstation/code/datums/components/orbit_poll.dm
SkyratBot b557e89855 [MIRROR] More standardization for ghost notifications (READY) [MDB IGNORE] (#25104)
* More standardization for ghost notifications (READY) (#79596)

## About The Pull Request
I'm still not satisfied with how ghost notifications work. This gives
every notification with a source (99% of all notifications, in other
words) a link to jump/orbit. Currently, notifications with "play"
interactions would only get the interact link, so jumping to the source
was pretty annoying.

It removes posting the entire message in the alert tooltip, as some got
pretty lengthy and it didn't seem to fit. To replace this, they will
always use headers

After:

![image](https://github.com/tgstation/tgstation/assets/42397676/debfce52-3627-4a43-8663-33d61d893161)

![image](https://github.com/tgstation/tgstation/assets/42397676/01f299ae-dc6a-45f8-a97a-cb2c815088b2)

![image](https://github.com/tgstation/tgstation/assets/42397676/99567376-063e-458e-af2a-2dd4306747cc)

NOTIFY_JUMP and NOTIFY_ORBIT have been merged, since the only difference
seems to be whether it's a turf. The result shaves off some redundant
lines of code, since most-every usage of notify_ghosts uses
NOTIFY_ORBIT.
## Why It's Good For The Game
More standardization for the ghost notification system. Adds a few alert
headers that never had them. All in all, makes it easier for creators to
throw alerts at ghosts
## Changelog
🆑
qol: Nearly every ghost alert should now feature a "VIEW" button, even
those with click interaction.
del: Ghost alerts no longer show the entire message in the tooltip,
instead have been replaced with titles.
/🆑

* More standardization for ghost notifications (READY)

* Modular

* Update outpost_of_cogs.dm

---------

Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
2023-11-19 11:25:32 -05:00

134 lines
4.1 KiB
Plaintext

/**
* A replacement for the standard poll_ghost_candidate.
* Use this to subtly ask players to join - it picks from orbiters.
* Please use named arguments for this.
*
* @params ignore_key - Required so it doesn't spam
* @params job_bans - You can insert a list or single items here.
* @params cb - Invokes this proc and appends the poll winner as the last argument, mob/dead/observer/ghost
* @params title - Optional. Useful if the role name does not match the parent.
*
* @usage
* ```
* var/datum/callback/cb = CALLBACK(src, PROC_REF(do_stuff), arg1, arg2)
* AddComponent(/datum/component/orbit_poll, \
* ignore_key = POLL_IGNORE_EXAMPLE, \
* job_bans = ROLE_EXAMPLE or list(ROLE_EXAMPLE, ROLE_EXAMPLE2), \
* title = "Use this if you want something other than the parent name", \
* to_call = cb, \
* )
*/
/datum/component/orbit_poll
/// Prevent players with this ban from being selected
var/list/job_bans = list()
/// Title of the role to announce after it's done
var/title
/// Proc to invoke whenever the poll is complete
var/datum/callback/to_call
/datum/component/orbit_poll/Initialize( \
ignore_key, \
list/job_bans, \
datum/callback/to_call, \
title, \
header = "Ghost Poll", \
custom_message, \
timeout = 20 SECONDS \
)
. = ..()
if (!isatom(parent))
return COMPONENT_INCOMPATIBLE
var/atom/owner = parent
src.job_bans |= job_bans
src.title = title || owner.name
src.to_call = to_call
var/message = custom_message || "[capitalize(src.title)] is looking for volunteers"
notify_ghosts(
"[message]. An orbiter will be chosen in [DisplayTimeText(timeout)].\n",
source = parent,
header = "Volunteers requested",
custom_link = " <a href='?src=[REF(src)];ignore=[ignore_key]'>(Ignore)</a>",
ignore_key = ignore_key,
notify_flags = NOTIFY_CATEGORY_NOFLASH,
)
addtimer(CALLBACK(src, PROC_REF(end_poll)), timeout, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE|TIMER_DELETE_ME)
/datum/component/orbit_poll/Topic(href, list/href_list)
if(!href_list["ignore"])
return
var/mob/user = usr
var/ignore_key = href_list["ignore"]
if(tgui_alert(user, "Ignore further [title] alerts?", "Ignore Alert", list("Yes", "No"), 20 SECONDS, TRUE) != "Yes")
return
GLOB.poll_ignore[ignore_key] |= user.ckey
/// Concludes the poll, picking one of the orbiters
/datum/component/orbit_poll/proc/end_poll()
if(QDELETED(parent))
return
var/list/candidates = list()
var/atom/owner = parent
var/datum/component/orbiter/orbiter_comp = owner.GetComponent(/datum/component/orbiter)
if(isnull(orbiter_comp))
phone_home()
return
for(var/mob/dead/observer/ghost as anything in orbiter_comp.orbiter_list)
var/client/ghost_client = ghost.client
if(QDELETED(ghost) || isnull(ghost_client))
continue
if(is_banned_from(ghost.ckey, job_bans))
continue
var/datum/preferences/ghost_prefs = ghost_client.prefs
if(isnull(ghost_prefs))
candidates += ghost // we'll assume they wanted to be picked despite prefs being null for whatever fucked up reason
continue
if(!ghost_prefs.read_preference(/datum/preference/toggle/ghost_roles))
continue
if(!isnull(ghost_client.holder) && !ghost_prefs.read_preference(/datum/preference/toggle/ghost_roles_as_admin))
continue
candidates += ghost
pick_and_offer(candidates)
/// Takes a list, picks a candidate, and offers the role to them.
/datum/component/orbit_poll/proc/pick_and_offer(list/volunteers)
if(length(volunteers) <= 0)
phone_home()
return
var/mob/dead/observer/chosen = pick(volunteers)
if(isnull(chosen))
phone_home()
return
SEND_SOUND(chosen, 'sound/misc/notice2.ogg')
var/response = tgui_alert(chosen, "Do you want to assume the role of [title]?", "Orbit Polling", list("Yes", "No"), 10 SECONDS)
if(response != "Yes")
var/reusable_list = volunteers - chosen
return pick_and_offer(reusable_list)
deadchat_broadcast("[key_name(chosen, include_name = FALSE)] was selected for the role ([title]).", "Ghost Poll: ", parent)
phone_home(chosen)
/// Make sure to call your parents my dude
/datum/component/orbit_poll/proc/phone_home(mob/dead/observer/chosen)
to_call.Invoke(chosen)
qdel(src)