simple ghost pod find (#17909)

* simple ghost spawn rewrite

* neutral

* .

* don't close

* migrate vore spawn

* use a searchable list

* move some more verbs

* allow special role spawns

* add key

* .

* fix that part

* announce for logging

* filter those

* typ o

* .

* .

* Update SelectionList.tsx

* .

* that

* .

---------

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
Kashargul
2025-07-17 01:00:51 +02:00
committed by GitHub
parent f94a66cb97
commit 426b24d37e
34 changed files with 1543 additions and 430 deletions
+5
View File
@@ -3,7 +3,10 @@
set name = "Check Player Attack Logs"
set desc = "Check a player's attack logs."
show_cmd_admin_check_player_logs(M)
//Views specific attack logs belonging to one player.
/client/proc/show_cmd_admin_check_player_logs(mob/living/M)
var/dat = span_bold("[M]'s Attack Log:<HR>")
dat += span_bold("Viewing attack logs of [M]") + " - (Played by ([key_name(M)]).<br>"
if(M.mind)
@@ -33,8 +36,10 @@
set category = "Admin.Logs"
set name = "Check Player Dialogue Logs"
set desc = "Check a player's dialogue logs."
show_cmd_admin_check_dialogue_logs(M)
//Views specific dialogue logs belonging to one player.
/client/proc/show_cmd_admin_check_dialogue_logs(mob/living/M)
var/dat = span_bold("[M]'s Dialogue Log:<HR>")
dat += span_bold("Viewing say and emote logs of [M]") + " - (Played by ([key_name(M)]).<br>"
if(M.mind)
+6 -3
View File
@@ -1,4 +1,7 @@
ADMIN_VERB_AND_CONTEXT_MENU(resize, (R_ADMIN|R_FUN|R_VAREDIT), "Resize", "Resizes any living mob without any restrictions on size.", "Fun.Event Kit", mob/living/L in GLOB.mob_list)
user.do_resize(L)
/client/proc/do_resize(var/mob/living/L)
var/size_multiplier = tgui_input_number(usr, "Input size multiplier.", "Resize", 1, round_value=FALSE)
if(!size_multiplier)
return //cancelled
@@ -8,11 +11,11 @@ ADMIN_VERB_AND_CONTEXT_MENU(resize, (R_ADMIN|R_FUN|R_VAREDIT), "Resize", "Resize
var/very_big = is_extreme_size(size_multiplier)
if(very_big && can_be_big) // made an extreme size in an area that allows it, don't assume adminbuse
to_chat(user, span_warning("[L] will lose this size upon moving into an area where this size is not allowed."))
to_chat(src, span_warning("[L] will lose this size upon moving into an area where this size is not allowed."))
else if(very_big) // made an extreme size in an area that doesn't allow it, assume adminbuse
to_chat(user, span_warning("[L] will retain this normally unallowed size outside this area."))
to_chat(src, span_warning("[L] will retain this normally unallowed size outside this area."))
L.resize(size_multiplier, animate = TRUE, uncapped = TRUE, ignore_prefs = TRUE)
log_and_message_admins("has changed [key_name(L)]'s size multiplier to [size_multiplier].", user)
log_and_message_admins("has changed [key_name(L)]'s size multiplier to [size_multiplier].", src)
feedback_add_details("admin_verb","RESIZE")
+29
View File
@@ -0,0 +1,29 @@
//Allows some list search inputs
/client/proc/tgui_admin_lists()
set name = "TGUI Admin Lists"
set desc = "Allows to have some procs with searchable lists."
set category = "Admin.Game"
if(!check_rights(R_ADMIN|R_EVENT))
return
var/list/modification_options = list(TGUI_VIEW_ATTACK_LOGS, TGUI_VIEW_DIALOG_LOGS, TGUI_RESIZE)
var/tgui_list_choice = tgui_input_list(src, "Select the verb you would like to use with a tgui input","Choice", modification_options)
if(!tgui_list_choice || tgui_list_choice == "Cancel")
return
log_and_message_admins("[key_name(src)] has used TGUI Admin Lists with ([tgui_list_choice])].")
feedback_add_details("admin_verb","TGUIADL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
switch(tgui_list_choice)
if(TGUI_VIEW_ATTACK_LOGS)
var/mob/living/L = tgui_input_list(src, "Check a player's attack logs.", "Check Player Attack Logs", GLOB.mob_list)
show_cmd_admin_check_player_logs(L)
if(TGUI_VIEW_DIALOG_LOGS)
var/mob/living/L = tgui_input_list(src, "Check a player's dialogue logs.", "Check Player Dialogue Logs", GLOB.mob_list)
show_cmd_admin_check_dialogue_logs(L)
if(TGUI_RESIZE)
var/mob/living/L = tgui_input_list(src, "Resizes any living mob without any restrictions on size.", "Resize", GLOB.mob_list)
if(L)
do_resize(L)
+1 -1
View File
@@ -1,4 +1,4 @@
//GLOBAL_LIST_EMPTY(event_viruses) // so that event viruses are kept around for admin logs, rather than being GCed
GLOBAL_LIST_EMPTY(event_viruses) // so that event viruses are kept around for admin logs, rather than being GCed
/datum/event/viral_infection
var/list/viruses = list()
+2 -56
View File
@@ -41,6 +41,7 @@
var/ghost_sprite = null
var/last_revive_notification = null // world.time of last notification, used to avoid spamming players from defibs or cloners.
var/cleanup_timer // Refernece to a timer that will delete this mob if no client returns
var/selecting_ghostrole = FALSE
invisibility = INVISIBILITY_OBSERVER
layer = BELOW_MOB_LAYER
@@ -648,61 +649,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/rads = SSradiation.get_rads_at_turf(t)
to_chat(src, span_notice("Radiation level: [rads ? rads : "0"] Bq."))
/mob/observer/dead/verb/become_mouse()
set name = "Become mouse"
set category = "Ghost.Join"
if(CONFIG_GET(flag/disable_player_mice))
to_chat(src, span_warning("Spawning as a mouse is currently disabled."))
return
//VOREStation Add Start
if(jobban_isbanned(src, JOB_GHOSTROLES))
to_chat(src, span_warning("You cannot become a mouse because you are banned from playing ghost roles."))
return
//VOREStation Add End
if(!MayRespawn(1))
return
var/turf/T = get_turf(src)
if(!T || (T.z in using_map.admin_levels))
to_chat(src, span_warning("You may not spawn as a mouse on this Z-level."))
return
var/timedifference = world.time - client.time_died_as_mouse
if(client.time_died_as_mouse && timedifference <= CONFIG_GET(number/mouse_respawn_time) MINUTES)
var/timedifference_text
timedifference_text = time2text(CONFIG_GET(number/mouse_respawn_time) MINUTES - timedifference,"mm:ss")
to_chat(src, span_warning("You may only spawn again as a mouse more than [CONFIG_GET(number/mouse_respawn_time)] minutes after your death. You have [timedifference_text] left."))
return
var/response = tgui_alert(src, "Are you -sure- you want to become a mouse?","Are you sure you want to squeek?",list("Squeek!","Nope!"))
if(response != "Squeek!") return //Hit the wrong key...again.
//find a viable mouse candidate
var/mob/living/simple_mob/animal/passive/mouse/host
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
var/list/found_vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/v in GLOB.machines)
if(!v.welded && v.z == T.z && v.network && v.network.normal_members.len > 20)
found_vents.Add(v)
if(found_vents.len)
vent_found = pick(found_vents)
host = new /mob/living/simple_mob/animal/passive/mouse(vent_found)
else
to_chat(src, span_warning("Unable to find any unwelded vents to spawn mice at."))
if(host)
if(CONFIG_GET(flag/uneducated_mice))
host.universal_understand = 0
announce_ghost_joinleave(src, 0, "They are now a mouse.")
host.ckey = src.ckey
host.add_ventcrawl(vent_found)
to_chat(host, span_info("You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent."))
/mob/observer/dead/verb/view_manfiest()
set name = "Show Crew Manifest"
set category = "Ghost.Game"
@@ -916,7 +862,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return 0
if(mind && mind.current && mind.current.stat != DEAD && can_reenter_corpse)
if(feedback)
to_chat(src, span_warning("Your non-dead body prevent you from respawning."))
to_chat(src, span_warning("Your non-dead body prevents you from respawning."))
return 0
if(CONFIG_GET(flag/antag_hud_restricted) && has_enabled_antagHUD == 1)
if(feedback)
+5 -77
View File
@@ -1,62 +1,3 @@
/mob/observer/dead/verb/nifjoin()
set category = "Ghost.Join"
set name = "Join Into Soulcatcher"
set desc = "Select a player with a working NIF + Soulcatcher NIFSoft to join into it."
var/picked = tgui_input_list(src, "Pick a friend with NIF and Soulcatcher to join into. Harrass strangers, get banned. Not everyone has a NIF w/ Soulcatcher.","Select a player", GLOB.player_list)
//Didn't pick anyone or picked a null
if(!picked)
return
//Good choice testing and some instance-grabbing
if(!ishuman(picked))
to_chat(src,span_warning("[picked] isn't in a humanoid mob at the moment."))
return
var/mob/living/carbon/human/H = picked
if(H.stat || !H.client)
to_chat(src,span_warning("[H] isn't awake/alive at the moment."))
return
if(!H.nif)
to_chat(src,span_warning("[H] doesn't have a NIF installed."))
return
var/datum/nifsoft/soulcatcher/SC = H.nif.imp_check(NIF_SOULCATCHER)
if(!SC)
to_chat(src,span_warning("[H] doesn't have the Soulcatcher NIFSoft installed, or their NIF is unpowered."))
return
//Fine fine, we can ask.
var/obj/item/nif/nif = H.nif
to_chat(src,span_notice("Request sent to [H]."))
var/req_time = world.time
nif.notify("Transient mindstate detected, analyzing...")
sleep(15) //So if they are typing they get interrupted by sound and message, and don't type over the box
var/response = tgui_alert(H,"[src] ([src.key]) wants to join into your Soulcatcher.","Soulcatcher Request",list("Deny","Allow"), timeout = 1 MINUTE)
if(!response || response == "Deny")
to_chat(src,span_warning("[H] denied your request."))
return
if((world.time - req_time) > 1 MINUTE)
to_chat(H,span_warning("The request had already expired. (1 minute waiting max)"))
return
//Final check since we waited for input a couple times.
if(H && src && src.key && !H.stat && nif && SC)
if(!mind) //No mind yet, aka haven't played in this round.
mind = new(key)
mind.name = name
mind.current = src
mind.active = TRUE
SC.catch_mob(src) //This will result in us being deleted so...
/mob/observer/dead/verb/backup_ping()
set category = "Ghost.Join"
set name = "Notify Transcore"
@@ -106,30 +47,17 @@
*/
/mob/observer/dead/verb/findghostpod() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
set category = "Ghost.Join"
set name = "Find Ghost Pod"
set desc = "Find an active ghost pod"
set popup_menu = FALSE
set name = "Ghost Spawn"
set desc = "Open Ghost Spawn Menu"
if(!isobserver(src)) //Make sure they're an observer!
return
var/input = tgui_input_list(src, "Select a ghost pod:", "Ghost Jump", observe_list_format(GLOB.active_ghost_pods))
if(!input)
to_chat(src, span_filter_notice("No active ghost pods detected."))
if(selecting_ghostrole)
return
var/target = observe_list_format(GLOB.active_ghost_pods)[input]
if (!target)//Make sure we actually have a target
return
else
var/obj/O = target //Destination mob
var/turf/T = get_turf(O) //Turf of the destination mob
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
forceMove(T)
stop_following()
else
to_chat(src, span_filter_notice("This ghost pod is not located in the game world."))
var/datum/tgui_module/ghost_spawn_menu/ui = new(src)
ui.tgui_interact(src)
/mob/observer/dead/verb/findautoresleever()
set category = "Ghost.Join"
@@ -34,6 +34,15 @@
fabricator_tag = "Upper Level Mining"
drone_type = /mob/living/silicon/robot/drone/mining
/obj/machinery/drone_fabricator/Initialize(mapload)
. = ..()
GLOB.all_drone_fabricators += src
/obj/machinery/drone_fabricator/Destroy()
GLOB.all_drone_fabricators -= src
. = ..()
/obj/machinery/drone_fabricator/power_change()
..()
if (stat & NOPOWER)
@@ -88,70 +97,3 @@
new_drone.transfer_personality(player)
return new_drone
/mob/observer/dead/verb/join_as_drone()
set category = "Ghost.Join"
set name = "Join As Drone"
set desc = "If there is a powered, enabled fabricator in the game world with a prepared chassis, join as a maintenance drone."
if(ticker.current_state < GAME_STATE_PLAYING)
to_chat(src, span_danger("The game hasn't started yet!"))
return
if(!CONFIG_GET(flag/allow_drone_spawn))
to_chat(src, span_danger("That verb is not currently permitted."))
return
if (!src.stat)
return
if (usr != src)
return 0 //something is terribly wrong
if(jobban_isbanned(src,JOB_CYBORG))
to_chat(src, span_danger("You are banned from playing synthetics and cannot spawn as a drone."))
return
// VOREStation Addition Start
if(CONFIG_GET(flag/use_age_restriction_for_jobs) && isnum(src.client.player_age))
var/time_till_play = max(0, 3 - src.client.player_age)
if(time_till_play)
to_chat(src, span_danger("You have not been playing on the server long enough to join as drone."))
return
// VOREStation Addition End
if(!MayRespawn(1))
return
var/deathtime = world.time - src.timeofdeath
var/deathtimeminutes = round(deathtime / (1 MINUTE))
var/pluralcheck = "minute"
if(deathtimeminutes == 0)
pluralcheck = ""
else if(deathtimeminutes == 1)
pluralcheck = " [deathtimeminutes] minute and"
else if(deathtimeminutes > 1)
pluralcheck = " [deathtimeminutes] minutes and"
var/deathtimeseconds = round((deathtime - deathtimeminutes * 1 MINUTE) / 10,1)
if (deathtime < 5 MINUTES)
to_chat(src, "You have been dead for[pluralcheck] [deathtimeseconds] seconds.")
to_chat(src, "You must wait 5 minutes to respawn as a drone!")
return
var/list/all_fabricators = list()
for(var/obj/machinery/drone_fabricator/DF in GLOB.machines)
if(DF.stat & NOPOWER || !DF.produce_drones)
continue
if(DF.drone_progress >= 100)
all_fabricators[DF.fabricator_tag] = DF
if(!all_fabricators.len)
to_chat(src, span_danger("There are no available drone spawn points, sorry."))
return
var/choice = tgui_input_list(src, "Which fabricator do you wish to use?", "Fabricator Choice", all_fabricators)
if(choice)
var/obj/machinery/drone_fabricator/chosen_fabricator = all_fabricators[choice]
chosen_fabricator.create_drone(src.client)
-66
View File
@@ -1,68 +1,3 @@
/mob/observer/dead/verb/spawn_in_belly()
set category = "Ghost.Join"
set name = "Spawn In Belly"
set desc = "Spawn in someone's belly."
if(!client)
return
// If any ghost-side restrictions are desired, they'll go here
tgui_alert(src,{"
This verb allows you to spawn inside someone's belly when they are in round.
Make sure you to coordinate with your predator OOCly as well as roleplay approprietly.
You are considered to have been in the belly entire time the predator was around and are not added to crew lists.
This is not intended to be used for mechanical advantage or providing assistance, but for facilitating longterm scenes.
Please do not abuse this ability.
"},"OOC Warning") // Warning.
var/list/eligible_targets = list()
for(var/mob/living/pred in GLOB.living_mob_list)
if(!istype(pred) || !pred.client) // Ignore preds that aren't living mobs or player controlled
continue
if(pred.no_vore) // No vore, no bellies, no inbelly spawning
continue
if(!(get_z(pred) in using_map.station_levels)) // No explo reinforcements
continue
if(ishuman(pred))
var/mob/living/carbon/human/H = pred
if(!H.latejoin_vore)
continue
eligible_targets += H
continue
if(issilicon(pred))
var/mob/living/silicon/S = pred
if(isAI(S))
continue // Sorry, AI buddies. Your vore works too differently.
if(!S.latejoin_vore)
continue
eligible_targets += S
continue
if(isanimal(pred))
var/mob/living/simple_mob/SM = pred
if(!SM.vore_active) // No vore, no bellies, no inbelly spawning
continue
if(!SM.latejoin_vore)
continue
eligible_targets += SM
continue
// Only humans, simple_mobs and non-AI silicons are included. Obscure stuff like bots is skipped.
if(!eligible_targets.len)
to_chat(src, span_notice("No eligible preds were found.")) // :(
return
var/mob/living/target = tgui_input_list(src, "Please specify which character you want to spawn inside of.", "Predator", eligible_targets) // Offer the list of things we gathered.
if(!target || !client) // Did out target cease to exist? Or did we?
return
// Notify them that its now pred's turn
to_chat(src, span_notice("Inbelly spawn request sent to predator."))
target.inbelly_spawn_prompt(client) // Hand reins over to them
/mob/living/proc/inbelly_spawn_prompt(client/potential_prey)
if(!potential_prey || !istype(potential_prey)) // Did our prey cease to exist?
return
@@ -127,7 +62,6 @@ Please do not abuse this ability.
else
to_chat(potential_prey, span_notice("Inbelly spawn cancelled."))
to_chat(src, span_notice("Prey cancelled their inbelly spawn request."))
return
/proc/inbelly_spawn(client/prey, mob/living/pred, obj/belly/target_belly, var/absorbed = FALSE)
// All this is basically admin late spawn-in, but skipping all parts related to records and equipment and with predteremined location
@@ -1,52 +0,0 @@
/mob/observer/dead/verb/soulcatcherjoin()
set category = "Ghost.Join"
set name = "Join Into Soulcatcher(Vore)"
set desc = "Select a player with enabled Soulcatcher to join."
var/list/valid_players = list()
for(var/mob/player in GLOB.player_list)
if(player.soulgem?.flag_check(SOULGEM_ACTIVE | SOULGEM_CATCHING_GHOSTS, TRUE))
valid_players += player
if(!valid_players.len)
to_chat(src, span_warning("No valid players found."))
return
var/picked = tgui_input_list(usr, "Pick a friend with enabled Soulcatcher to join into. Harrass strangers, get banned.","Select a player", valid_players)
if(!picked)
return
if(!ismob(picked))
to_chat(src, span_warning("Target is no mob."))
return
var/mob/M = picked
var/obj/soulgem/gem = M.soulgem
if(!gem?.flag_check(SOULGEM_ACTIVE))
to_chat(src, span_warning("[M] has no enabled Soulcatcher."))
return
var/req_time = world.time
gem.notify_holder("Transient mindstate detected, analyzing...")
sleep(15) //So if they are typing they get interrupted by sound and message, and don't type over the box
if(tgui_alert(M,"[src.name] wants to join into your Soulcatcher.","Soulcatcher Request",list("Deny","Allow"), timeout=1 MINUTES) != "Allow")
to_chat(src, span_warning("[M] has denied your request."))
return
if((world.time - req_time) > 1 MINUTES)
to_chat(M, span_warning("The request had already expired. (1 minute waiting max)"))
return
//Final check since we waited for input a couple times.
if(M && src && src.key && !M.stat && gem?.flag_check(SOULGEM_ACTIVE | SOULGEM_CATCHING_GHOSTS, TRUE))
if(!mind) //No mind yet, aka haven't played in this round.
mind = new(key)
mind.name = name
mind.current = src
mind.active = TRUE
gem.catch_mob(src) //This will result in us being deleted so...