[MIRROR] Improved Imaginary Friend Smite [MDB IGNORE] (#22871)

* Improved Imaginary Friend Smite (#77331)

## About The Pull Request

By admin request:
- The Imaginary Friend smite now allows you to select "Offer to ghosts"
rather than selecting an observer mob manually.
- If you select this option you can also select to bulk-accept multiple
ghosts at a time, if you want to give people twelve imaginary friends
without having to smite them 12 times.

This necessitated changing the order of events a little bit so nwo you
choose whether they have a randomised appearance before picking a
candidate.

## Why It's Good For The Game

Makes it easier to drop the entire end of round deadchat into one guy's
brain with just a couple of clicks

## Changelog

🆑
admin: The imaginary friend smite now allows selecting "offer to ghosts"
instead of having to perform that poll yourself manually. When offering
to ghosts you can also offer for several ghosts to volunteer at the same
time.
/🆑

* Improved Imaginary Friend Smite

---------

Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
SkyratBot
2023-08-04 21:18:29 +02:00
committed by GitHub
parent 771e4495a7
commit d0f20dae01
2 changed files with 96 additions and 40 deletions
@@ -1,3 +1,8 @@
#define CHOICE_RANDOM_APPEARANCE "Random"
#define CHOICE_PREFS_APPEARANCE "Look-a-like"
#define CHOICE_POLL_GHOSTS "Offer to ghosts"
#define CHOICE_CANCEL "Cancel"
/**
* Custom imaginary friend.
*
@@ -10,34 +15,67 @@
**/
/datum/smite/custom_imaginary_friend
name = "Imaginary Friend (Special)"
var/client/friend_candidate_client
/// Who are we going to add to your head today?
var/list/friend_candidates
/// Do we randomise friend appearances or not?
var/random_appearance
/datum/smite/custom_imaginary_friend/configure(client/user)
friend_candidate_client = tgui_input_list(user, "Pick the player to put in control", "New Imaginary Friend", sort_list(GLOB.clients))
if(isnull(friend_candidate_client))
var/appearance_choice = tgui_alert(user,
"Do you want the imaginary friend(s) to share name and appearance with their currently selected character preferences?",
"Imaginary Friend Appearance?",
list(CHOICE_PREFS_APPEARANCE, CHOICE_RANDOM_APPEARANCE, CHOICE_CANCEL))
if (isnull(appearance_choice) || appearance_choice == CHOICE_CANCEL)
return FALSE
random_appearance = appearance_choice == CHOICE_RANDOM_APPEARANCE
var/picked_client = tgui_input_list(user, "Pick the player to put in control", "New Imaginary Friend", list(CHOICE_POLL_GHOSTS) + sort_list(GLOB.clients))
if(isnull(picked_client))
return FALSE
if(picked_client == CHOICE_POLL_GHOSTS)
return poll_ghosts(user)
var/client/friend_candidate_client = picked_client
if(QDELETED(friend_candidate_client))
to_chat(user, span_notice("Selected player no longer has a client, aborting."))
to_chat(user, span_warning("Selected player no longer has a client, aborting."))
return FALSE
if(isliving(friend_candidate_client.mob) && (tgui_alert(user, "This player already has a living mob ([friend_candidate_client.mob]). Do you still want to turn them into an Imaginary Friend?", "Remove player from mob?", list("Do it!", "Cancel")) != "Do it!"))
return FALSE
if(QDELETED(friend_candidate_client))
to_chat(user, span_notice("Selected player no longer has a client, aborting."))
to_chat(user, span_warning("Selected player no longer has a client, aborting."))
return FALSE
if(friend_candidate_client.prefs)
var/choice = tgui_alert(user, "Do you want the imaginary friend to look like and be named after [friend_candidate_client]'s current preferences ([friend_candidate_client.prefs.read_preference(/datum/preference/name/real_name)])?", "Imaginary Friend Appearance?", list("Look-a-like", "Random", "Cancel"))
if(choice != "Look-a-like" && choice != "Random")
return FALSE
random_appearance = choice == "Random"
else
if(tgui_alert(user, "The preferences for the friend could not be loaded, defaulting to random appearance. Is that okay?", "Preference error", list("Yes", "No")) != "Yes")
return FALSE
random_appearance = TRUE
friend_candidates = list(friend_candidate_client)
return TRUE
/// Try to offer the role to ghosts
/datum/smite/custom_imaginary_friend/proc/poll_ghosts(client/user)
var/how_many = tgui_input_number(user, "How many imaginary friends should be added?", "Imaginary friend count", default = 1, min_value = 1)
if (isnull(how_many) || how_many < 1)
return FALSE
var/list/volunteers = poll_ghost_candidates(
question = "Do you want to play as an imaginary friend?",
jobban_type = ROLE_PAI,
poll_time = 10 SECONDS,
ignore_category = POLL_IGNORE_IMAGINARYFRIEND,
)
var/volunteer_count = length(volunteers)
if (volunteer_count == 0)
to_chat(user, span_warning("No candidates volunteered, aborting."))
return FALSE
shuffle_inplace(volunteers)
friend_candidates = list()
while (how_many > 0 && length(volunteers) > 0)
var/mob/dead/observer/lucky_ghost = pop(volunteers)
if (!lucky_ghost.client)
continue
how_many--
friend_candidates += lucky_ghost.client
return TRUE
/datum/smite/custom_imaginary_friend/effect(client/user, mob/living/target)
@@ -47,18 +85,34 @@
to_chat(user, span_warning("The target mob no longer exists, aborting."))
return
if(QDELETED(friend_candidate_client))
to_chat(user, span_warning("Imaginary friend candidate no longer has a client, aborting."))
if(!length(friend_candidates))
to_chat(user, span_warning("No provided imaginary friend candidates, aborting."))
return
if(isliving(friend_candidate_client.mob))
friend_candidate_client.mob.ghostize(can_reenter_corpse = TRUE)
var/list/final_clients = list()
for (var/client/client as anything in friend_candidates)
if (QDELETED(client))
continue
final_clients += client
var/mob/camera/imaginary_friend/friend_mob
if(!length(final_clients))
to_chat(user, span_warning("No provided imaginary friend candidates had clients, aborting."))
return
if(random_appearance)
friend_mob = new /mob/camera/imaginary_friend(get_turf(target), target)
else
friend_mob = new /mob/camera/imaginary_friend(get_turf(target), target, friend_candidate_client.prefs)
for (var/client/friend_candidate_client as anything in final_clients)
var/mob/client_mob = friend_candidate_client.mob
if(isliving(client_mob))
client_mob.ghostize()
friend_mob.key = friend_candidate_client.key
var/mob/camera/imaginary_friend/friend_mob = client_mob.change_mob_type(
new_type = /mob/camera/imaginary_friend,
location = get_turf(client_mob),
delete_old_mob = TRUE,
)
friend_mob.attach_to_owner(target)
friend_mob.setup_appearance(random_appearance ? null : friend_candidate_client.prefs)
#undef CHOICE_RANDOM_APPEARANCE
#undef CHOICE_PREFS_APPEARANCE
#undef CHOICE_POLL_GHOSTS
#undef CHOICE_CANCEL