Skip to content

Commit

Permalink
Force-cryo refactor + improvements (BeeStation#10235)
Browse files Browse the repository at this point in the history
* Force-cryo refactor + improvements

* Address reviews.

* Only use on-station pods

* fix comment

* forgot to fix this comment too

* Fix player panel layout

* Address reviews
  • Loading branch information
Absolucy authored Dec 7, 2023
1 parent 3cf2308 commit ec9be3f
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 22 deletions.
17 changes: 14 additions & 3 deletions code/__HELPERS/game.dm
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,22 @@
break

/proc/get_mob_by_ckey(key)
var/ckey = ckey(key) //just to be safe
var/mob_ckey = ckey(key) //just to be safe
if(!mob_ckey)
return
for(var/mob/M as() in GLOB.player_list)
if(M?.ckey == ckey)
if(M?.ckey == mob_ckey)
return M
return null

/proc/get_ckey_last_living(key, healthy = FALSE)
var/mob_ckey = ckey(key) //just to be safe
if(!mob_ckey)
return
for(var/mob/living/potential_target as() in GLOB.mob_living_list)
if(QDELETED(potential_target) || (healthy && potential_target.stat))
continue
if(potential_target.ckey == mob_ckey || (!length(potential_target.ckey) && ckey(potential_target.mind?.key) == mob_ckey))
return potential_target

/proc/considered_alive(datum/mind/M, enforce_human = TRUE)
if(M?.current)
Expand Down
2 changes: 2 additions & 0 deletions code/modules/admin/admin.dm
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@
body += "<A href='?_src_=holder;[HrefToken()];newbankey=[M.key]'>Ban</A> "

body += "<A href='?_src_=holder;[HrefToken()];showmessageckey=[M.ckey]'>Notes</A>"
if(isliving(M))
body += " <A href='?_src_=holder;[HrefToken()];force_cryo=[REF(M)]'>Force Cryo</A> "
if(M.client)
body += " <A href='?_src_=holder;[HrefToken()];sendtoprison=[REF(M)]'>Prison</A> "
body += " <A href='?_src_=holder;[HrefToken()];sendbacktolobby=[REF(M)]'>Send to Lobby</A>"
Expand Down
4 changes: 4 additions & 0 deletions code/modules/admin/player_panel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@
if(!check_rights(R_ADMIN))
return
holder.Topic(null, list("sendbacktolobby" = REF(target_mob), "admin_token" = holder.href_token))
if("force_cryo")
if(!check_rights(R_ADMIN))
return
holder.Topic(null, list("force_cryo" = isliving(target_mob) ? REF(target_mob) : target_ckey, "admin_token" = holder.href_token))


/datum/admins/proc/open_player_panel()
Expand Down
15 changes: 11 additions & 4 deletions code/modules/admin/smites/forcecryo.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
/// Cryo's the target, opening up their job slot in the lobby
/datum/smite/forcecryo
name = "Force Cryo"
/datum/smite/force_cryo_pod
name = "Force Cryo (using centcom pod)"

/datum/smite/forcecryo/effect(client/user, mob/living/target)
/datum/smite/force_cryo_pod/effect(client/user, mob/living/target)
. = ..()
forcecryo(target)
force_cryo(target)

/datum/smite/force_cryo_instant
name = "Force Cryo (instant)"

/datum/smite/force_cryo_instant/effect(client/user, mob/living/target)
. = ..()
instant_force_cryo(target)
16 changes: 12 additions & 4 deletions code/modules/admin/sql_ban_system.dm
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
C.ban_cache[query_build_ban_cache.item[1]] = TRUE
qdel(query_build_ban_cache)

/datum/admins/proc/ban_panel(player_key, player_ip, player_cid, role, duration = 1440, applies_to_admins, reason, edit_id, page, admin_key, global_ban = TRUE)
/datum/admins/proc/ban_panel(player_key, player_ip, player_cid, role, duration = 1440, applies_to_admins, reason, edit_id, page, admin_key, global_ban = TRUE, force_cryo_after = FALSE)
var/suppressor
if(check_rights(R_SUPPRESS, FALSE))
suppressor = TRUE
Expand Down Expand Up @@ -181,7 +181,10 @@
<input type='checkbox' id='lastconn' name='lastconn' value='1' [(isnull(duration) && !player_ip) || (!player_cid) ? " checked": ""]>
<div class='inputbox'></div></label>
<label class='inputlabel checkbox'>Applies to Admins
<input class='redact_incompatible' type='checkbox' id='applyadmins' name='applyadmins' value='1'[applies_to_admins ? " checked": ""]>
<input class='redact_incompatible' type='checkbox' id='applyadmins' name='applyadmins' value='1' [applies_to_admins ? " checked": ""]>
<div class='inputbox'></div></label>
<label class='inputlabel checkbox'>Force Cryo Afterwards
<input class='redact_incompatible' type='checkbox' id='forcecryo' name='forcecryo' value='1' [force_cryo_after ? " checked": ""]>
<div class='inputbox'></div></label>
<input type='submit' value='Submit'>
<br>
Expand Down Expand Up @@ -399,6 +402,7 @@
var/page
var/admin_key
var/redact
var/force_cryo_after = FALSE
var/list/changes = list()
var/list/roles_to_ban = list()
if(href_list["redactioncheck"])
Expand Down Expand Up @@ -438,6 +442,8 @@
if(redact)
error_state += "Admin bans can not be suppressed."
applies_to_admins = TRUE
if(href_list["forcecryo"])
force_cryo_after = TRUE
switch(href_list["radioservban"])
if("local")
if(CONFIG_GET(flag/disable_local_bans))
Expand Down Expand Up @@ -514,9 +520,9 @@
if(edit_id)
edit_ban(edit_id, player_key, ip_check, player_ip, cid_check, player_cid, use_last_connection, applies_to_admins, duration, interval, reason, global_ban, mirror_edit, old_key, old_ip, old_cid, old_applies, old_globalban, page, admin_key, changes)
else
create_ban(player_key, ip_check, player_ip, cid_check, player_cid, use_last_connection, applies_to_admins, duration, interval, severity, reason, global_ban, roles_to_ban, redact)
create_ban(player_key, ip_check, player_ip, cid_check, player_cid, use_last_connection, applies_to_admins, duration, interval, severity, reason, global_ban, roles_to_ban, redact, force_cryo_after)

/datum/admins/proc/create_ban(player_key, ip_check, player_ip, cid_check, player_cid, use_last_connection, applies_to_admins, duration, interval, severity, reason, global_ban, list/roles_to_ban, redact = 0)
/datum/admins/proc/create_ban(player_key, ip_check, player_ip, cid_check, player_cid, use_last_connection, applies_to_admins, duration, interval, severity, reason, global_ban, list/roles_to_ban, redact = FALSE, force_cryo_after = FALSE)
if(!check_rights(R_BAN))
return
if(!SSdbcore.Connect())
Expand Down Expand Up @@ -686,6 +692,8 @@
is_admin = TRUE
if(roles_to_ban[1] == "Server" && (!is_admin || (is_admin && applies_to_admins)))
qdel(i)
if(force_cryo_after)
force_cryo_ckey(player_ckey)

/datum/admins/proc/unban_panel(player_key, admin_key, player_ip, player_cid, page = 0)
if(!check_rights(R_BAN))
Expand Down
23 changes: 23 additions & 0 deletions code/modules/admin/topic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1926,6 +1926,29 @@
return
paper_to_show.ui_interact(usr)

else if(href_list["force_cryo"])
if(!check_rights(R_ADMIN))
return
var/param = href_list["force_cryo"]
// If it's a direct reference to a mob, use that.
var/mob/living/target = locate(param)
if(!istype(target))
// Might be a ckey? Let's see.
target = get_ckey_last_living(target)
if(!istype(target))
to_chat(usr, "<span class='warning'>This can only be used on instances of type /mob/living.</span>")
return
var/method = tgui_alert(usr, "Select force-cryo method", "Cryo Express", list("Centcom Pod (recommended)", "Instant", "Cancel"))
switch(method)
if("Centcom Pod (recommended)")
INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(force_cryo), target)
if("Instant")
INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(instant_force_cryo), target)
else
return
message_admins("[key_name_admin(usr)] force-cryoed [ADMIN_LOOKUPFLW(target)]].")
log_admin("[key_name(usr)] force-cryoed [key_name(target)]].")

