mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
## About The Pull Request Converts `/datum/player_details` into `/datum/persistent_client`. Persistent Clients persist across connections. The only time a mob's persistent client will change is if the ckey it's bound to logs into a different mob, or the mob is deleted (duh). Also adds PossessByPlayer() so that transfering mob control is cleaner and makes more immediate sense if you don't know byond-fu. ## Why It's Good For The Game Clients are an abstract representation of a connection that can be dropped at almost any moment so putting things that should be stable to access at any time onto an undying object is ideal. This allows for future expansions like abstracting away client.screen and managing everything cleanly.
190 lines
5.3 KiB
Plaintext
190 lines
5.3 KiB
Plaintext
#define BM_SWITCHSTATE_NONE 0
|
|
#define BM_SWITCHSTATE_MODE 1
|
|
#define BM_SWITCHSTATE_DIR 2
|
|
|
|
/datum/buildmode
|
|
var/build_dir = SOUTH
|
|
var/datum/buildmode_mode/mode
|
|
var/client/holder
|
|
|
|
// login callback
|
|
var/li_cb
|
|
|
|
// SECTION UI
|
|
var/list/buttons
|
|
|
|
// Switching management
|
|
var/switch_state = BM_SWITCHSTATE_NONE
|
|
var/switch_width = 4
|
|
// modeswitch UI
|
|
var/atom/movable/screen/buildmode/mode/modebutton
|
|
var/list/modeswitch_buttons = list()
|
|
// dirswitch UI
|
|
var/atom/movable/screen/buildmode/bdir/dirbutton
|
|
var/list/dirswitch_buttons = list()
|
|
/// item preview for selected item
|
|
var/atom/movable/screen/buildmode/preview_item/preview
|
|
|
|
/datum/buildmode/New(client/c)
|
|
mode = new /datum/buildmode_mode/basic(src)
|
|
holder = c
|
|
buttons = list()
|
|
li_cb = CALLBACK(src, PROC_REF(post_login))
|
|
holder.persistent_client.post_login_callbacks += li_cb
|
|
holder.show_popup_menus = FALSE
|
|
create_buttons()
|
|
holder.screen += buttons
|
|
holder.click_intercept = src
|
|
mode.enter_mode(src)
|
|
|
|
/datum/buildmode/proc/quit()
|
|
mode.exit_mode(src)
|
|
holder.screen -= buttons
|
|
holder.click_intercept = null
|
|
holder.show_popup_menus = TRUE
|
|
qdel(src)
|
|
|
|
/datum/buildmode/Destroy()
|
|
close_switchstates()
|
|
close_preview()
|
|
holder.persistent_client.post_login_callbacks -= li_cb
|
|
li_cb = null
|
|
holder = null
|
|
modebutton = null
|
|
dirbutton = null
|
|
QDEL_NULL(mode)
|
|
QDEL_LIST(buttons)
|
|
QDEL_LIST(modeswitch_buttons)
|
|
QDEL_LIST(dirswitch_buttons)
|
|
return ..()
|
|
|
|
/datum/buildmode/proc/post_login()
|
|
// since these will get wiped upon login
|
|
holder.screen += buttons
|
|
// re-open the according switch mode
|
|
switch(switch_state)
|
|
if(BM_SWITCHSTATE_MODE)
|
|
open_modeswitch()
|
|
if(BM_SWITCHSTATE_DIR)
|
|
open_dirswitch()
|
|
|
|
/datum/buildmode/proc/create_buttons()
|
|
// keep a reference so we can update it upon mode switch
|
|
modebutton = new /atom/movable/screen/buildmode/mode(src)
|
|
buttons += modebutton
|
|
buttons += new /atom/movable/screen/buildmode/help(src)
|
|
// keep a reference so we can update it upon dir switch
|
|
dirbutton = new /atom/movable/screen/buildmode/bdir(src)
|
|
buttons += dirbutton
|
|
buttons += new /atom/movable/screen/buildmode/quit(src)
|
|
// build the lists of switching buttons
|
|
build_options_grid(subtypesof(/datum/buildmode_mode), modeswitch_buttons, /atom/movable/screen/buildmode/modeswitch)
|
|
build_options_grid(GLOB.alldirs, dirswitch_buttons, /atom/movable/screen/buildmode/dirswitch)
|
|
|
|
// this creates a nice offset grid for choosing between buildmode options,
|
|
// because going "click click click ah hell" sucks.
|
|
/datum/buildmode/proc/build_options_grid(list/elements, list/buttonslist, buttontype)
|
|
var/pos_idx = 0
|
|
for(var/thing in elements)
|
|
var/x = pos_idx % switch_width
|
|
var/y = FLOOR(pos_idx / switch_width, 1)
|
|
var/atom/movable/screen/buildmode/B = new buttontype(src, thing)
|
|
// extra .5 for a nice offset look
|
|
B.screen_loc = "NORTH-[(1 + 0.5 + y*1.5)],WEST+[0.5 + x*1.5]"
|
|
buttonslist += B
|
|
pos_idx++
|
|
|
|
/datum/buildmode/proc/close_switchstates()
|
|
switch(switch_state)
|
|
if(BM_SWITCHSTATE_MODE)
|
|
close_modeswitch()
|
|
if(BM_SWITCHSTATE_DIR)
|
|
close_dirswitch()
|
|
|
|
/datum/buildmode/proc/toggle_modeswitch()
|
|
if(switch_state == BM_SWITCHSTATE_MODE)
|
|
close_modeswitch()
|
|
else
|
|
close_switchstates()
|
|
open_modeswitch()
|
|
|
|
/datum/buildmode/proc/open_modeswitch()
|
|
switch_state = BM_SWITCHSTATE_MODE
|
|
holder.screen += modeswitch_buttons
|
|
|
|
/datum/buildmode/proc/close_modeswitch()
|
|
switch_state = BM_SWITCHSTATE_NONE
|
|
holder.screen -= modeswitch_buttons
|
|
|
|
/datum/buildmode/proc/toggle_dirswitch()
|
|
if(switch_state == BM_SWITCHSTATE_DIR)
|
|
close_dirswitch()
|
|
else
|
|
close_switchstates()
|
|
open_dirswitch()
|
|
|
|
/datum/buildmode/proc/open_dirswitch()
|
|
switch_state = BM_SWITCHSTATE_DIR
|
|
holder.screen += dirswitch_buttons
|
|
|
|
/datum/buildmode/proc/close_dirswitch()
|
|
switch_state = BM_SWITCHSTATE_NONE
|
|
holder.screen -= dirswitch_buttons
|
|
|
|
/datum/buildmode/proc/preview_selected_item(atom/typepath)
|
|
close_preview()
|
|
preview = new /atom/movable/screen/buildmode/preview_item(src)
|
|
preview.name = initial(typepath.name)
|
|
|
|
// Scale the preview if it's bigger than one tile
|
|
var/mutable_appearance/preview_overlay = get_small_overlay(new /mutable_appearance(typepath))
|
|
preview_overlay.appearance_flags |= TILE_BOUND
|
|
preview_overlay.layer = FLOAT_LAYER
|
|
preview_overlay.plane = FLOAT_PLANE
|
|
preview.add_overlay(preview_overlay)
|
|
|
|
holder.screen += preview
|
|
|
|
/datum/buildmode/proc/close_preview()
|
|
if(isnull(preview))
|
|
return
|
|
holder.screen -= preview
|
|
QDEL_NULL(preview)
|
|
|
|
/datum/buildmode/proc/change_mode(newmode)
|
|
mode.exit_mode(src)
|
|
QDEL_NULL(mode)
|
|
close_switchstates()
|
|
close_preview()
|
|
mode = new newmode(src)
|
|
mode.enter_mode(src)
|
|
modebutton.update_appearance()
|
|
|
|
/datum/buildmode/proc/change_dir(newdir)
|
|
build_dir = newdir
|
|
close_dirswitch()
|
|
dirbutton.update_appearance()
|
|
return 1
|
|
|
|
/datum/buildmode/proc/InterceptClickOn(mob/user, params, atom/object)
|
|
mode.handle_click(user.client, params, object)
|
|
return TRUE // no doing underlying actions
|
|
|
|
/proc/togglebuildmode(mob/M as mob in GLOB.player_list)
|
|
set name = "Toggle Build Mode"
|
|
set category = "Event"
|
|
|
|
if(M.client)
|
|
if(istype(M.client.click_intercept,/datum/buildmode))
|
|
var/datum/buildmode/B = M.client.click_intercept
|
|
B.quit()
|
|
log_admin("[key_name(M)] has left build mode.")
|
|
else
|
|
new /datum/buildmode(M.client)
|
|
message_admins("[key_name_admin(M)] has entered build mode.")
|
|
log_admin("[key_name(M)] has entered build mode.")
|
|
|
|
#undef BM_SWITCHSTATE_NONE
|
|
#undef BM_SWITCHSTATE_MODE
|
|
#undef BM_SWITCHSTATE_DIR
|