Merge branch 'master' into sploinky-2

This commit is contained in:
BongaTheProto
2022-03-19 15:03:38 -05:00
35 changed files with 2549 additions and 464 deletions
+173 -170
View File
@@ -1282,14 +1282,6 @@
icon_state = "dark"
},
/area/holodeck/rec_center/chapelcourt)
"dy" = (
/obj/structure/table/wood/fancy,
/obj/item/book/manual/splurt_space_law,
/turf/open/floor/holofloor{
dir = 8;
icon_state = "dark"
},
/area/holodeck/rec_center/chapelcourt)
"dz" = (
/obj/structure/closet{
name = "Evidence Closet"
@@ -3979,22 +3971,6 @@
},
/turf/open/floor/plasteel/dark,
/area/centcom/control)
"kc" = (
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/obj/structure/table/wood,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/control)
"kd" = (
/obj/item/wrench,
/obj/item/restraints/handcuffs,
@@ -5312,21 +5288,6 @@
},
/turf/open/floor/plasteel,
/area/centcom/control)
"mU" = (
/obj/item/book/manual/splurt_space_law,
/obj/structure/table/wood,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/control)
"mV" = (
/obj/machinery/vending/cola,
/obj/effect/turf_decal/tile/neutral{
@@ -7079,28 +7040,6 @@
/obj/effect/light_emitter,
/turf/open/floor/plating/asteroid/snow/airless,
/area/syndicate_mothership)
"qb" = (
/obj/structure/table/wood,
/obj/item/folder/red,
/obj/item/book/manual/splurt_space_law,
/obj/item/restraints/handcuffs,
/obj/item/assembly/flash/handheld,
/obj/machinery/airalarm{
dir = 1;
pixel_y = -22
},
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/ferry)
"qc" = (
/obj/structure/table/wood,
/obj/item/folder/red,
@@ -7453,6 +7392,13 @@
},
/turf/open/floor/plasteel,
/area/slavers)
"qM" = (
/obj/effect/turf_decal/stripes/corner,
/obj/machinery/computer/cryopod{
pixel_x = 32
},
/turf/open/floor/plasteel,
/area/slavers)
"qP" = (
/obj/structure/bed/matress,
/turf/open/floor/plating,
@@ -7567,22 +7513,6 @@
/obj/item/pen/fountain,
/turf/open/indestructible/hotelwood,
/area/centcom/holding)
"rk" = (
/obj/structure/table/reinforced,
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/ferry)
"rl" = (
/obj/machinery/computer/auxillary_base{
pixel_y = 32
@@ -10812,6 +10742,12 @@
},
/turf/open/floor/plasteel,
/area/centcom/control)
"yk" = (
/obj/structure/table/reinforced,
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/turf/open/floor/plasteel/grimy,
/area/centcom/ferry)
"yn" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/sign/warning/vacuum,
@@ -11818,6 +11754,24 @@
},
/turf/open/floor/plasteel,
/area/syndicate_mothership)
"AE" = (
/obj/structure/table/wood,
/obj/item/folder/red,
/obj/item/book/manual/splurt_space_law,
/obj/item/restraints/handcuffs,
/obj/item/assembly/flash/handheld,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/ferry)
"AF" = (
/obj/structure/toilet{
dir = 4
@@ -12091,6 +12045,24 @@
/obj/effect/turf_decal/tile/blue,
/turf/open/floor/plasteel/dark,
/area/slavers)
"Br" = (
/obj/structure/table/wood,
/obj/item/folder/red,
/obj/item/book/manual/splurt_space_law,
/obj/item/restraints/handcuffs,
/obj/item/assembly/flash/handheld,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/tdome/tdomeadmin)
"Bu" = (
/obj/structure/table/wood,
/obj/item/paper_bin,
@@ -12113,12 +12085,6 @@
},
/turf/open/floor/plasteel/grimy,
/area/centcom/ferry)
"Bw" = (
/obj/structure/table/reinforced,
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/turf/open/floor/plasteel/grimy,
/area/centcom/ferry)
"Bx" = (
/obj/structure/table/reinforced,
/obj/item/storage/fancy/donut_box,
@@ -12564,24 +12530,6 @@
/obj/structure/statue/uranium/nuke,
/turf/open/floor/plating/asteroid/snow/airless,
/area/syndicate_mothership)
"Cq" = (
/obj/structure/table/wood,
/obj/item/folder/red,
/obj/item/book/manual/splurt_space_law,
/obj/item/restraints/handcuffs,
/obj/item/assembly/flash/handheld,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/ferry)
"Cr" = (
/obj/structure/table/wood,
/obj/item/folder/red,
@@ -12823,26 +12771,6 @@
},
/turf/open/floor/plasteel,
/area/centcom/ferry)
"CH" = (
/obj/structure/table/reinforced,
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/obj/machinery/firealarm{
dir = 8;
pixel_x = 24
},
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/control)
"CI" = (
/obj/structure/table,
/obj/item/paper_bin,
@@ -13327,22 +13255,6 @@
},
/turf/open/floor/plasteel/dark,
/area/centcom/evac)
"DA" = (
/obj/structure/table/reinforced,
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/evac)
"DB" = (
/obj/item/storage/box/ids{
pixel_x = 3;
@@ -16589,24 +16501,6 @@
},
/turf/open/floor/plasteel/dark,
/area/tdome/tdomeadmin)
"Kp" = (
/obj/structure/table/wood,
/obj/item/folder/red,
/obj/item/book/manual/splurt_space_law,
/obj/item/restraints/handcuffs,
/obj/item/assembly/flash/handheld,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/tdome/tdomeadmin)
"Kq" = (
/obj/structure/table/wood,
/obj/item/clipboard,
@@ -17062,6 +16956,21 @@
},
/turf/open/floor/wood,
/area/centcom/holding)
"Lr" = (
/obj/item/book/manual/splurt_space_law,
/obj/structure/table/wood,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/control)
"Ls" = (
/obj/docking_port/stationary{
dir = 4;
@@ -19097,6 +19006,28 @@
},
/turf/open/floor/plasteel/dark,
/area/slavers)
"Tb" = (
/obj/structure/table/wood,
/obj/item/folder/red,
/obj/item/book/manual/splurt_space_law,
/obj/item/restraints/handcuffs,
/obj/item/assembly/flash/handheld,
/obj/machinery/airalarm{
dir = 1;
pixel_y = -22
},
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/ferry)
"Td" = (
/obj/structure/fireplace,
/turf/open/floor/carpet/red,
@@ -19353,10 +19284,6 @@
},
/turf/open/indestructible/hotelwood,
/area/centcom/holding)
"Ud" = (
/obj/effect/turf_decal/stripes/corner,
/turf/open/floor/plasteel,
/area/slavers)
"Ug" = (
/obj/machinery/door/poddoor/shuttledock{
checkdir = 1;
@@ -19481,6 +19408,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plasteel,
/area/slavers)
"UB" = (
/obj/structure/table/wood/fancy,
/obj/item/book/manual/splurt_space_law,
/turf/open/floor/holofloor{
dir = 8;
icon_state = "dark"
},
/area/holodeck/rec_center/chapelcourt)
"UC" = (
/obj/machinery/vending/cola,
/turf/open/floor/plasteel,
@@ -20084,6 +20019,22 @@
},
/turf/open/floor/plasteel,
/area/centcom/supplypod)
"WP" = (
/obj/structure/table/reinforced,
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/ferry)
"WQ" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/centcom{
@@ -20108,6 +20059,22 @@
/obj/structure/closet/syndicate/personal,
/turf/open/floor/wood,
/area/syndicate_mothership)
"WT" = (
/obj/structure/table/reinforced,
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/evac)
"WU" = (
/obj/structure/flora/bush,
/obj/structure/sign/warning/securearea{
@@ -20498,6 +20465,26 @@
/obj/item/kitchen/rollingpin,
/turf/open/floor/plasteel/cafeteria,
/area/slavers)
"YD" = (
/obj/structure/table/reinforced,
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/obj/machinery/firealarm{
dir = 8;
pixel_x = 24
},
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/control)
"YF" = (
/obj/machinery/vending/clothing{
extended_inventory = 1
@@ -20543,6 +20530,22 @@
/obj/item/book/manual/hydroponics_pod_people,
/turf/open/indestructible/hotelwood,
/area/centcom/holding)
"YQ" = (
/obj/item/book/manual/splurt_space_law,
/obj/item/taperecorder,
/obj/structure/table/wood,
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
dir = 4
},
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
/turf/open/floor/plasteel/dark,
/area/centcom/control)
"YU" = (
/obj/structure/window/reinforced{
dir = 1
@@ -55187,7 +55190,7 @@ aa
aa
aa
oe
rk
WP
sq
to
uj
@@ -57259,7 +57262,7 @@ oA
uV
Bu
BZ
Cq
AE
mD
aa
aa
@@ -57498,7 +57501,7 @@ of
oA
oX
pH
qb
Tb
mD
rs
sw
@@ -58028,7 +58031,7 @@ zb
pg
Ac
AK
Bw
yk
pg
Ct
nT
@@ -62945,7 +62948,7 @@ JI
JQ
Ka
JG
Kp
Br
IR
KG
Iv
@@ -63170,7 +63173,7 @@ tL
io
iu
io
CH
YD
vM
Ds
DG
@@ -68541,7 +68544,7 @@ iH
iq
iA
il
mU
Lr
nt
nO
iC
@@ -71104,7 +71107,7 @@ aa
aa
aa
in
kc
YQ
kl
kE
lb
@@ -71396,7 +71399,7 @@ BP
Cf
Cc
Dg
DA
WT
VO
WK
WK
@@ -81205,7 +81208,7 @@ XS
ZD
Co
Pi
Ud
qM
Xn
Xn
Wg
@@ -82543,7 +82546,7 @@ cS
cY
dh
bj
dy
UB
dV
ep
eB
+166 -164
View File
@@ -10,7 +10,6 @@
GLOBAL_LIST_EMPTY(cryopod_computers)
//Main cryopod console.
/obj/machinery/computer/cryopod
name = "general oversight console"
desc = "An interface between crew and the cryogenic storage/teleporter storage oversight systems."
@@ -143,7 +142,6 @@ GLOBAL_LIST_EMPTY(cryopod_computers)
///Weakref to our controller
var/datum/weakref/control_computer_weakref
COOLDOWN_DECLARE(last_no_computer_message)
/obj/machinery/cryopod/Initialize()
..()
@@ -151,32 +149,16 @@ GLOBAL_LIST_EMPTY(cryopod_computers)
/obj/machinery/cryopod/LateInitialize()
update_icon()
find_control_computer()
control_computer_weakref = cryo_find_control_computer(src)
// This is not a good situation
/obj/machinery/cryopod/Destroy()
control_computer_weakref = null
return ..()
/obj/machinery/cryopod/proc/find_control_computer(urgent = FALSE)
for(var/cryo_console as anything in GLOB.cryopod_computers)
var/obj/machinery/computer/cryopod/console = cryo_console
if(get_area(console) == get_area(src))
control_computer_weakref = WEAKREF(console)
break
// Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged
if(!control_computer_weakref && urgent && COOLDOWN_FINISHED(src, last_no_computer_message))
COOLDOWN_START(src, last_no_computer_message, 5 MINUTES)
log_admin("\The [src] in [get_area(src)] could not find control computer!")
message_admins("\The [src] in [get_area(src)] could not find control computer!")
last_no_computer_message = world.time
return control_computer_weakref != null
/obj/machinery/cryopod/close_machine(atom/movable/target)
if(!control_computer_weakref)
find_control_computer(TRUE)
control_computer_weakref = cryo_find_control_computer(src, TRUE)
if((isnull(target) || isliving(target)) && state_open && !panel_open)
..(target)
var/mob/living/mob_occupant = occupant
@@ -214,12 +196,11 @@ GLOBAL_LIST_EMPTY(cryopod_computers)
if(!mob_occupant.client && COOLDOWN_FINISHED(src, despawn_world_time))
if(!control_computer_weakref)
find_control_computer(urgent = TRUE)
control_computer_weakref = cryo_find_control_computer(src, urgent = TRUE)
despawn_occupant()
/obj/machinery/cryopod/proc/handle_objectives()
var/mob/living/mob_occupant = occupant
/proc/cryo_handle_objectives(mob/living/mob_occupant)
// Update any existing objectives involving this mob.
for(var/datum/objective/objective in GLOB.objectives)
// We don't want revs to get objectives that aren't for heads of staff. Letting
@@ -276,147 +257,6 @@ GLOBAL_LIST_EMPTY(cryopod_computers)
return TRUE
return FALSE
// This function can not be undone; do not call this unless you are sure
/obj/machinery/cryopod/proc/despawn_occupant()
var/mob/living/mob_occupant = occupant
var/list/crew_member = list()
crew_member["name"] = mob_occupant.real_name
if(mob_occupant.mind)
// Handle job slot/tater cleanup.
var/job = mob_occupant.mind.assigned_role
crew_member["job"] = job
SSjob.FreeRole(job)
// if(LAZYLEN(mob_occupant.mind.objectives))
// mob_occupant.mind.objectives.Cut()
mob_occupant.mind.special_role = null
else
crew_member["job"] = "N/A"
// Delete them from datacore.
var/announce_rank = null
for(var/datum/data/record/medical_record as anything in GLOB.data_core.medical)
if(medical_record.fields["name"] == mob_occupant.real_name)
qdel(medical_record)
for(var/datum/data/record/security_record as anything in GLOB.data_core.security)
if(security_record.fields["name"] == mob_occupant.real_name)
qdel(security_record)
for(var/datum/data/record/general_record as anything in GLOB.data_core.general)
if(general_record.fields["name"] == mob_occupant.real_name)
announce_rank = general_record.fields["rank"]
qdel(general_record)
var/obj/machinery/computer/cryopod/control_computer = control_computer_weakref?.resolve()
if(!control_computer)
control_computer_weakref = null
else
control_computer.frozen_crew += list(crew_member)
// Make an announcement and log the person entering storage.
if(GLOB.announcement_systems.len)
var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems)
announcer.announce(tele ? "CRYOSTORAGE_TELE" : "CRYOSTORAGE", mob_occupant.real_name, announce_rank, list())
visible_message(span_notice("\The [src] hums and hisses as it [tele ? "teleports" : "moves"] [mob_occupant.real_name] [tele ? "to centcom" : "into storage"]."))
if(tele)
do_fake_sparks(2, TRUE, src) // Oh yeah plasmafire time.
playsound(src, 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff_exponent = 5)
/* ============================= */
var/list/obj/item/storing = list()
var/list/obj/item/destroying = list()
var/list/obj/item/destroy_later = list()
var/drop_to_ground = !istype(control_computer, /obj/machinery/computer/cryopod) || !control_computer.allow_items
var/mind_identity = mob_occupant.mind?.name
var/occupant_identity = mob_occupant.real_name
if(iscyborg(mob_occupant))
var/mob/living/silicon/robot/R = mob_occupant
if(R.mmi?.brain)
destroy_later += R.mmi
destroy_later += R.mmi.brain
for(var/i in R.module)
if(!isitem(i))
destroying += i
continue
var/obj/item/I = i
// let's be honest we only care about the trash bag don't beat around the bush
if(SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE))
storing += I.contents
for(var/atom/movable/AM in I.contents)
AM.forceMove(src)
R.module.remove_module(I, TRUE)
else
if(ishuman(mob_occupant))
var/mob/living/carbon/human/H = mob_occupant
if(H.mind && H.client && H.client.prefs && H == H.mind.original_character)
H.SaveTCGCards()
var/list/gear = list()
if(iscarbon(mob_occupant)) // sorry simp-le-mobs deserve no mercy
var/mob/living/carbon/C = mob_occupant
gear = C.get_all_gear()
for(var/obj/item/item_content as anything in gear)
if(!istype(item_content) || HAS_TRAIT(item_content, TRAIT_NODROP))
destroying += item_content
continue
if(item_content.item_flags & (DROPDEL | ABSTRACT))
destroying += item_content
continue
// destroying stays in mob for a bit
item_content.forceMove(src)
// WEE WOO SNOWFLAKE TIME
if(istype(item_content, /obj/item/pda))
var/obj/item/pda/P = item_content
if((P.owner == mind_identity) || (P.owner == occupant_identity))
destroying += P
else
storing += P
else if(istype(item_content, /obj/item/card/id))
var/obj/item/card/id/idcard = item_content
if((idcard.registered_name == mind_identity) || (idcard.registered_name == occupant_identity))
destroying += idcard
else
storing += idcard
else
storing += item_content
// get rid of mobs
for(var/mob/living/L in mob_occupant.GetAllContents() - mob_occupant)
L.forceMove(drop_location())
if(storing.len)
var/obj/item/storage/box/blue/cryostorage_items/O = new /obj/item/storage/box/blue/cryostorage_items
O.name = "[tele ? "early leave" : "cryogenic"] retrieval package: [mob_occupant.real_name]"
O.real_name = mob_occupant.real_name
for(var/i in storing)
var/obj/item/I = i
I.forceMove(O)
O.forceMove(drop_to_ground ? control_computer.drop_location() : control_computer)
if((control_computer == control_computer) && !drop_to_ground)
control_computer.stored_packages += O
/* ============================= */
// Ghost and delete the mob.
// they already did ghost verb
var/mob/dead/observer/G = mob_occupant.get_ghost(TRUE)
if(G)
G.voluntary_ghosted = TRUE
// they did not ghost verb
else
mob_occupant.ghostize(FALSE, penalize = TRUE, voluntary = TRUE, cryo = TRUE)
QDEL_LIST(destroying)
handle_objectives()
QDEL_NULL(occupant)
QDEL_LIST(destroy_later)
open_machine()
name = initial(name)
/obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user)
if(!istype(target) || !can_interact(user) || !target.Adjacent(user) || !ismob(target) || isanimal(target) || !istype(user.loc, /turf) || target.buckled)
return
@@ -502,3 +342,165 @@ GLOBAL_LIST_EMPTY(cryopod_computers)
/obj/item/storage/box/blue/cryostorage_items
w_class = WEIGHT_CLASS_HUGE
var/real_name = "fire coderbus"
occupant
// This function can not be undone; do not call this unless you are sure
/obj/machinery/cryopod/proc/despawn_occupant()
cryoMob(occupant, control_computer_weakref, src, tele, initial(name))
/proc/cryoMob(mob/living/mob_occupant, datum/weakref/control_computer_weakref, obj/machinery/cryopod/pod, is_teleporter, initial_name, effects = FALSE)
var/list/crew_member = list()
// No computer passed in, use admin-cryo instead
if (!control_computer_weakref)
control_computer_weakref = cryo_find_control_computer(urgent = TRUE)
if (effects)
// Fancy effect for admin-cryo
playsound(get_turf(mob_occupant.loc), 'sound/magic/Repulse.ogg', 100, 1)
var/datum/effect_system/spark_spread/quantum/sparks = new
sparks.set_up(10, 1, mob_occupant)
sparks.attach(mob_occupant.loc)
sparks.start()
crew_member["name"] = mob_occupant.real_name
if(mob_occupant.mind)
// Handle job slot/tater cleanup.
var/job = mob_occupant.mind.assigned_role
crew_member["job"] = job
SSjob.FreeRole(job)
// if(LAZYLEN(mob_occupant.mind.objectives))
// mob_occupant.mind.objectives.Cut()
mob_occupant.mind.special_role = null
else
crew_member["job"] = "N/A"
// Delete them from datacore.
var/announce_rank = null
for(var/datum/data/record/medical_record as anything in GLOB.data_core.medical)
if(medical_record.fields["name"] == mob_occupant.real_name)
qdel(medical_record)
for(var/datum/data/record/security_record as anything in GLOB.data_core.security)
if(security_record.fields["name"] == mob_occupant.real_name)
qdel(security_record)
for(var/datum/data/record/general_record as anything in GLOB.data_core.general)
if(general_record.fields["name"] == mob_occupant.real_name)
announce_rank = general_record.fields["rank"]
qdel(general_record)
var/obj/machinery/computer/cryopod/control_computer = control_computer_weakref?.resolve()
if(!control_computer)
control_computer_weakref = null
else
control_computer.frozen_crew += list(crew_member)
// Make an announcement and log the person entering storage.
if(GLOB.announcement_systems.len)
var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems)
announcer.announce(is_teleporter ? "CRYOSTORAGE_TELE" : "CRYOSTORAGE", mob_occupant.real_name, announce_rank, list())
if (pod)
pod.visible_message(span_notice("\The [pod] hums and hisses as it [is_teleporter ? "teleports" : "moves"] [mob_occupant.real_name] [is_teleporter ? "to centcom" : "into storage"]."))
if(is_teleporter)
do_fake_sparks(2, TRUE, pod) // Oh yeah plasmafire time.
playsound(pod, 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff_exponent = 5)
/* ============================= */
var/list/obj/item/storing = list()
var/list/obj/item/destroying = list()
var/list/obj/item/destroy_later = list()
var/drop_to_ground = !istype(control_computer, /obj/machinery/computer/cryopod) || !control_computer.allow_items
var/mind_identity = mob_occupant.mind?.name
var/occupant_identity = mob_occupant.real_name
if(iscyborg(mob_occupant))
var/mob/living/silicon/robot/R = mob_occupant
if(R.mmi?.brain)
destroy_later += R.mmi
destroy_later += R.mmi.brain
for(var/i in R.module)
if(!isitem(i))
destroying += i
continue
var/obj/item/I = i
// let's be honest we only care about the trash bag don't beat around the bush
if(SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE))
storing += I.contents
for(var/atom/movable/AM in I.contents)
if(pod)
AM.forceMove(pod)
R.module.remove_module(I, TRUE)
else
if(ishuman(mob_occupant))
var/mob/living/carbon/human/H = mob_occupant
if(H.mind && H.client && H.client.prefs && H == H.mind.original_character)
H.SaveTCGCards()
var/list/gear = list()
if(iscarbon(mob_occupant)) // sorry simp-le-mobs deserve no mercy
var/mob/living/carbon/C = mob_occupant
gear = C.get_all_gear()
for(var/obj/item/item_content as anything in gear)
if(!istype(item_content) || HAS_TRAIT(item_content, TRAIT_NODROP))
destroying += item_content
continue
if(item_content.item_flags & (DROPDEL | ABSTRACT))
destroying += item_content
continue
// destroying stays in mob for a bit
if(pod)
item_content.forceMove(pod)
// WEE WOO SNOWFLAKE TIME
if(istype(item_content, /obj/item/pda))
var/obj/item/pda/P = item_content
if((P.owner == mind_identity) || (P.owner == occupant_identity))
destroying += P
else
storing += P
else if(istype(item_content, /obj/item/card/id))
var/obj/item/card/id/idcard = item_content
if((idcard.registered_name == mind_identity) || (idcard.registered_name == occupant_identity))
destroying += idcard
else
storing += idcard
else
storing += item_content
// get rid of mobs
if (pod)
for(var/mob/living/L in mob_occupant.GetAllContents() - mob_occupant)
L.forceMove(pod.drop_location())
if(storing.len)
var/obj/item/storage/box/blue/cryostorage_items/O = new /obj/item/storage/box/blue/cryostorage_items
O.name = "[is_teleporter ? "early leave" : "cryogenic"] retrieval package: [mob_occupant.real_name]"
O.real_name = mob_occupant.real_name
for(var/i in storing)
var/obj/item/I = i
I.forceMove(O)
O.forceMove(drop_to_ground ? control_computer.drop_location() : control_computer)
if((control_computer == control_computer) && !drop_to_ground)
control_computer.stored_packages += O
/* ============================= */
// Ghost and delete the mob.
// they already did ghost verb
var/mob/dead/observer/G = mob_occupant.get_ghost(TRUE)
if(G)
G.voluntary_ghosted = TRUE
// they did not ghost verb
else
mob_occupant.ghostize(FALSE, penalize = TRUE, voluntary = TRUE, cryo = TRUE)
QDEL_LIST(destroying)
cryo_handle_objectives()
QDEL_NULL(mob_occupant)
QDEL_LIST(destroy_later)
if (pod)
pod.open_machine()
pod.name = initial_name
+5 -2
View File
@@ -16,6 +16,11 @@
set name = "Show Player Panel"
set desc="Edit player (respawn, ban, heal, etc)"
// Based on client setting, use modern TGUI player panel instead
if(usr.client.prefs.use_new_playerpanel)
usr.client.holder.show_player_panel2(M)
return
if(!check_rights())
return
@@ -74,8 +79,6 @@
body += "<a href='?_src_=holder;[HrefToken()];borgpanel=[REF(M)]'>BP</a> - "
body += "<a href='?priv_msg=[M.ckey]'>PM</a> - "
body += "<a href='?_src_=holder;[HrefToken()];subtlemessage=[REF(M)]'>SM</a> - "
if (ishuman(M) && M.mind)
body += "<a href='?_src_=holder;[HrefToken()];HeadsetMessage=[REF(M)]'>HM</a> - "
body += "<a href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(M)]'>FLW</a> - "
//Default to client logs if available
var/source = LOGSRC_MOB
+3 -5
View File
@@ -46,7 +46,6 @@ GLOBAL_PROTECT(admin_verbs_admin)
/client/proc/getserverlogs, /*for accessing server logs*/
/client/proc/getcurrentlogs, /*for accessing server logs for the current round*/
/client/proc/cmd_admin_subtle_message, /*send a message to somebody as a 'voice in their head'*/
/client/proc/cmd_admin_headset_message, /*send a message to somebody through their headset as CentCom*/
/client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/
/client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/
/client/proc/centcom_podlauncher,/*Open a window to launch a Supplypod and configure it or it's contents*/
@@ -229,8 +228,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
/datum/admins/proc/set_admin_notice,
/client/proc/admin_ghost,
/client/proc/toggle_view_range,
/client/proc/cmd_admin_subtle_message,
/client/proc/cmd_admin_headset_message,
/client/proc/cmd_admin_check_contents,
/datum/admins/proc/access_news_network,
/client/proc/admin_end_shift,
@@ -713,7 +710,8 @@ GLOBAL_PROTECT(admin_verbs_hideable)
var/type_length = length_char("/obj/effect/proc_holder/spell") + 2
for(var/A in GLOB.spells)
spell_list[copytext_char("[A]", type_length)] = A
var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in sortList(spell_list)
var/obj/effect/proc_holder/spell/S = tgui_input_list(usr, "Choose a spell to give", "ABRAKADABRA", sortList(spell_list)) //input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in sortList(spell_list)
if(!S)
return
@@ -734,7 +732,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
set desc = "Remove a spell from the selected mob."
if(T?.mind)
var/obj/effect/proc_holder/spell/S = input("Choose the spell to remove", "NO ABRAKADABRA") as null|anything in sortList(T.mind.spell_list)
var/obj/effect/proc_holder/spell/S = tgui_input_list(usr, "Choose the spell to remove", "NO ABRAKADABRA", sortList(T.mind.spell_list)) // input("Choose the spell to remove", "NO ABRAKADABRA") as null|anything in sortList(T.mind.spell_list)
if(S)
T.mind.RemoveSpell(S)
log_admin("[key_name(usr)] removed the spell [S] from [key_name(T)].")
+508
View File
@@ -0,0 +1,508 @@
GLOBAL_LIST_INIT(mute_bits, list(
list(name = "IC", bitflag = MUTE_IC),
list(name = "OOC", bitflag = MUTE_OOC),
list(name = "Pray", bitflag = MUTE_PRAY),
list(name = "Ahelp", bitflag = MUTE_ADMINHELP),
list(name = "Deadchat", bitflag = MUTE_DEADCHAT)
))
GLOBAL_LIST_INIT(pp_limbs, list(
"Head" = BODY_ZONE_HEAD,
"Left leg" = BODY_ZONE_L_LEG,
"Right leg" = BODY_ZONE_R_LEG,
"Left arm" = BODY_ZONE_L_ARM,
"Right arm" = BODY_ZONE_R_ARM
))
/datum/admins/proc/show_player_panel2(mob/M)
if(!M)
to_chat(owner, "You seem to be selecting a mob that doesn't exist anymore.")
return
// this is stupid, thanks byond
if(istype(src, /client))
var/client/C = src
src = C.holder
if(!check_rights())
to_chat(owner, "Error: you are not an admin!")
return
if(!M.mob_panel)
M.create_player_panel()
M.mob_panel.ui_interact(owner.mob)
/datum/player_panel
var/mob/targetMob
var/client/targetClient
var/list/roleStatus // A list of each role and whether they are banned or not for this player.
var/antagBanReason
var/activeRoleBans
var/mobSize // Because aparently there is no variable that tracks this on the mob??
/datum/player_panel/New(mob/target)
. = ..()
targetMob = target
var/mob/living/L = targetMob
if (istype(L))
mobSize = L.mob_size
/datum/player_panel/Destroy(force, ...)
targetMob = null
targetClient = null
roleStatus = null
antagBanReason = null
activeRoleBans = null
mobSize = null
SStgui.close_uis(src)
return ..()
/datum/player_panel/ui_interact(mob/user, datum/tgui/ui)
if(!targetMob)
return
ui = SStgui.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "PlayerPanel2", "[targetMob.name] Player Panel")
ui.open()
/datum/player_panel/ui_state(mob/user)
return GLOB.admin_state
/datum/player_panel/ui_data(mob/user)
. = list()
.["mob_name"] = targetMob.real_name
// .["current_permissions"] = user.client?.holder?.rank.rights
.["mob_type"] = targetMob.type
.["admin_mob_type"] = user.client?.mob.type
.["godmode"] = targetMob.status_flags & GODMODE
var/mob/living/L = targetMob
if (istype(L))
.["is_frozen"] = L.admin_frozen
.["is_slept"] = L.admin_sleeping
.["mob_scale"] = mobSize
if(targetMob.client)
targetClient = targetMob.client
.["client_ckey"] = targetClient.ckey
.["client_muted"] = targetClient.prefs.muted
.["client_rank"] = targetClient.holder ? targetClient.holder.rank : "Player"
if (!roleStatus)
updateJobbanStatus()
.["roles"] = roleStatus
.["antag_ban_reason"] = antagBanReason
.["active_role_ban_count"] = activeRoleBans
else
targetClient = null
roleStatus = null
antagBanReason = null
.["client_ckey"] = null
/datum/player_panel/ui_static_data()
. = list()
.["transformables"] = GLOB.pp_transformables
.["glob_limbs"] = GLOB.pp_limbs
.["glob_mute_bits"] = GLOB.mute_bits
.["current_time"] = time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")
.["initial_scale"] = 1
if(targetClient)
var/byond_version = "Unknown"
if(targetClient.byond_version)
byond_version = "[targetClient.byond_version].[targetClient.byond_build ? targetClient.byond_build : "xxx"]"
.["data_byond_version"] = byond_version
.["data_player_join_date"] = targetClient.player_join_date
.["data_account_join_date"] = targetClient.account_join_date
.["data_related_cid"] = targetClient.related_accounts_cid
.["data_related_ip"] = targetClient.related_accounts_ip
.["initial_scale"] = targetClient.prefs.features["body_size"]
if(CONFIG_GET(flag/use_exp_tracking))
.["playtimes_enabled"] = TRUE
.["playtime"] = targetMob.client.get_exp_living()
/datum/player_panel/ui_act(action, params, datum/tgui/ui)
if(..())
return
var/client/admin = usr.client
if (!check_rights(R_ADMIN))
message_admins("<span class='adminhelp'>WARNING: NON-ADMIN [ADMIN_LOOKUPFLW(admin)] ACCESSING ADMIN PANEL. WARN Casper#3044.</span>")
to_chat(admin, "Error: you are not an admin!")
return
switch(action)
if ("edit_rank")
if (!targetMob.client?.ckey)
return
var/list/context = list()
context["key"] = targetMob.client.ckey
if (GLOB.admin_datums[targetMob.client.ckey] || GLOB.deadmins[targetMob.client.ckey])
context["editrights"] = "rank"
else
context["editrights"] = "add"
admin.holder.edit_rights_topic(context)
if ("access_variables")
admin.debug_variables(targetMob)
if ("access_playtimes")
if (targetMob.client)
admin.holder.cmd_show_exp_panel(targetMob.client)
if ("private_message")
admin.cmd_admin_pm_context(targetMob)
if ("subtle_message")
admin.cmd_admin_subtle_headset_message(targetMob)
if ("set_name")
targetMob.vv_auto_rename(params["name"])
if ("heal")
admin.cmd_admin_rejuvenate(targetMob)
if ("ghost")
if(targetMob.client)
log_admin("[key_name(admin)] ejected [key_name(targetMob)] from their body.")
message_admins("[key_name_admin(admin)] ejected [key_name_admin(targetMob)] from their body.")
to_chat(targetMob, "<span class='danger'>An admin has ejected you from your body.</span>")
targetMob.ghostize(FALSE)
if ("offer_control")
offer_control(targetMob)
if ("take_control")
var/mob/adminMob = admin.mob
// Disassociates observer mind from the body mind
if(targetMob.client)
targetMob.ghostize(FALSE)
else
for(var/mob/dead/observer/ghost in GLOB.dead_mob_list)
if(targetMob.mind == ghost.mind)
ghost.mind = null
targetMob.ckey = adminMob.ckey
qdel(adminMob)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] took control of [targetMob].</span>")
log_admin("[key_name(usr)] took control of [targetMob].")
addtimer(CALLBACK(targetMob.mob_panel, /datum.proc/ui_interact, targetMob), 0.1 SECONDS)
if ("smite")
admin.smite(targetMob)
if ("bring")
admin.Getmob(targetMob)
if ("orbit")
if(!isobserver(admin.mob))
admin.admin_ghost()
var/mob/dead/observer/O = admin.mob
O.ManualFollow(targetMob)
if ("jump_to")
admin.jumptomob(targetMob)
if ("freeze")
var/mob/living/L = targetMob
if (istype(L))
L.toggle_admin_freeze(admin)
if ("sleep")
var/mob/living/L = targetMob
if (istype(L))
L.toggle_admin_sleep(admin)
if ("lobby")
if(!isobserver(targetMob))
to_chat(usr, "<span class='notice'>You can only send ghost players back to the Lobby.</span>")
return
if(!targetMob.client)
to_chat(usr, "<span class='warning'>[targetMob] doesn't seem to have an active client.</span>")
return
log_admin("[key_name(usr)] has sent [key_name(targetMob)] back to the Lobby.")
message_admins("[key_name(usr)] has sent [key_name(targetMob)] back to the Lobby.")
var/mob/dead/new_player/NP = new()
NP.ckey = targetMob.ckey
qdel(targetMob)
if(GLOB.preferences_datums[NP.ckey])
var/datum/preferences/P = GLOB.preferences_datums[NP.ckey]
P.respawn_restrictions_active = FALSE
if ("select_equipment")
admin.cmd_select_equipment(targetMob)
if ("strip")
for(var/obj/item/I in targetMob)
targetMob.dropItemToGround(I, TRUE) //The TRUE forces all items to drop, since this is an admin undress.
if ("cryo")
cryoMob(targetMob, effects = TRUE)
if ("force_say")
targetMob.say(params["to_say"], forced="admin")
if ("force_emote")
targetMob.emote("me", EMOTE_VISIBLE, params["to_emote"])
if ("prison")
if(isAI(targetMob))
to_chat(usr, "This cannot be used on instances of type /mob/living/silicon/ai.")
return
targetMob.forceMove(pick(GLOB.prisonwarp))
to_chat(targetMob, "<span class='userdanger'>You have been sent to Prison!</span>")
log_admin("[key_name(admin)] has sent [key_name(targetMob)] to Prison!")
message_admins("[key_name_admin(admin)] has sent [key_name_admin(targetMob)] to Prison!")
if ("kick")
admin.holder.kick(targetMob)
if ("ban")
admin.holder.newBan(targetMob)
if ("sticky_ban")
var/list/ban_settings = list()
if(targetMob.client)
ban_settings["ckey"] = targetMob.ckey
admin.holder.stickyban("add", ban_settings)
if ("notes")
if (targetMob.client)
browse_messages(target_ckey = targetMob.ckey)
if ("logs")
var/source = LOGSRC_MOB
if (targetMob.client)
source = LOGSRC_CLIENT
show_individual_logging_panel(targetMob, source)
if ("job_ban")
if(targetMob.client)
process_banlist(params["selected_role"], params["is_category"], params["want_to_ban"])
if ("mute")
if(!targetMob.client)
return
targetMob.client.prefs.muted = text2num(params["mute_flag"])
log_admin("[key_name(admin)] set the mute flags for [key_name(targetMob)] to [targetMob.client.prefs.muted].")
if ("mute_all")
if(!targetMob.client)
return
for(var/bit in GLOB.mute_bits)
targetMob.client.prefs.muted |= bit["bitflag"]
log_admin("[key_name(admin)] mass-muted [key_name(targetMob)].")
if ("unmute_all")
if(!targetMob.client)
return
for(var/bit in GLOB.mute_bits)
targetMob.client.prefs.muted &= ~bit["bitflag"]
log_admin("[key_name(admin)] mass-unmuted [key_name(targetMob)].")
if ("related_accounts")
if(targetMob.client)
var/related_accounts
if (params["related_thing"] == "CID")
related_accounts = targetMob.client.related_accounts_cid
else
related_accounts = targetMob.client.related_accounts_ip
related_accounts = splittext(related_accounts, ", ")
var/list/dat = list("Related accounts by [params["related_thing"]]:")
dat += related_accounts
usr << browse(dat.Join("<br>"), "window=related_[targetMob.client];size=420x300")
if ("transform")
var/choice = params["newType"]
if (choice == "/mob/living")
choice = tgui_input_list(usr, "What should this mob transform into", "Mob Transform", subtypesof(choice))
if (!choice)
return
admin.holder.transformMob(targetMob, admin.mob, choice, params["newTypeName"])
if ("toggle_godmode")
admin.cmd_admin_godmode(targetMob)
if ("spell")
admin.toggle_spell(targetMob)
if ("martial_art")
admin.teach_martial_art(targetMob)
if ("quirk")
admin.toggle_quirk(targetMob)
if ("species")
admin.set_species(targetMob)
if ("limb")
if(!params["limbs"] || !ishuman(targetMob))
return
var/mob/living/carbon/human/H = targetMob
for(var/limb in params["limbs"])
if (!limb)
continue
if (params["delimb_mode"])
var/obj/item/bodypart/L = H.get_bodypart(limb)
if (!L)
continue
L.dismember(harmless = TRUE)
playsound(H, 'modular_splurt/sound/effects/cartoon_pop.ogg', 70)
else
H.regenerate_limb(limb)
if ("scale")
var/mob/living/L = targetMob
if(!isnull(params["new_scale"]) && istype(L))
L.vv_edit_var("resize", params["new_scale"])
mobSize = params["new_scale"]
if ("explode")
var/power = text2num(params["power"])
var/empMode = text2num(params["emp_mode"])
var/turf/T = get_turf(usr)
message_admins("[ADMIN_LOOKUPFLW(usr)] created an admin [empMode ? "EMP" : "explosion"] at [ADMIN_VERBOSEJMP(T)].")
log_admin("[key_name(usr)] created an admin [empMode ? "EMP" : "explosion"] at [usr.loc].")
if (empMode)
empulse_using_range(usr, power, TRUE)
else
explosion(usr, power / 3, power / 2, power, power, ignorecap = TRUE)
if ("narrate")
var/list/stylesRaw = params["classes"]
var/styles = ""
for(var/style in stylesRaw)
styles += "[style]:[stylesRaw[style]];"
if (params["mode_global"])
to_chat(world, "<span style='[styles]'>[params["message"]]</span>")
log_admin("GlobalNarrate: [key_name(usr)] : [params["message"]]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] Sent a global narrate</span>")
else
for(var/mob/M in view(params["range"], usr))
to_chat(M, "<span style='[styles]'>[params["message"]]</span>")
log_admin("LocalNarrate: [key_name(usr)] at [AREACOORD(usr)]: [params["message"]]")
message_admins("<span class='adminnotice'><b> LocalNarrate: [key_name_admin(usr)] at [ADMIN_VERBOSEJMP(usr)]:</b> [params["message"]]<BR></span>")
if ("languages")
var/datum/language_holder/H = targetMob.get_language_holder()
H.open_language_menu(usr)
if ("ambitions")
var/datum/mind/requesting_mind = targetMob.mind
if(!istype(requesting_mind) || QDELETED(requesting_mind))
to_chat(usr, "<span class='warning'>This mind reference is no longer valid. It has probably since been destroyed.</span>")
return
requesting_mind.do_edit_objectives_ambitions()
if ("traitor_panel")
admin.holder.show_traitor_panel(targetMob)
// process_banlist: Gets all jobs in a job category
// Input:
// query (string): The name of the role / department you want to jobban.
// is_category (boolean): Is the query a department / role category? e.g. query "Engineering" needs TRUE
// want_to_ban (boolean): Should we ban or should we unban the job we just supplied.
//
// Output:A list of strings with the names of each role the INPUT covers.
/datum/player_panel/proc/process_banlist(query, is_category, want_to_ban)
if(!SSjob)
to_chat(usr, "Jobs subsystem not initialized yet!")
return
var/mob/M = targetClient.mob
var/list/jobs_to_set = list() // All the roles relating to the clicked button
if (is_category)
for(var/list/role_category in roleStatus) // For every department / antag category
if (role_category["category_name"] == query) // If this is the selected category
for(var/list/role in role_category["category_roles"])
jobs_to_set += role["name"]
break
else
jobs_to_set += query
var/list/jobs_to_set_trimmed = list() // The roles from jobs_to_set that aren't already banned / unbanned
for(var/role in jobs_to_set)
// If we are in ban mode and this role is unbanned OR if we are in unban mode and this role is banned
// (We don't want to ban / unban roles that are already banned / unbanned)
if ((want_to_ban && !jobban_isbanned(M, role)) || (!want_to_ban && jobban_isbanned(M, role)))
jobs_to_set_trimmed += role
for(var/role in jobs_to_set_trimmed)
if (jobs_to_set_trimmed.len) // At least one role to get banned / unbanned
if (want_to_ban)
usr.client.holder.Jobban(targetClient.mob, jobs_to_set_trimmed)
else
usr.client.holder.UnJobban(targetClient.mob, jobs_to_set_trimmed)
updateJobbanStatus() // Update TGUI data to reflect new ban statuses
// Updates the jobban status of this client's jobban panel.
/datum/player_panel/proc/updateJobbanStatus()
var/list/roles = list()
var/active_role_bans = 0
for(var/list/role_category in GLOB.jobban_panel_data) // For every department / antag category
var/list/category_roles = list()
category_roles["category_name"] = role_category["name"]
category_roles["category_color"] = role_category["color"]
category_roles["category_roles"] = list()
for(var/role in role_category["roles"]) // For every job / antag
var/list/roles_instance = list()
roles_instance["name"] = role
var/reason = jobban_isbanned(targetMob, role)
if(reason)
roles_instance["ban_reason"] = reason
active_role_bans++
category_roles["category_roles"] += list(roles_instance)
roles += list(category_roles)
roleStatus = roles
antagBanReason = jobban_isbanned(targetMob, ROLE_SYNDICATE)
activeRoleBans = active_role_bans
+6 -10
View File
@@ -933,13 +933,15 @@
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=bloodsucker;jobban4=[REF(M)]'><font color=red>Bloodsucker</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=bloodsucker;jobban4=[REF(M)]'>Bloodsucker</a></td>"
dat += "</tr><tr align='center'>" //So things dont get squished.
//Slave Trader
if(jobban_isbanned(M, ROLE_SLAVER) || isbanned_dept)
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=slaver;jobban4=[REF(M)]'><font color=red>Slaver</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=slaver;jobban4=[REF(M)]'>Slaver</a></td>"
//Other Roles (black)
dat += "<table cellpadding='1' cellspacing='0' width='100%'>"
dat += "<tr bgcolor='000000'><th colspan='5'><a href='?src=[REF(src)];[HrefToken()];jobban3=otherroles;jobban4=[REF(M)]' style='color: white;'>Other Roles</a></th></tr><tr align='center'>"
@@ -2025,21 +2027,15 @@
return
var/mob/M = locate(href_list["CentComReply"])
usr.client.admin_headset_message(M, RADIO_CHANNEL_CENTCOM)
usr.client.cmd_admin_subtle_headset_message(M, RADIO_CHANNEL_CENTCOM)
else if(href_list["SyndicateReply"])
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["SyndicateReply"])
usr.client.admin_headset_message(M, RADIO_CHANNEL_SYNDICATE)
usr.client.cmd_admin_subtle_headset_message(M, RADIO_CHANNEL_SYNDICATE)
else if(href_list["HeadsetMessage"])
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["HeadsetMessage"])
usr.client.admin_headset_message(M)
//ambition start
else if(href_list["ObjectiveRequest"])
if(!check_rights(R_ADMIN))
@@ -2100,7 +2096,7 @@
return
var/mob/M = locate(href_list["subtlemessage"])
usr.client.cmd_admin_subtle_message(M)
usr.client.cmd_admin_subtle_headset_message(M)
else if(href_list["individuallog"])
if(!check_rights(R_ADMIN))
+5 -59
View File
@@ -19,67 +19,12 @@
admin_ticket_log(M, msg)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
// Unless I am dent-skulled, there is no way to do (mob/M in GLOB.mob_list, someothervar) with context-menu buttons, hence the instant proc call.
/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list)
set category = "Admin.Events"
set name = "Subtle Message"
if(!ismob(M))
return
if(!check_rights(R_ADMIN))
return
message_admins("[key_name_admin(src)] has started answering [ADMIN_LOOKUPFLW(M)]'s prayer.")
var/msg = input("Message:", text("Subtle PM to [M.key]")) as text|null
if (!msg)
message_admins("[key_name_admin(src)] decided not to answer [ADMIN_LOOKUPFLW(M)]'s prayer")
return
if(usr)
if (usr.client)
if(usr.client.holder)
to_chat(M, "<i>You hear a voice in your head... <b>[msg]</i></b>")
log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
msg = "<span class='adminnotice'><b> SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] :</b> [msg]</span>"
message_admins(msg)
admin_ticket_log(M, msg)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_headset_message(mob/M in GLOB.mob_list)
set category = "Admin.Events"
set name = "Headset Message"
admin_headset_message(M)
/client/proc/admin_headset_message(mob/M in GLOB.mob_list, sender = null)
var/mob/living/carbon/human/H = M
if(!check_rights(R_ADMIN))
return
if(!istype(H))
to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human")
return
if(!istype(H.ears, /obj/item/radio/headset))
to_chat(usr, "The person you are trying to contact is not wearing a headset.")
return
if (!sender)
sender = input("Who is the message from?", "Sender") as null|anything in list(RADIO_CHANNEL_CENTCOM,RADIO_CHANNEL_SYNDICATE)
if(!sender)
return
message_admins("[key_name_admin(src)] has started answering [key_name_admin(H)]'s [sender] request.")
var/input = input("Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from [sender]", "") as text|null
if(!input)
message_admins("[key_name_admin(src)] decided not to answer [key_name_admin(H)]'s [sender] request.")
return
log_directed_talk(mob, H, input, LOG_ADMIN, "reply")
message_admins("[key_name_admin(src)] replied to [key_name_admin(H)]'s [sender] message with: \"[input]\"")
to_chat(H, "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from [sender == "Syndicate" ? "your benefactor" : "Central Command"]. Message as follows[sender == "Syndicate" ? ", agent." : ":"] <span class='bold'>[input].</span> Message ends.\"")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Headset Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
cmd_admin_subtle_headset_message(M)
/client/proc/cmd_admin_mod_antag_rep(client/C in GLOB.clients, var/operation)
set category = "Special Verbs"
@@ -1336,7 +1281,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!check_rights(R_ADMIN) || !check_rights(R_FUN))
return
var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE,
var/list/punishment_list = list(
ADMIN_PUNISHMENT_PIE,
ADMIN_PUNISHMENT_CUSTOM_PIE,
ADMIN_PUNISHMENT_FIREBALL,
ADMIN_PUNISHMENT_LIGHTNING,
@@ -1362,7 +1308,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
ADMIN_PUNISHMENT_BOOKIFY,
ADMIN_PUNISHMENT_BONK)
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
var/punishment = tgui_input_list(usr, "Choose a punishment", "Divine Smiting", punishment_list)
if(QDELETED(target) || !punishment)
return
+5 -1
View File
@@ -97,6 +97,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/preferred_map = null
var/preferred_chaos = null
var/be_victim = null
var/use_new_playerpanel = FALSE
var/disable_combat_cursor = FALSE
var/pda_style = MONO
var/pda_color = "#808000"
@@ -1037,7 +1038,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<b>Adminhelp Sounds:</b> <a href='?_src_=prefs;preference=hear_adminhelps'>[(toggles & SOUND_ADMINHELP)?"Enabled":"Disabled"]</a><br>"
dat += "<b>Announce Login:</b> <a href='?_src_=prefs;preference=announce_login'>[(toggles & ANNOUNCE_LOGIN)?"Enabled":"Disabled"]</a><br>"
dat += "<br>"
dat += "<b>Combo HUD Lighting:</b> <a href = '?_src_=prefs;preference=combohud_lighting'>[(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]</a><br>" // sandstorm end - moves admins prefs to the right
dat += "<b>Combo HUD Lighting:</b> <a href='?_src_=prefs;preference=combohud_lighting'>[(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]</a><br>"
dat += "<b>Use Modern Player Panel:</b> <a href='?_src_=prefs;preference=use_new_playerpanel'>[use_new_playerpanel ? "Yes" : "No"]</a><br>" // sandstorm end - moves admins prefs to the right
dat += "<h2>Citadel Preferences</h2>" //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe.
dat += "<b>Widescreen:</b> <a href='?_src_=prefs;preference=widescreenpref'>[widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]</a><br>"
@@ -3181,6 +3183,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
toggles ^= ANNOUNCE_LOGIN
if("combohud_lighting")
toggles ^= COMBOHUD_LIGHTING
if("use_new_playerpanel")
use_new_playerpanel = !use_new_playerpanel
if("be_special")
var/be_special_type = href_list["be_special_type"]
+5 -3
View File
@@ -445,10 +445,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["no_tetris_storage"] >> no_tetris_storage
// Splurt
S["be_victim"] >> be_victim
S["disable_combat_cursor"] >> disable_combat_cursor
S["be_victim"] >> be_victim
S["disable_combat_cursor"] >> disable_combat_cursor
S["use_new_playerpanel"] >> use_new_playerpanel
//favorite outfits
S["favorite_outfits"] >> favorite_outfits
S["favorite_outfits"] >> favorite_outfits
var/list/parsed_favs = list()
for(var/typetext in favorite_outfits)
@@ -633,6 +634,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
// Splurt
WRITE_FILE(S["be_victim"], be_victim)
WRITE_FILE(S["disable_combat_cursor"], disable_combat_cursor)
WRITE_FILE(S["use_new_playerpanel"], use_new_playerpanel)
var/mob/living/carbon/human/H = parent.mob
if(istype(H))
+1 -17
View File
@@ -1037,23 +1037,7 @@
if(href_list[VV_HK_MARTIAL_ART])
if(!check_rights(NONE))
return
var/list/artpaths = subtypesof(/datum/martial_art)
var/list/artnames = list()
for(var/i in artpaths)
var/datum/martial_art/M = i
artnames[initial(M.name)] = M
var/result = input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in artnames
if(!usr)
return
if(QDELETED(src))
to_chat(usr, "Mob doesn't exist anymore")
return
if(result)
var/chosenart = artnames[result]
var/datum/martial_art/MA = new chosenart
MA.teach(src)
log_admin("[key_name(usr)] has taught [MA] to [key_name(src)].")
message_admins("<span class='notice'>[key_name_admin(usr)] has taught [MA] to [key_name_admin(src)].</span>")
usr.client.teach_martial_art(src)
if(href_list[VV_HK_GIVE_TRAUMA])
if(!check_rights(NONE))
return
+1 -20
View File
@@ -721,26 +721,7 @@
return
copy_outfit()
if(href_list[VV_HK_MOD_QUIRKS])
if(!check_rights(R_SPAWN))
return
var/list/options = list("Clear"="Clear")
for(var/x in subtypesof(/datum/quirk))
var/datum/quirk/T = x
var/qname = initial(T.name)
options[has_quirk(T) ? "[qname] (Remove)" : "[qname] (Add)"] = T
var/result = input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options
if(result)
if(result == "Clear")
for(var/datum/quirk/q in roundstart_quirks)
remove_quirk(q.type)
else
var/T = options[result]
if(has_quirk(T))
remove_quirk(T)
else
add_quirk(T,TRUE)
usr.client.toggle_quirk(src)
if(href_list[VV_HK_MAKE_MONKEY])
if(!check_rights(R_SPAWN))
return
+5
View File
@@ -0,0 +1,5 @@
author: Crowbar764
delete-after: true
changes:
- rscadd: Shiny new admin panel
- tweak: Switches some admin panels to TGUI
+4
View File
@@ -0,0 +1,4 @@
author: Crowbar764
delete-after: true
changes:
- tweak: Slaver improvements
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -1,4 +1,5 @@
#define ANNOUNCEMENT_COOLDOWN 6 MINUTES
#define SLAVER_RANSOM_SCALE_VALUE 1000000
/obj/machinery/computer/slavery
name = "\improper slave management console"
@@ -49,6 +50,7 @@
var/turf/curr = get_turf(src)
data["currentCoords"] = "[curr.x], [curr.y], [curr.z]"
data["value_table"] = GLOB.slavers_ransom_values
data["ransom_scale_value"] = SLAVER_RANSOM_SCALE_VALUE
data["categories"] = list()
for(var/category in possible_gear)
var/list/cat = list(
@@ -0,0 +1,20 @@
GLOBAL_VAR_INIT(cryo_next_admin_warning, 0) // The last time we told admins about a mapping / coding error because no cryo computer was found
/proc/cryo_find_control_computer(obj/machinery/cryopod/pod = null, urgent = FALSE)
for(var/cryo_console as anything in GLOB.cryopod_computers)
var/obj/machinery/computer/cryopod/console = cryo_console
if(!pod) // No cryopod passed in, we will try to find the standard crew cryo computer instead.
var/turf/console_turf = get_turf(console)
if((console_turf.z == 2) && (!istype(get_area(console), /area/security/prison))) // If station Z-level and NOT the prison cryo computer. Should get the standard crew cryo computer.
return WEAKREF(console)
else
if(get_area(console) == get_area(pod))
return WEAKREF(console)
// Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged
if(urgent && (world.time > GLOB.cryo_next_admin_warning))
log_admin("\The [pod] in [get_area(pod)] could not find control computer!")
message_admins("\The [pod] in [get_area(pod)] could not find control computer!")
GLOB.cryo_next_admin_warning = world.time + 5 MINUTES
@@ -43,8 +43,11 @@
var/automatic_ransom_value = GLOB.slavers_ransom_values[M.job]
if (automatic_ransom_value)
station_rank = M.job
setPrice(automatic_ransom_value)
var/datum/bank_account/bank = SSeconomy.get_dep_account(ACCOUNT_CAR)
automatic_ransom_value += automatic_ransom_value * (bank.account_balance / SLAVER_RANSOM_SCALE_VALUE) // Slave price scales with station credit balance (+100% per 1,000,000 credits in the cargo budget)
setPrice(automatic_ransom_value)
/obj/item/electropack/shockcollar/slave/proc/setPrice(newPrice)
var/mob/living/M = loc
@@ -0,0 +1,5 @@
/obj/item/radio/headset/syndicate/slaver/Initialize()
. = ..()
set_frequency(FREQ_SYNDICATE)
freqlock = TRUE
@@ -10,7 +10,7 @@
new /obj/item/clothing/under/syndicate(src)
new /obj/item/clothing/shoes/workboots(src)
new /obj/item/storage/belt/military(src)
new /obj/item/radio/headset/syndicate(src)
new /obj/item/radio/headset/syndicate/slaver(src)
new /obj/item/crowbar/red(src)
new /obj/item/restraints/handcuffs(src)
new /obj/item/restraints/handcuffs(src)
@@ -31,7 +31,7 @@
new /obj/item/clothing/under/syndicate(src)
new /obj/item/clothing/shoes/workboots(src)
new /obj/item/storage/belt/military(src)
new /obj/item/radio/headset/syndicate(src)
new /obj/item/radio/headset/syndicate/slaver(src)
new /obj/item/crowbar/red(src)
new /obj/item/restraints/handcuffs(src)
new /obj/item/restraints/handcuffs(src)
+179
View File
@@ -0,0 +1,179 @@
// Stuff that helps the TGUI player panel jobban section to work
GLOBAL_LIST_INIT(jobban_panel_data, list(
list(
"name" = "Command",
"color" = "yellow",
"roles" = GLOB.command_positions
),
list(
"name" = "Security",
"color" = "red",
"roles" = GLOB.security_positions
),
list(
"name" = "Engineering",
"color" = "orange",
"roles" = GLOB.engineering_positions
),
list(
"name" = "Medical",
"color" = "blue",
"roles" = GLOB.medical_positions
),
list(
"name" = "Science",
"color" = "violet",
"roles" = GLOB.science_positions
),
list(
"name" = "Supply",
"color" = "brown",
"roles" = GLOB.supply_positions
),
list(
"name" = "Service",
"color" = "green",
"roles" = GLOB.civilian_positions
),
list(
"name" = "Silicon",
"color" = "purple",
"roles" = GLOB.nonhuman_positions
),
list(
"name" = "Ghost Roles",
"color" = "teal",
"roles" = list(
ROLE_PAI,
ROLE_POSIBRAIN,
ROLE_DRONE,
ROLE_DEATHSQUAD,
ROLE_LAVALAND,
ROLE_GHOSTCAFE,
ROLE_SENTIENCE,
ROLE_MIND_TRANSFER
)
),
list(
"name" = "Antagonists",
"color" = "red",
"roles" = list(
ROLE_TRAITOR,
ROLE_CHANGELING,
ROLE_HERETIC,
ROLE_OPERATIVE,
ROLE_REV,
ROLE_CULTIST,
ROLE_SERVANT_OF_RATVAR,
ROLE_WIZARD,
ROLE_ABDUCTOR,
ROLE_ALIEN,
ROLE_FAMILIES,
ROLE_BLOODSUCKER,
ROLE_SLAVER
)
),
list(
"name" = "Other",
"color" = "red",
"roles" = list(
"pacifist",
"appearance",
"emote",
"OOC",
ROLE_RESPAWN
)
)
))
// notbannedlist is just a list of strings of the job titles you want to ban.
/datum/admins/proc/Jobban(mob/M, list/notbannedlist)
if (!check_rights(R_BAN))
to_chat(usr, "Error: You do not have sufficient admin rights to ban players.")
return
var/severity = null
var/reason = null
switch(tgui_alert(usr, "Job ban type", buttons = list("Temporary", "Permanent", "Cancel")))
if("Temporary")
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(mins <= 0)
to_chat(usr, "<span class='danger'>[mins] is not a valid duration.</span>")
return
reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
if(!reason)
return
severity = tgui_alert(usr, "Set the severity of the note/ban", buttons = list("High", "Medium", "Minor", "None"))
if(!severity)
return
var/msg
for(var/job in notbannedlist)
if(!DB_ban_record(BANTYPE_JOB_TEMP, M, mins, reason, job))
to_chat(usr, "<span class='danger'>Failed to apply ban.</span>")
return
if(M.client)
jobban_buildcache(M.client)
ban_unban_log_save("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes. reason: [reason]")
log_admin_private("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes.")
if(!msg)
msg = job
else
msg += ", [job]"
create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0, null, 0, severity)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes.</span>")
to_chat(M, "<span class='boldannounce'><BIG>You have been [((msg == "ooc") || (msg == "appearance") || (msg == "pacifist")) ? "banned" : "jobbanned"] by [usr.client.key] from: [msg == "pacifist" ? "using violence" : msg].</BIG></span>")
to_chat(M, "<span class='boldannounce'>The reason is: [reason]</span>")
to_chat(M, "<span class='danger'>This jobban will be lifted in [mins] minutes.</span>")
if("Permanent")
reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
if (!reason)
return
severity = tgui_alert(usr, "Please State Reason For Banning", buttons = list("High", "Medium", "Minor", "None"))
if (!severity)
return
var/msg
for(var/job in notbannedlist)
if(!DB_ban_record(BANTYPE_JOB_PERMA, M, -1, reason, job))
to_chat(usr, "<span class='danger'>Failed to apply ban.</span>")
return
if(M.client)
jobban_buildcache(M.client)
ban_unban_log_save("[key_name(usr)] perma-jobbanned [key_name(M)] from [job]. reason: [reason]")
log_admin_private("[key_name(usr)] perma-banned [key_name(M)] from [job]")
if(!msg)
msg = job
else
msg += ", [job]"
create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0, null, 0, severity)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg].</span>")
to_chat(M, "<span class='boldannounce'><BIG>You have been [((msg == "ooc") || (msg == "appearance") || (msg == "pacifist")) ? "banned" : "jobbanned"] by [usr.client.key] from: [msg == "pacifist" ? "using violence" : msg].</BIG></span>")
to_chat(M, "<span class='boldannounce'>The reason is: [reason]</span>")
to_chat(M, "<span class='danger'>This jobban can be lifted only upon request.</span>")
// notbannedlist is just a list of strings of the job titles you want to unban.
/datum/admins/proc/UnJobban(mob/M, list/bannedlist)
if (!check_rights(R_BAN))
to_chat(usr, "Error: You do not have sufficient admin rights to unban players.")
return
var/msg
for(var/job in bannedlist)
var/reason = jobban_isbanned(M, job)
if (tgui_alert(usr, "Job: '[job]' Ban reason: '[reason]'", "Un-Jobban This Player?", list("Yes", "No")) == "Yes")
ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]")
log_admin_private("[key_name(usr)] unbanned [key_name(M)] from [job]")
DB_ban_unban(M.ckey, BANTYPE_ANY_JOB, job)
if(M.client)
jobban_buildcache(M.client)
if(!msg)
msg = job
else
msg += ", [job]"
if(msg)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg].</span>")
to_chat(M, "<span class='boldannounce'><BIG>You have been un-jobbanned by [usr.client.key] from [msg].</BIG></span>")
+13
View File
@@ -0,0 +1,13 @@
/datum/admins/proc/kick(mob/M)
if (!ismob(M) || !M.client)
to_chat(usr, "<span class='danger'>Error: [M] has no client!</span>")
return
if(!check_if_greater_rights_than(M.client))
to_chat(usr, "<span class='danger'>Error: They have more rights than you do.</span>")
return
to_chat(M, "<span class='danger'>You have been kicked from the server by [usr.client.holder.fakekey ? "an Administrator" : "[usr.client.key]"].</span>")
log_admin("[key_name(usr)] kicked [key_name(M)].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] kicked [key_name_admin(M)].</span>")
qdel(M.client)
@@ -0,0 +1,70 @@
/datum/admins/proc/newBan(mob/M)
if(!check_rights(R_BAN))
return
// var/mob/M = mob_to_ban
if(!ismob(M) || !M.client)
to_chat(usr, "<span class='danger'>Error: [M] has no client!</span>")
return
if(M.client && M.client.holder)
to_chat(usr, "<span class='danger'>Error: You cannot ban admins!</span>")
return //admins cannot be banned. Even if they could, the ban doesn't affect them anyway
switch(tgui_alert(usr, "Ban type", buttons = list("Temporary", "Permanent", "Cancel")))
if("Temporary")
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(mins <= 0)
to_chat(usr, "<span class='danger'>[mins] is not a valid duration.</span>")
return
var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
if(!reason)
return
if(!DB_ban_record(BANTYPE_TEMP, M, mins, reason))
to_chat(usr, "<span class='danger'>Failed to apply ban.</span>")
return
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
ban_unban_log_save("[key_name(usr)] has banned [key_name(M)]. - Reason: [reason] - This will be removed in [mins] minutes.")
to_chat(M, "<span class='boldannounce'><BIG>You have been banned by [usr.client.key].\nReason: [reason]</BIG></span>")
to_chat(M, "<span class='danger'>This is a temporary ban, it will be removed in [mins] minutes. The round ID is [GLOB.round_id].</span>")
var/bran = CONFIG_GET(string/banappeals)
if(bran)
to_chat(M, "<span class='danger'>To try to resolve this matter head to [bran]</span>")
else
to_chat(M, "<span class='danger'>No ban appeals URL has been set.</span>")
log_admin_private("[key_name(usr)] has banned [key_name(M)].\nReason: [key_name(M)]\nThis will be removed in [mins] minutes.")
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has banned [key_name_admin(M)].\nReason: [reason]\nThis will be removed in [mins] minutes.</span>"
message_admins(msg)
var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
if(AH)
AH.Resolve()
qdel(M.client)
if("Permanent")
var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
if(!reason)
return
switch(alert(usr,"IP ban?",,"Yes","No","Cancel"))
if("Cancel")
return
if("Yes")
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP)
if("No")
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0)
to_chat(M, "<span class='boldannounce'><BIG>You have been banned by [usr.client.key].\nReason: [reason]</BIG></span>")
to_chat(M, "<span class='danger'>This is a permanent ban. The round ID is [GLOB.round_id].</span>")
var/bran = CONFIG_GET(string/banappeals)
if(bran)
to_chat(M, "<span class='danger'>To try to resolve this matter head to [bran]</span>")
else
to_chat(M, "<span class='danger'>No ban appeals URL has been set.</span>")
if(!DB_ban_record(BANTYPE_PERMA, M, -1, reason))
to_chat(usr, "<span class='danger'>Failed to apply ban.</span>")
return
ban_unban_log_save("[key_name(usr)] has permabanned [key_name(M)]. - Reason: [reason] - This is a permanent ban.")
log_admin_private("[key_name(usr)] has banned [key_name(M)].\nReason: [reason]\nThis is a permanent ban.")
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has banned [key_name_admin(M)].\nReason: [reason]\nThis is a permanent ban.</span>"
message_admins(msg)
var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
if(AH)
AH.Resolve()
qdel(M.client)
@@ -0,0 +1,127 @@
// Stuff that helps the TGUI player panel transform section to work
GLOBAL_LIST_INIT(pp_transformables, list(
list(
name = "Common",
color = "",
types = list(
list(
name = "Human",
key = /mob/living/carbon/human
),
list(
name = "Monkey",
key = /mob/living/carbon/monkey
),
list(
name = "Cyborg",
key = /mob/living/silicon/robot
)
)
),
list(
name = "Xenomorph",
color = "purple",
types = list(
list(
name = "Larva",
key = /mob/living/carbon/alien/larva
),
list(
name = "Drone",
key = /mob/living/carbon/alien/humanoid/drone
),
list(
name = "Hunter",
key = /mob/living/carbon/alien/humanoid/hunter
),
list(
name = "Sentinel",
key = /mob/living/carbon/alien/humanoid/sentinel
),
list(
name = "Praetorian",
key = /mob/living/carbon/alien/humanoid/royal/praetorian
),
list(
name = "Queen",
key = /mob/living/carbon/alien/humanoid/royal/queen
)
)
),
list(
name = "Lavaland",
color = "orange",
types = list(
list(
name = "Goliath",
key = /mob/living/simple_animal/hostile/asteroid/goliath/beast
),
list(
name = "Legion",
key = /mob/living/simple_animal/hostile/asteroid/hivelord/legion
),
list(
name = "Blood-Drunk Miner",
key = /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner
),
list(
name = "Gladiator",
key = /mob/living/simple_animal/hostile/megafauna/gladiator
),
list(
name = "Dragon",
key = /mob/living/simple_animal/hostile/megafauna/dragon
),
list(
name = "Legion Hivelord",
key = /mob/living/simple_animal/hostile/asteroid/elite/legionnaire
)
)
),
list(
name = "Cultist",
color = "violet",
types = list(
list(
name = "Shade",
key = /mob/living/simple_animal/hostile/construct/shade
),
list(
name = "Artificer",
key = /mob/living/simple_animal/hostile/construct/builder
),
list(
name = "Wraith",
key = /mob/living/simple_animal/hostile/construct/wraith
),
list(
name = "Juggernaut",
key = /mob/living/simple_animal/hostile/construct/armored
)
)
)
))
// M: Mob to change
// newType: Path of new type e.g: /mob/living/carbon/alien/humanoid/drone
// newTypeName (optional): Name of the new type (used in logging): e.g: "Drone"
/datum/admins/proc/transformMob(mob/M, mob/adminMob, newType, newTypeName)
if(!check_rights(R_SPAWN))
return
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob.")
return
if (!newTypeName)
newTypeName = newType
log_admin("[key_name(usr)] transformed [key_name(M)] into a [newTypeName].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] transformed [key_name_admin(M)] into a [newTypeName].</span>")
var/mob/newMob = M.change_mob_type(newType, delete_old_mob = TRUE)
if (M == adminMob)
adminMob = newMob
addtimer(CALLBACK(newMob.mob_panel, /datum.proc/ui_interact, adminMob), 0.1 SECONDS)
@@ -6,3 +6,43 @@
var/obj/item/reagent_containers/food/snacks/store/book/funnyBook = new(get_turf(target))
target.forceMove(funnyBook)
funnyBook.name = "Book of " + target.name
/client/proc/cmd_admin_subtle_headset_message(mob/M, sender = null)
if(!ismob(M))
return
if(!check_rights(R_ADMIN))
return
if (!sender)
var/list/subtle_message_options = list("Voice in head", RADIO_CHANNEL_CENTCOM, RADIO_CHANNEL_SYNDICATE)
sender = tgui_input_list(usr, "Choose the method of subtle messaging", "Subtle Message", subtle_message_options)
if (!sender)
return
message_admins("[key_name_admin(src)] has started answering [ADMIN_LOOKUPFLW(M)]'s prayer / faction PM.")
var/msg = input("Contents of the message", text("Subtle PM to [M.key]")) as text
if (!msg)
message_admins("[key_name_admin(src)] decided not to answer [ADMIN_LOOKUPFLW(M)]'s prayer / faction PM.")
return
if (sender == "Voice in head")
to_chat(M, "<i>You hear a voice in your head... <b>[msg]</i></b>")
else
var/mob/living/carbon/human/H = M
if(!istype(H))
to_chat(usr, "The person you are trying to contact is not human. Unsent message: [msg]")
return
if(!istype(H.ears, /obj/item/radio/headset))
to_chat(usr, "The person you are trying to contact is not wearing a headset. Unsent message: [msg]")
return
to_chat(H, "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from [sender == RADIO_CHANNEL_SYNDICATE ? "your benefactor" : "Central Command"]. Message as follows[sender == RADIO_CHANNEL_SYNDICATE ? ", agent." : ":"] <span class='bold'>[msg].</span> Message ends.\"")
log_admin("SubtlePM ([sender]): [key_name(usr)] -> [key_name(M)] : [msg]")
msg = "<span class='adminnotice'><b> SubtleMessage ([sender]): [key_name_admin(usr)] -> [key_name_admin(M)] :</b> [msg]</span>"
message_admins(msg)
admin_ticket_log(M, msg)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -59,6 +59,8 @@
else
R = new /mob/living/silicon/robot/modules/slaver(T)
R.radio = new /obj/item/radio/borg/syndicate(R)
var/brainopsname = C.prefs.real_name
R.mmi.name = "Man-Machine Interface: [brainopsname]"
@@ -73,3 +75,9 @@
new_borg.send_to_spawnpoint = FALSE
R.mind.add_antag_datum(new_borg,creator_slaver.slaver_team)
R.mind.special_role = "Slaver Cyborg"
R.grant_language(/datum/language/codespeak, TRUE, TRUE)
var/newName = sanitize_name(stripped_input(R, "Enter new robot name", "Cyborg Reclassification", "Cyborg", MAX_NAME_LEN))
if (newName)
R.custom_name = newName
R.updatename()
@@ -90,6 +90,13 @@ GLOBAL_LIST_INIT(slaver_gear, subtypesof(/datum/slaver_gear))
category = "Advanced"
cost = 10000
/datum/slaver_gear/jetpack
name = "Jetpack"
description = "Back-mounted jetpack for use in zero-gravity environments."
build_path = /obj/item/tank/jetpack/oxygen/harness
category = "Advanced"
cost = 3000
/datum/slaver_gear/riot
name = "Riot Kit"
description = "Toy L6 SAW with riot darts."
@@ -153,7 +160,7 @@ GLOBAL_LIST_INIT(slaver_gear, subtypesof(/datum/slaver_gear))
description = ".50 cal sniper rifle with sleep-inducing rounds."
build_path = /obj/item/storage/backpack/duffelbag/syndie/slaver_marksman
category = "Firearms"
cost = 40000
cost = 50000
/datum/slaver_gear/freedom
name = "Freedom Implant"
@@ -171,7 +178,7 @@ GLOBAL_LIST_INIT(slaver_gear, subtypesof(/datum/slaver_gear))
/datum/slaver_gear/implant_teleport
name = "Emergency Teleport Implants"
description = "Emergency teleport implant x 2."
description = "Emergency teleport implant x 2. Once activated, user needs to stand still for 5 seconds, after which they will be teleported from any location back to the slaver hideout. Has only one use."
build_path = /obj/item/storage/box/slaver_teleport
category = "Implants"
cost = 15000
@@ -5,7 +5,7 @@
shoes = /obj/item/clothing/shoes/workboots
gloves = /obj/item/clothing/gloves/color/black
back = /obj/item/storage/backpack
ears = /obj/item/radio/headset/syndicate
ears = /obj/item/radio/headset/syndicate/slaver
id = /obj/item/card/id/syndicate/slaver
backpack_contents = list(/obj/item/storage/box/survival,\
/obj/item/kitchen/knife/combat/survival)
@@ -17,9 +17,5 @@
gloves = /obj/item/clothing/gloves/krav_maga/combatglovesplus
/datum/outfit/slaver/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
var/obj/item/radio/R = H.ears
R.set_frequency(FREQ_SYNDICATE)
R.freqlock = TRUE
H.faction |= ROLE_SLAVER
H.update_icons()
@@ -2,3 +2,93 @@
. = ..()
if(ip_intel != initial(ip_intel) && ip_intel >= CONFIG_GET(number/ipintel_rating_bad))
uses_vpn = TRUE
/client/proc/toggle_quirk(mob/living/carbon/human/H)
if (!istype(H))
to_chat(usr, "This can only be used on /mob/living/carbon/human.")
return
var/list/options = list("Clear"="Clear")
for(var/x in subtypesof(/datum/quirk))
var/datum/quirk/T = x
var/qname = initial(T.name)
options[H.has_quirk(T) ? "[qname] (Remove)" : "[qname] (Add)"] = T
var/result = tgui_input_list(usr, "Choose quirk to add/remove", "Mob Quirks", options) // input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options
if(QDELETED(H))
to_chat(usr, "Mob doesn't exist anymore")
return
if(result)
if(result == "Clear")
for(var/datum/quirk/q in H.roundstart_quirks)
H.remove_quirk(q.type)
else
var/T = options[result]
if(H.has_quirk(T))
H.remove_quirk(T)
else
H.add_quirk(T,TRUE)
/client/proc/toggle_spell(mob/M)
var/list/options = list("Clear"="Clear")
for(var/x in GLOB.spells)
var/obj/effect/proc_holder/spell/spell = x
var/spell_name = initial(spell.name)
options[M.has_spell(spell) ? "[spell_name] (Remove)" : "[spell_name] (Add)"] = spell
var/spell_to_modify = tgui_input_list(usr, "Choose spell to add/remove", "Mob Spells", options) // input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options
if(QDELETED(M))
to_chat(usr, "Mob doesn't exist anymore")
return
if(spell_to_modify)
if(spell_to_modify == "Clear")
if (!M.mind)
return
for(var/obj/effect/proc_holder/spell/S in M.mind.spell_list)
M.mind.RemoveSpell(S.type)
else
var/T = options[spell_to_modify]
if(M.has_spell(T))
M.mind.RemoveSpell(T)
else
if (M.mind)
M.mind.AddSpell(new T)
else
M.AddSpell(new T)
message_admins("<span class='danger'>Spells given to mindless mobs will not be transferred in mindswap or cloning!</span>")
/client/proc/teach_martial_art(mob/living/carbon/C)
if (!istype(C))
to_chat(usr, "This can only be used on /mob/living/carbon.")
return
var/list/artpaths = subtypesof(/datum/martial_art)
var/list/artnames = list()
for(var/i in artpaths)
var/datum/martial_art/M = i
artnames[initial(M.name)] = M
var/result = tgui_input_list(usr, "Choose the martial art to teach", "JUDO CHOP", artnames) // input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in artnames
if(QDELETED(C))
to_chat(usr, "Mob doesn't exist anymore")
return
if(result)
var/chosenart = artnames[result]
var/datum/martial_art/MA = new chosenart
MA.teach(C)
log_admin("[key_name(usr)] has taught [MA] to [key_name(C)].")
message_admins("<span class='notice'>[key_name_admin(usr)] has taught [MA] to [key_name_admin(C)].</span>")
/client/proc/set_species(mob/living/carbon/human/H)
if (istype(H))
var/result = tgui_input_list(usr, "Choose a new species","Species", GLOB.species_list)
if(QDELETED(H))
to_chat(usr, "Mob doesn't exist anymore")
return
if(result)
admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [H] to [result]")
H.set_species(GLOB.species_list[result])
@@ -0,0 +1,27 @@
/// Toggle admin frozen
/mob/living/proc/toggle_admin_freeze(client/admin)
admin_frozen = !admin_frozen
if(admin_frozen)
SetStun(INFINITY, ignore_canstun = TRUE)
else
SetStun(0, ignore_canstun = TRUE)
if(client && admin)
to_chat(src, "<span class='userdanger'>An admin has [!admin_frozen ? "un" : ""]frozen you.</span>")
log_admin("[key_name(admin)] toggled admin-freeze on [key_name(src)].")
message_admins("[key_name_admin(admin)] toggled admin-freeze on [key_name_admin(src)].")
/// Toggle admin sleeping
/mob/living/proc/toggle_admin_sleep(client/admin)
admin_sleeping = !admin_sleeping
if(admin_sleeping)
SetSleeping(INFINITY, ignore_canstun = TRUE)
else
SetSleeping(0, ignore_canstun = TRUE)
if(client && admin)
to_chat(src, "<span class='userdanger'>An admin has [!admin_sleeping ? "un": ""]slept you.</span>")
log_admin("[key_name(admin)] toggled admin-sleep on [key_name(src)].")
message_admins("[key_name_admin(admin)] toggled admin-sleep on [key_name_admin(src)].")
@@ -0,0 +1,4 @@
/mob/living
// Admin CC
var/admin_frozen = FALSE
var/admin_sleeping = FALSE
+21
View File
@@ -1,3 +1,11 @@
/mob/Initialize()
. = ..()
create_player_panel()
/mob/Destroy()
QDEL_NULL(mob_panel)
. = ..()
/mob/verb/tilt_left()
set hidden = TRUE
if(!canface() || is_tilted < -45)
@@ -11,3 +19,16 @@
return FALSE
transform = transform.Turn(1)
is_tilted++
/mob/proc/has_spell(spelltype)
if (!mind)
return FALSE
for(var/obj/effect/proc_holder/spell/S in mind.spell_list)
if(S.type == spelltype)
return TRUE
return FALSE
/mob/proc/create_player_panel()
QDEL_NULL(mob_panel)
mob_panel = new(src)
@@ -1,2 +1,5 @@
/mob
var/is_tilted
// Admin player panel for this mob
var/datum/player_panel/mob_panel
+9
View File
@@ -1500,6 +1500,7 @@
#include "code\modules\admin\outfits.dm"
#include "code\modules\admin\permissionedit.dm"
#include "code\modules\admin\player_panel.dm"
#include "code\modules\admin\player_panel2.dm"
#include "code\modules\admin\playtimes.dm"
#include "code\modules\admin\sound_emitter.dm"
#include "code\modules\admin\sql_message_system.dm"
@@ -4240,6 +4241,7 @@
#include "modular_splurt\code\game\gamemodes\objectives.dm"
#include "modular_splurt\code\game\machinery\brigdoors.dm"
#include "modular_splurt\code\game\machinery\chem_alert.dm"
#include "modular_splurt\code\game\machinery\cryopod.dm"
#include "modular_splurt\code\game\machinery\research_table.dm"
#include "modular_splurt\code\game\machinery\computer\slavery.dm"
#include "modular_splurt\code\game\machinery\porta_turret\portable_turret.dm"
@@ -4256,6 +4258,7 @@
#include "modular_splurt\code\game\object\items\circuitboards\machine_circuitboards.dm"
#include "modular_splurt\code\game\object\items\circuitboards\miner_circuitboards.dm"
#include "modular_splurt\code\game\object\items\devices\radio\electropack.dm"
#include "modular_splurt\code\game\object\items\devices\radio\headset.dm"
#include "modular_splurt\code\game\object\items\devices\radio\radio.dm"
#include "modular_splurt\code\game\object\items\implants\implant_slave.dm"
#include "modular_splurt\code\game\object\items\implants\implant_slaver.dm"
@@ -4295,7 +4298,11 @@
#include "modular_splurt\code\game\turfs\simulated\floor\plating\asteroid.dm"
#include "modular_splurt\code\game\turfs\simulated\wall\mineral_walls.dm"
#include "modular_splurt\code\modules\admin\chat_commands.dm"
#include "modular_splurt\code\modules\admin\JobBan.dm"
#include "modular_splurt\code\modules\admin\Kick.dm"
#include "modular_splurt\code\modules\admin\NewBan.dm"
#include "modular_splurt\code\modules\admin\playtimes.dm"
#include "modular_splurt\code\modules\admin\Transform.dm"
#include "modular_splurt\code\modules\admin\verbs\discord_subsystem.dm"
#include "modular_splurt\code\modules\admin\verbs\discordbunker.dm"
#include "modular_splurt\code\modules\admin\verbs\one_click_antag.dm"
@@ -4429,6 +4436,8 @@
#include "modular_splurt\code\modules\mob\dead\new_player\sprite_accesories\synthliz.dm"
#include "modular_splurt\code\modules\mob\dead\new_player\sprite_accesories\tails.dm"
#include "modular_splurt\code\modules\mob\dead\new_player\sprite_accesories\wings.dm"
#include "modular_splurt\code\modules\mob\living\living.dm"
#include "modular_splurt\code\modules\mob\living\living_defines.dm"
#include "modular_splurt\code\modules\mob\living\carbon\human\human.dm"
#include "modular_splurt\code\modules\mob\living\carbon\human\human_defines.dm"
#include "modular_splurt\code\modules\mob\living\carbon\human\simple_animal\hostile\deathclaw\deathclaw.dm"
File diff suppressed because it is too large Load Diff
@@ -108,7 +108,7 @@ export const SlaveConsole = (props, context) => {
const SlavePanel = (props, context) => {
const { slaves } = props;
const { act, data } = useBackend(context);
const { act } = useBackend(context);
if (!slaves.length) {
return (
<NoticeBox danger>
@@ -239,7 +239,9 @@ const SupplyPanel = (props, context) => {
};
const RansomPanel = (props, context) => {
const { data } = useBackend(context);
const value_table = props.value_table;
const { cargo_credits, ransom_scale_value } = data;
let value_table_converted = [];
@@ -271,7 +273,10 @@ const RansomPanel = (props, context) => {
{rank_value.rank}
</Flex.Item>
<Flex.Item>
{formatMoney(rank_value.value, null, true)}cr
{formatMoney(
rank_value.value + (rank_value.value
* (cargo_credits / ransom_scale_value))
, null, true)}cr
</Flex.Item>
</Flex>
);