/datum/admins/proc/HandleCMode()
if(!check_rights(R_ADMIN))
return
Expand Down
90 changes: 81 additions & 9 deletions code/modules/admin/verbs/forcecryo.dm
Original file line number Diff line number Diff line change
@@ -1,9 +1,81 @@
/proc/forcecryo(mob/target)
var/turf/T = get_turf(target)
new /obj/effect/temp_visual/tornado(T)
sleep(20)
for(var/obj/machinery/cryopod/C in GLOB.machines)
if(!C.occupant)
C.close_machine(target)
C.despawn_occupant()
break
/proc/force_cryo_ckey(target_ckey, instant = FALSE)
var/mob/living/target = get_ckey_last_living(target_ckey, healthy = TRUE)
if(!target)
return
var/method = instant ? GLOBAL_PROC_REF(instant_force_cryo) : GLOBAL_PROC_REF(force_cryo)
INVOKE_ASYNC(GLOBAL_PROC, method, target)

/proc/force_cryo(mob/living/target)
if(!istype(target))
return
var/obj/machinery/cryopod/pod_loc = target.loc
if(istype(pod_loc) && pod_loc.occupant == target)
pod_loc.despawn_occupant()
return
var/turf/target_turf = get_turf(target)
target.ghostize(can_reenter_corpse = FALSE)
// unbuckle them from everything and release them from any pulls
target.unbuckle_all_mobs(force = TRUE)
target.stop_pulling()
target.pulledby?.stop_pulling()
target.buckled?.unbuckle_mob(target, force = TRUE)
// ensure that they don't move / get moved and cause any weirdness
target.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
target.Stun(INFINITY, ignore_canstun = TRUE)
target.move_resist = INFINITY
target.anchored = TRUE
target.status_flags |= GODMODE
// ensure they're on a turf
target.forceMove(target_turf)
// send a fancy centcom pod, so nobody ICly questions this
var/obj/structure/closet/supplypod/force_cryo/cryo_express = new
cryo_express.target = target
new /obj/effect/pod_landingzone(target_turf, cryo_express)

