mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-14 03:32:00 +00:00
* Removes Orbit Polling Component, SSpolling improvement * a * Update effects.dmi * Update tgstation.dme * Revert "Update tgstation.dme" This reverts commit d4fdaf0abbfaacddb0cc0d175dad4e410fe57e44. --------- Co-authored-by: 13spacemen <46101244+13spacemen@users.noreply.github.com> Co-authored-by: Pinta <68373373+softcerv@users.noreply.github.com>
155 lines
5.8 KiB
Plaintext
155 lines
5.8 KiB
Plaintext
/**
|
|
* Component which lets ghosts click on a mob to take control of it
|
|
*/
|
|
/datum/component/ghost_direct_control
|
|
/// Message to display upon successful possession
|
|
var/assumed_control_message
|
|
/// Type of ban you can get to prevent you from accepting this role
|
|
var/ban_type
|
|
/// Any extra checks which need to run before we take over
|
|
var/datum/callback/extra_control_checks
|
|
/// Callback run after someone successfully takes over the body
|
|
var/datum/callback/after_assumed_control
|
|
/// If we're currently awaiting the results of a ghost poll
|
|
var/awaiting_ghosts = FALSE
|
|
|
|
/datum/component/ghost_direct_control/Initialize(
|
|
ban_type = ROLE_SENTIENCE,
|
|
role_name = null,
|
|
poll_question = null,
|
|
poll_candidates = TRUE,
|
|
poll_announce_chosen = TRUE,
|
|
poll_length = 10 SECONDS,
|
|
poll_chat_border_icon = null,
|
|
poll_ignore_key = POLL_IGNORE_SENTIENCE_POTION,
|
|
assumed_control_message = null,
|
|
datum/callback/extra_control_checks,
|
|
datum/callback/after_assumed_control,
|
|
)
|
|
. = ..()
|
|
if (!isliving(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
src.ban_type = ban_type
|
|
src.assumed_control_message = assumed_control_message || "You are [parent]!"
|
|
src.extra_control_checks = extra_control_checks
|
|
src.after_assumed_control = after_assumed_control
|
|
|
|
var/mob/mob_parent = parent
|
|
LAZYADD(GLOB.joinable_mobs[format_text("[initial(mob_parent.name)]")], mob_parent)
|
|
|
|
if (poll_candidates)
|
|
INVOKE_ASYNC(src, PROC_REF(request_ghost_control), poll_question, role_name || "[parent]", poll_length, poll_ignore_key, poll_announce_chosen, poll_chat_border_icon)
|
|
|
|
/datum/component/ghost_direct_control/RegisterWithParent()
|
|
. = ..()
|
|
RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, PROC_REF(on_ghost_clicked))
|
|
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined))
|
|
RegisterSignal(parent, COMSIG_MOB_LOGIN, PROC_REF(on_login))
|
|
|
|
/datum/component/ghost_direct_control/UnregisterFromParent()
|
|
UnregisterSignal(parent, list(COMSIG_ATOM_ATTACK_GHOST, COMSIG_ATOM_EXAMINE, COMSIG_MOB_LOGIN))
|
|
return ..()
|
|
|
|
/datum/component/ghost_direct_control/Destroy(force)
|
|
extra_control_checks = null
|
|
after_assumed_control = null
|
|
|
|
var/mob/mob_parent = parent
|
|
var/list/spawners = GLOB.joinable_mobs[format_text("[initial(mob_parent.name)]")]
|
|
LAZYREMOVE(spawners, mob_parent)
|
|
if(!LAZYLEN(spawners))
|
|
GLOB.joinable_mobs -= format_text("[initial(mob_parent.name)]")
|
|
return ..()
|
|
|
|
/// Inform ghosts that they can possess this
|
|
/datum/component/ghost_direct_control/proc/on_examined(datum/source, mob/user, list/examine_text)
|
|
SIGNAL_HANDLER
|
|
if (!isobserver(user))
|
|
return
|
|
var/mob/living/our_mob = parent
|
|
if (our_mob.stat == DEAD || our_mob.key || awaiting_ghosts)
|
|
return
|
|
examine_text += span_boldnotice("You could take control of this mob by clicking on it.")
|
|
|
|
/// Send out a request for a brain
|
|
/datum/component/ghost_direct_control/proc/request_ghost_control(poll_question, role_name, poll_length, poll_ignore_key, poll_announce_chosen, poll_chat_border_icon)
|
|
if(!(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER))
|
|
return
|
|
awaiting_ghosts = TRUE
|
|
var/mob/chosen_one = SSpolling.poll_ghosts_for_target(
|
|
question = poll_question,
|
|
check_jobban = ban_type,
|
|
role = ban_type,
|
|
poll_time = poll_length,
|
|
checked_target = parent,
|
|
ignore_category = poll_ignore_key,
|
|
alert_pic = parent,
|
|
role_name_text = role_name,
|
|
chat_text_border_icon = poll_chat_border_icon,
|
|
announce_chosen = poll_announce_chosen,
|
|
)
|
|
awaiting_ghosts = FALSE
|
|
if(isnull(chosen_one))
|
|
return
|
|
assume_direct_control(chosen_one)
|
|
|
|
/// A ghost clicked on us, they want to get in this body
|
|
/datum/component/ghost_direct_control/proc/on_ghost_clicked(mob/our_mob, mob/dead/observer/hopeful_ghost)
|
|
SIGNAL_HANDLER
|
|
if (our_mob.key)
|
|
qdel(src)
|
|
return
|
|
if (!hopeful_ghost.client)
|
|
return
|
|
if (!(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER))
|
|
to_chat(hopeful_ghost, span_warning("Ghost roles have been temporarily disabled!"))
|
|
return
|
|
if (awaiting_ghosts)
|
|
to_chat(hopeful_ghost, span_warning("Ghost candidate selection currently in progress!"))
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
if (!SSticker.HasRoundStarted())
|
|
to_chat(hopeful_ghost, span_warning("You cannot assume control of this until after the round has started!"))
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
INVOKE_ASYNC(src, PROC_REF(attempt_possession), our_mob, hopeful_ghost)
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
/// We got far enough to establish that this mob is a valid target, let's try to posssess it
|
|
/datum/component/ghost_direct_control/proc/attempt_possession(mob/our_mob, mob/dead/observer/hopeful_ghost)
|
|
var/ghost_asked = tgui_alert(usr, "Become [our_mob]?", "Are you sure?", list("Yes", "No"))
|
|
if (ghost_asked != "Yes" || QDELETED(our_mob))
|
|
return
|
|
assume_direct_control(hopeful_ghost)
|
|
|
|
/// Grant possession of our mob, component is now no longer required
|
|
/datum/component/ghost_direct_control/proc/assume_direct_control(mob/harbinger)
|
|
if (QDELETED(src))
|
|
to_chat(harbinger, span_warning("Offer to possess creature has expired!"))
|
|
return
|
|
if (is_banned_from(harbinger.ckey, list(ban_type)))
|
|
to_chat(harbinger, span_warning("You are banned from playing as this role!"))
|
|
return
|
|
if (!(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER))
|
|
to_chat(harbinger, span_warning("Ghost roles have been temporarily disabled!"))
|
|
return
|
|
var/mob/living/new_body = parent
|
|
if (new_body.stat == DEAD)
|
|
to_chat(harbinger, span_warning("This body has passed away, it is of no use!"))
|
|
return
|
|
if (new_body.key)
|
|
to_chat(harbinger, span_warning("[parent] has already become sapient!"))
|
|
qdel(src)
|
|
return
|
|
if (extra_control_checks && !extra_control_checks.Invoke(harbinger))
|
|
return
|
|
harbinger.log_message("took control of [new_body].", LOG_GAME)
|
|
new_body.key = harbinger.key
|
|
to_chat(new_body, span_boldnotice(assumed_control_message))
|
|
after_assumed_control?.Invoke(harbinger)
|
|
qdel(src)
|
|
|
|
/// When someone else assumes control via some other means, get rid of our component
|
|
/datum/component/ghost_direct_control/proc/on_login()
|
|
SIGNAL_HANDLER
|
|
qdel(src)
|