Skip to content

Commit

Permalink
Merge pull request #85 from Superlagg/player-has-disconnected-from-th…
Browse files Browse the repository at this point in the history
…e-game

Add stash and lock equipment on logout preferences
  • Loading branch information
Tk420634 authored Dec 3, 2024
2 parents 2801b4b + 82d8474 commit 7274a57
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 43 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/voreconstants.dm
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,5 @@ GLOBAL_LIST_INIT(prey_release_sounds, list(

#define SEE_FANCY_OFF_SCREEN_RUNECHAT "SEE_FANCY_OFF_SCREEN_RUNECHAT"
#define SHOW_ME_HORNY_FURRIES "SHOW_ME_HORNY_FURRIES"
#define DUMP_STUFF_ON_LOGOUT "DUMP_STUFF_ON_LOGOUT"
#define LOCK_STUFF_ON_LOGOUT "LOCK_STUFF_ON_LOGOUT"
26 changes: 25 additions & 1 deletion code/controllers/subsystem/prefbreak.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ SUBSYSTEM_DEF(prefbreak) // ALL ABOARD THE S.S. PREFBREAK OFF TO **** YOUR *****
return zloy.prefs
if(ismob(pingvin))
var/mob/zloy = pingvin
return zloy.client?.prefs
if(zloy.client)
return zloy.client.prefs
pingvin = zloy.ckey // in case theyre not here
if(istext(pingvin))
if(isclient(GLOB.directory[ckey(pingvin)]))
var/client/zloy = GLOB.directory[ckey(pingvin)]
return zloy.prefs
else if(istype(GLOB.preferences_datums[ckey(pingvin)], /datum/preferences))
return GLOB.preferences_datums[ckey(pingvin)] // not even being offline can save you from the ULTIMATE BREAKER

/// takes in anything, sees if it has a client/prefs/whatever, and checks those prefs
/// Allows things by default, denies it if specifically disallowed
Expand Down Expand Up @@ -269,6 +277,22 @@ SUBSYSTEM_DEF(prefbreak) // ALL ABOARD THE S.S. PREFBREAK OFF TO **** YOUR *****
return CHECK_BITFIELD(consumer.chat_toggles, CHAT_SEE_COOLCHAT) // kinda vital here
// return consumer.see_fancy_offscreen_runechat // kinda vital here

///////////////////////////////////////////////////////////////////////////////////
/datum/prefcheck/stash_equipment_on_logout
index = DUMP_STUFF_ON_LOGOUT

/datum/prefcheck/stash_equipment_on_logout/allowed(datum/preferences/consumer)
PREFBROKEN
return consumer.stash_equipment_on_logout // kinda vital here

///////////////////////////////////////////////////////////////////////////////////
/datum/prefcheck/lock_equipment_on_logout
index = LOCK_STUFF_ON_LOGOUT

/datum/prefcheck/lock_equipment_on_logout/allowed(datum/preferences/consumer)
PREFBROKEN
return consumer.lock_equipment_on_logout // kinda vital here




Expand Down
9 changes: 9 additions & 0 deletions code/datums/components/storage/concrete/backpack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
rustle_sound = TRUE
number_of_rows = STORAGE_ROWS_BACKPACK

/datum/component/storage/concrete/debug_sack/massive
storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT // space limited, only
max_items = STORAGE_BACKPACK_DEFAULT_MAX_ITEMS
max_w_class = WEIGHT_CLASS_GIGANTIC
max_combined_w_class = STORAGE_DUFFEL_SCAV_DEFAULT_MAX_TOTAL_SPACE * 2
max_volume = STORAGE_DUFFEL_SCAV_DEFAULT_MAX_TOTAL_SPACE * 2
rustle_sound = TRUE
number_of_rows = STORAGE_ROWS_DUFFEL_SCAV + 1

/// Backpack
/datum/component/storage/concrete/backpack
storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT // space limited, only
Expand Down
3 changes: 3 additions & 0 deletions code/datums/components/storage/storage.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
var/list/mob/is_using //lazy list of mobs looking at the contents of this storage.

var/locked = FALSE //when locked nothing can see inside or use it.
var/lock_key = null //Only this ckey can use this storage (or admins)

/// Storage flags, including what kinds of limiters we use for how many items we can hold
var/storage_flags = STORAGE_FLAGS_VOLUME_AND_NUMBER
Expand Down Expand Up @@ -632,6 +633,8 @@

/datum/component/storage/proc/check_locked(datum/source, mob/user, message = FALSE)
. = locked
if(lock_key && user && ckey(user.ckey) != ckey(lock_key))
. = TRUE
if(message && . && user)
to_chat(user, span_warning("[parent] seems to be locked!"))

Expand Down
13 changes: 11 additions & 2 deletions code/modules/client/preferences.dm
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
/// lets the user see runechat that's hidden behind a wall
var/see_hidden_runechat = TRUE

var/stash_equipment_on_logout = TRUE
var/lock_equipment_on_logout = TRUE

/datum/preferences/New(client/C)
parent = C

Expand Down Expand Up @@ -589,8 +592,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)

dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender;task=input'>[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]</a><BR>"
dat += "<b>Age:</b> <a style='display:block;width:30px' href='?_src_=prefs;preference=age;task=input'>[age]</a><BR>"
dat += "<b>Top/Bottom/Switch:</b> <a href='?_src_=prefs;preference=tbs;task=input'>[tbs]</a><BR>"
dat += "<b>Orientation:</b> <a href='?_src_=prefs;preference=kisser;task=input'>[kisser]</a><BR>"
dat += "<b>Top/Bottom/Switch:</b> <a href='?_src_=prefs;preference=tbs;task=input'>[tbs || "Set me!"]</a><BR>"
dat += "<b>Orientation:</b> <a href='?_src_=prefs;preference=kisser;task=input'>[kisser || "Set me!"]</a><BR>"
dat += "<b>When you despawn, all your equipment...</b> <a href='?_src_=prefs;preference=stash_equipment_on_logout;task=input'>[stash_equipment_on_logout?"will be left where you despawn":"will be deleted"]</a><BR>"
dat += "<b>Your equipment, if left behind...</b> <a href='?_src_=prefs;preference=lock_equipment_on_logout;task=input'>[lock_equipment_on_logout?"will be locked (only you can open it)":"will be open for everyone"]</a><BR>"
dat += "</td>"
/* //Middle Column
dat +="<td width='30%' valign='top'>"
Expand Down Expand Up @@ -2798,6 +2803,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/newkiss = input(user, "What sort of person do you like to kisser?", "Character Preference") as null|anything in KISS_LIST
if(newkiss)
kisser = newkiss
if("stash_equipment_on_logout")
TOGGLE_VAR(stash_equipment_on_logout)
if("lock_equipment_on_logout")
TOGGLE_VAR(lock_equipment_on_logout)
if("age")
var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null
if(new_age)
Expand Down
5 changes: 5 additions & 0 deletions code/modules/client/preferences_savefile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
saved_active_quests = safe_json_decode(helicopter_postcum)
S["number_of_finished_quests"] >> number_of_finished_quests
S["historical_banked_points"] >> historical_banked_points
S["stash_equipment_on_logout"] >> stash_equipment_on_logout
S["lock_equipment_on_logout"] >> lock_equipment_on_logout

//sanitize data
show_in_directory = sanitize_integer(show_in_directory, 0, 1, initial(show_in_directory))
Expand All @@ -1028,6 +1030,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
number_of_finished_quests = sanitize_integer(number_of_finished_quests, 0, INFINITY, initial(number_of_finished_quests))
historical_banked_points = sanitize_integer(historical_banked_points, 0, INFINITY, initial(historical_banked_points))
last_quest_login = sanitize_integer(last_quest_login, 5, INFINITY, world.realtime)
stash_equipment_on_logout = sanitize_integer(stash_equipment_on_logout, 0, 1, initial(stash_equipment_on_logout))
lock_equipment_on_logout = sanitize_integer(lock_equipment_on_logout, 0, 1, initial(lock_equipment_on_logout))
if(features["chat_color"] == "whoopsie")
features["chat_color"] = random_color()

Expand Down Expand Up @@ -1375,6 +1379,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["gender"] , gender)
WRITE_FILE(S["tbs"] , tbs)
WRITE_FILE(S["kisser"] , kisser)
WRITE_FILE(S["stash_equipment_on_logout"] , stash_equipment_on_logout)
WRITE_FILE(S["body_model"] , features["body_model"])
WRITE_FILE(S["body_size"] , features["body_size"])
WRITE_FILE(S["body_width"] , features["body_width"])
Expand Down
198 changes: 158 additions & 40 deletions code/modules/fallout/turf/walls.dm
Original file line number Diff line number Diff line change
Expand Up @@ -316,63 +316,181 @@

/turf/closed/indestructible/f13/matrix/MouseDrop_T(atom/dropping, mob/user)
. = ..()
if(!dropping || !user)
return
if(!isliving(user))
to_chat(user, span_warning("Can't quite do that!"))
return
if(!isliving(dropping))
to_chat(user, span_warning("That's not something that this thing can do anything with!"))
return
if(QDELETED(dropping))
to_chat(user, span_warning("They're already on their way out!"))
return
if(!isliving(user) || user.incapacitated(allow_crit = TRUE) || !isliving(dropping))
return //No ghosts or incapacitated folk allowed to do this.
if(in_use) // Someone's already going in.
to_chat(user, span_warning("Someone is already using that thing, or it just stopped working. Try a different tile =3"))
return
if(SSmobs.there_is_no_escape)
to_chat(user, span_warning("This method of escape has been disabled. Sorry! You're allowed to ghost out and respawn though, just ahelp and tell an admin to ditch your body."))
to_chat(user, span_warning("This method of escape has been disabled. Sorry!"))
return
var/mob/living/departing_mob = dropping
if(departing_mob != user && departing_mob.client)
to_chat(user, span_warning("This one retains their free will. It's their choice if they want to depart or not."))
if(dropping == user)
depart_self(user)
else
depart_other(user, dropping)

/turf/closed/indestructible/f13/matrix/proc/depart_self(mob/living/user)
if(in_use)
return
if(alert("Are you sure you want to [departing_mob == user ? "depart the area for good (you" : "send this person away (they"] will be removed from the current round, the job slot freed)?", "Departing the swamps", "Confirm", "Cancel") != "Confirm")
in_use = TRUE
var/igo = alert(
user,
"This will depart you from the game (despawn you). You can come back any time you want! Are you sure you want to do this?",
"Time to go!",
"Depart!",
"Cancel",
)
if(igo != "Depart!")
return
if(user.incapacitated(allow_crit = TRUE) || QDELETED(departing_mob) || (departing_mob != user && departing_mob.client) || get_dist(src, dropping) > 2 || get_dist(src, user) > 2)
return //Things have changed since the alert happened.
if(departing_mob.logout_time && departing_mob.logout_time + 2 MINUTES > world.time)
to_chat(user, span_warning("This mind has only recently departed. Wait at most two minutes before sending this character out of the round."))
var/dumpit = alert(
user,
"Want to dump all your stuff into a bag before you go? It'll sit here until you come back (or someone else takes it!).",
"Durg?",
"Dump it!",
"No thanks",
)
dumpit = (dumpit == "Dump it!") ? TRUE : FALSE
var/lockit = CHECK_PREFS(user, DUMP_STUFF_ON_LOGOUT)
var/worked = FALSE
if(do_after(
user,
(3 SECONDS),
FALSE,
src,
TRUE,
null,
null,
null,
FALSE,
TRUE,
TRUE,
TRUE,
TRUE,
))
worked = TRUE
in_use = FALSE
if(!worked)
to_chat(user, span_warning("Okay nevermind!!"))
return
user.visible_message(span_warning("[user] [departing_mob == user ? "is trying to leave the swamps!" : "is trying to send [departing_mob] away!"]"), span_notice("I [departing_mob == user ? "are trying to leave the swamps." : "are trying to send [departing_mob] away."]"))
icon_state = "matrix_going" // ALERT, WEE WOO
update_icon()
in_use = TRUE
if(!do_after(user, 50, target = src))
icon_state = initial(icon_state)
in_use = FALSE
to_chat(user, span_notice("You have departed from the bar, hope to see you soon!"))
user.visible_message(span_notice("[user] has departed from the bar. Hope to see them soon!"))
if(dumpit)
to_chat(user, span_notice("Your stuff has been put into a bag."))
StuffPlayerContentsIntoABag(user, get_turf(user), lockit)
message_admins("[key_name(user)] has departed from the bar.")
log_admin("[key_name(user)] has departed from the bar.")
if(user.client.is_in_game >= 1)
// if(user.client.is_in_game == 2)
// to_chat(world, span_nicegreen("I hear through the grapevine that [user.name] has left the county."))
user.client.is_in_game = 0
whoosh(user)
user.despawn()

/turf/closed/indestructible/f13/matrix/proc/depart_other(mob/living/user, mob/living/departing_mob)
if(in_use)
return
if(departing_mob.client)
to_chat(user, span_warning("That person is still 'with us', so they'll have to decide for themselves if they want to leave."))
return
var/igo = alert(
user,
"This will depart [departing_mob] from the game (despawn them). They can come back any time they want! Are you sure you want to do this? All their stuff will be left in a sack, just in case.",
"Send 'em packing!",
"Send them away!",
"Cancel",
)
if(igo != "Send them away!")
return
icon_state = initial(icon_state)
in_use = TRUE
var/worked = FALSE
if(do_after(
user,
(3 SECONDS),
FALSE,
src,
TRUE,
null,
null,
null,
FALSE,
TRUE,
TRUE,
TRUE,
TRUE,
))
worked = TRUE
in_use = FALSE
update_icon()
var/dat
if(ishuman(departing_mob))
dat = "[key_name(user)] has despawned [departing_mob == user ? "themselves" : departing_mob]."
else if(isanimal(departing_mob))
dat = "[key_name(user)] has despawned [departing_mob == user ? "themselves" : departing_mob]."
if(!length(departing_mob.contents))
dat += " none."
else
var/atom/movable/content = departing_mob.contents[1]
dat += " [content.name]"
for(var/i in 2 to length(departing_mob.contents))
content = departing_mob.contents[i]
dat += ", [content.name]"
dat += "."
message_admins(dat)
log_admin(dat)
if(departing_mob.stat == DEAD)
departing_mob.visible_message(span_notice("[user] pushes the body of [departing_mob] over the border. They're someone else's problem now."))
else
departing_mob.visible_message(span_notice("[departing_mob == user ? "Out of their own volition, " : "Ushered by [user], "][departing_mob] crosses the border and departs the swamps."))

if(!worked)
to_chat(user, span_warning("Okay nevermind!!"))
return
var/lockit = CHECK_PREFS(user, DUMP_STUFF_ON_LOGOUT)
to_chat(user, span_notice("[user] has sent [departing_mob] away. Hope to see them soon!"))
departing_mob.visible_message(span_notice("[departing_mob] has been sent away. Hope to see them soon!"))
StuffPlayerContentsIntoABag(departing_mob, get_turf(departing_mob), lockit)
message_admins("[key_name(user)] has sent [key_name(departing_mob)] away.")
log_admin("[key_name(user)] has sent [key_name(departing_mob)] away.")
if(departing_mob.client.is_in_game >= 1)
// if(departing_mob.client.is_in_game == 2)
// to_chat(world, span_nicegreen("I hear through the grapevine that [departing_mob.name] has left the county."))
departing_mob.client.is_in_game = 0

whoosh(departing_mob)
departing_mob.despawn()

/turf/closed/indestructible/f13/matrix/proc/whoosh(mob/departing_mob)
do_sparks(2, TRUE, departing_mob)
playsound(departing_mob, 'sound/effects/player_despawn.ogg', 80, TRUE)

/proc/StuffPlayerContentsIntoABag(mob/who, atom/where, lockit)
if(!who)
return
if(!where)
where = get_turf(who)
var/obj/item/storage/despawned/box = new /obj/item/storage/despawned(where)
for(var/obj/item/I in who.contents)
if(istype(I, /obj/item/organ))
continue
if(istype(I, /obj/item/bodypart))
continue
if(HAS_TRAIT(I, TRAIT_NODROP))
continue
I.forceMove(box)
if(lockit)
box.SetOwnerKey(who)

/obj/item/storage/despawned
name = "box of stuff"
desc = "A sack of belongings belonging to someone who left and might want to come back."
icon_state = "eq_box"
inhand_icon_state = "backpack"
lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
w_class = WEIGHT_CLASS_GIGANTIC
slot_flags = NONE
resistance_flags = INDESTRUCTIBLE
component_type = /datum/component/storage/concrete/debug_sack/massive
var/owner_key

/obj/item/storage/despawned/examine(mob/user)
. = ..()
if(user.ckey == owner_key)
to_chat(user, span_greentext("This is your stuff! It belongs to you! =3"))

/obj/item/storage/despawned/proc/SetOwnerKey(mob/who)
owner_key = who.ckey
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.lock_key = owner_key

/turf/closed/indestructible/f13/obsidian //Just like that one game studio that worked on the original game, or that block in Minecraft!
name = "obsidian"
desc = "No matter what you do with this rock, there's not even a scratch left on its surface.<br><font color='#7e0707'>You shall not pass!!!</font>"
Expand Down
Binary file added sound/effects/player_despawn.ogg
Binary file not shown.

0 comments on commit 7274a57

Please sign in to comment.