/proc/instant_force_cryo(mob/living/target)
if(!istype(target))
return
// unbuckle them from everything, and release them from any pulls
target.pulledby?.stop_pulling()
target.buckled?.unbuckle_mob(target, force = TRUE)
for(var/obj/machinery/cryopod/pod in GLOB.machines)
if(!is_station_level(pod.z) || !QDELETED(pod.occupant) || pod.panel_open)
continue
pod.close_machine(target)
pod.despawn_occupant()
return
message_admins("<span class='danger'>Failed to force-cryo [ADMIN_LOOKUPFLW(target)] (no valid cryopods)</span>")
log_admin("Failed to force-cryo [key_name(target)] (no valid cryopods)")

/obj/structure/closet/supplypod/force_cryo
name = "\improper CentCom employee retrieval pod"
desc = "A pod used by Central Command to retrieve certain employees from the station for long-term cryogenic storage."
style = STYLE_CENTCOM
bluespace = TRUE
reversing = TRUE
specialised = TRUE
explosionSize = list(0, 0, 0, 0)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
reverse_delays = list(POD_TRANSIT = 0.5 SECONDS, POD_FALLING = 0.5 SECONDS, POD_OPENING = 0.5 SECONDS, POD_LEAVING = 1.5 SECONDS)
var/mob/living/target

/obj/structure/closet/supplypod/force_cryo/insert(mob/living/to_insert, atom/movable/holder)
if(!insertion_allowed(to_insert))
return FALSE
// make SURE they aren't buckled or being pulled.
to_insert.pulledby?.stop_pulling()
to_insert.buckled?.unbuckle_mob(target, force = TRUE)
to_insert.forceMove(holder)
return TRUE

/obj/structure/closet/supplypod/force_cryo/insertion_allowed(atom/to_insert)
return to_insert == target

/obj/structure/closet/supplypod/force_cryo/preOpen()
// if we're going back to centcom, now we just cryo them
if(!reversing && !QDELETED(target))
target.moveToNullspace()
INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(instant_force_cryo), target)
qdel(src)
return
return ..()
5 changes: 3 additions & 2 deletions tgui/packages/tgui/interfaces/PlayerPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const LOG_TYPES_REVERSE = {

const LOG_TYPES_LIST = Object.keys(LOG_TYPES_REVERSE);

const PANEL_HEIGHT = 260;
const PANEL_HEIGHT = 300;

/**
--------------------
Expand Down Expand Up @@ -88,7 +88,7 @@ export const PlayerPanel = (_, context) => {
return (
<Window
width={1000}
height={615}
height={700}
theme="admin"
buttons={
<>
Expand Down Expand Up @@ -441,6 +441,7 @@ class PlayerDetailsActionButtons extends PureComponent {
'Ban': 'open_ban',
'Smite': 'smite',
'Prison': 'jail',
'Cryo': 'force_cryo',
},
};
if (!has_mind) {
Expand Down

0 comments on commit ec9be3f

Please sign in to comment.