mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-04-22 04:03:35 +01:00
## About The Pull Request This PR converts the native text/list input that pops up when the Spawn verb is used into a TGUI panel with a dynamic search function. It now displays atom names, as well if they are abstract (and probably shouldn't be spawned). You can still input a typepath after the spawn verb in the tab bar which will open the menu with said path already in the input box. If only one typepath matches the input, it will be spawned immediately without opening the panel. <img width="400" height="500" alt="Qs0t8xkGj7" src="https://github.com/user-attachments/assets/d54a57d5-fc22-4f59-af18-45b4fab0b256" /> It features RegEx support which activates when the input starts with ``re:``, as well as toggles for searching in atom names and fancy typepath display. They can be toggled via buttons, or Alt+R/N/F for regex/names/fancy paths respectively. Invalid regex-es will highlight the search bar red. The list itself can be navigated using arrow keys, enter/double click will spawn the atom, and escape will close the menu. <img width="400" height="500" alt="xgK2vCd1ck" src="https://github.com/user-attachments/assets/e621c6ba-ad6b-4a30-922f-eb863797c65a" /> <img width="400" height="500" alt="2DeOPBRqoC" src="https://github.com/user-attachments/assets/18fbba32-17d7-4351-bbc2-bc8e66eb24ae" /> Old functionality of spawning multiple objects by leaving a colon + number after the typepath has been preserved. Using ``*`` and``!`` to signify final path/end of a path respectively also still works when regex mode isn't active. ## Why It's Good For The Game Spawn isn't a critical tool, and using TGUI allows it to have dynamic search and shifts searching from serverside to clientside, making it significantly more responsive. Because we don't need to build a fancy list of atom types, using it the first time won't cause a lag spike on weaker machines anymore, which should make debugging locally a bit less annoying. ## Changelog 🆑 admin: Converted the Spawn verb into a TGUI input, featuring for dynamic search and RegEx support /🆑
300 lines
9.6 KiB
Plaintext
300 lines
9.6 KiB
Plaintext
#define WHERE_FLOOR_BELOW_MOB "Current location"
|
|
#define WHERE_SUPPLY_BELOW_MOB "Current location (droppod)"
|
|
#define WHERE_MOB_HAND "In own mob's hand"
|
|
#define WHERE_MARKED_OBJECT "At a marked object"
|
|
#define WHERE_IN_MARKED_OBJECT "In the marked object"
|
|
#define WHERE_TARGETED_LOCATION "Targeted location"
|
|
#define WHERE_TARGETED_LOCATION_POD "Targeted location (droppod)"
|
|
#define WHERE_TARGETED_MOB_HAND "In targeted mob's hand"
|
|
|
|
#define PRECISE_MODE_OFF "Off"
|
|
#define PRECISE_MODE_TARGET "Target"
|
|
#define PRECISE_MODE_MARK "Mark"
|
|
#define PRECISE_MODE_COPY "Copy"
|
|
|
|
#define OFFSET_ABSOLUTE "Absolute offset"
|
|
#define OFFSET_RELATIVE "Relative offset"
|
|
|
|
/*
|
|
An instance of a /tg/UI™ Spawn Panel. Stores preferences, spawns things, controls the UI. Unique for each user (their ckey).
|
|
*/
|
|
/datum/spawnpanel
|
|
/// Where and how the atom should be spawned.
|
|
var/where_target_type = WHERE_FLOOR_BELOW_MOB
|
|
/// The atom selected from the panel.
|
|
var/atom/selected_atom = null
|
|
/// The icon selected for the atom from the panel.
|
|
var/selected_atom_icon = null
|
|
/// The icon state selected for the atom from the panel.
|
|
var/selected_atom_icon_state = null
|
|
/// Should selected icon/icon state override the initial ones? Added as an edge case to not replace animated GAGS icons.
|
|
var/apply_icon_override = FALSE
|
|
/// A list of icon states to display in preview panels.
|
|
var/list/available_icon_states = null
|
|
/// Override for the icon size of the spawned mob.
|
|
var/atom_icon_size = 100
|
|
/// How many atoms will be spawned at once.
|
|
var/atom_amount = 1
|
|
/// Custom atom name (leave `null` for initial).
|
|
var/atom_name = null
|
|
/// Custom atom description (leave `null` for initial).
|
|
var/atom_desc = null
|
|
/// Custom atom dir (leave `null` for `2`).
|
|
var/atom_dir = 1
|
|
/// An associative list of x-y-z offsets.
|
|
var/offset = list()
|
|
/// The pivot point for offsetting — relative or absolute.
|
|
var/offset_type = OFFSET_RELATIVE
|
|
/// Precise mode toggle. Used for build-mode-like spawning experience and targeting datums.
|
|
var/precise_mode = PRECISE_MODE_OFF
|
|
|
|
/datum/spawnpanel/New()
|
|
. = ..()
|
|
offset = list("X" = 0, "Y" = 0, "Z" = 0)
|
|
|
|
/datum/spawnpanel/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "SpawnPanel")
|
|
ui.open()
|
|
|
|
/datum/spawnpanel/ui_close(mob/user)
|
|
. = ..()
|
|
if (precise_mode && precise_mode != PRECISE_MODE_OFF)
|
|
toggle_precise_mode(PRECISE_MODE_OFF)
|
|
|
|
/datum/spawnpanel/ui_state(mob/user)
|
|
return ADMIN_STATE(R_SPAWN)
|
|
|
|
/datum/spawnpanel/ui_act(action, params, datum/tgui/ui)
|
|
if(..() || !check_rights_for(ui.user.client, R_SPAWN))
|
|
return FALSE
|
|
|
|
switch(action)
|
|
if("select-new-DMI")
|
|
var/icon/new_icon = input("Select a new icon file:", "Icon") as null|icon
|
|
if(new_icon)
|
|
selected_atom_icon = new_icon
|
|
available_icon_states = icon_states(selected_atom_icon)
|
|
if(!(selected_atom_icon_state in available_icon_states))
|
|
selected_atom_icon_state = available_icon_states[1]
|
|
return TRUE
|
|
|
|
if("set-apply-icon-override")
|
|
apply_icon_override = !!params["value"]
|
|
return TRUE
|
|
|
|
if("reset-DMI-icon")
|
|
selected_atom_icon = null
|
|
selected_atom_icon_state = null
|
|
if(selected_atom)
|
|
selected_atom_icon = initial(selected_atom.icon)
|
|
selected_atom_icon_state = initial(selected_atom.icon_state)
|
|
available_icon_states = icon_states(selected_atom_icon)
|
|
else
|
|
available_icon_states = list()
|
|
return TRUE
|
|
|
|
if("select-new-icon-state")
|
|
selected_atom_icon_state = params["new_state"]
|
|
return TRUE
|
|
|
|
if("reset-icon-state")
|
|
selected_atom_icon_state = null
|
|
if(selected_atom)
|
|
selected_atom_icon_state = initial(selected_atom.icon_state)
|
|
return TRUE
|
|
|
|
if("set-icon-size")
|
|
atom_icon_size = params["size"]
|
|
return TRUE
|
|
|
|
if("reset-icon-size")
|
|
atom_icon_size = 100
|
|
return TRUE
|
|
|
|
if("get-icon-states")
|
|
available_icon_states = icon_states(selected_atom_icon)
|
|
return TRUE
|
|
|
|
if("selected-atom-changed")
|
|
var/path = text2path(params["newObj"])
|
|
if(path)
|
|
var/atom/temp_atom = path
|
|
selected_atom_icon = initial(temp_atom.icon)
|
|
selected_atom_icon_state = initial(temp_atom.icon_state)
|
|
available_icon_states = icon_states(selected_atom_icon)
|
|
selected_atom = temp_atom
|
|
return TRUE
|
|
|
|
if("create-atom-action")
|
|
var/list/spawn_params = list(
|
|
"selected_atom" = selected_atom,
|
|
"offset" = params["offset"],
|
|
"atom_dir" = text2num(params["dir"]) || 1,
|
|
"atom_amount" = text2num(params["atom_amount"]) || 1,
|
|
"atom_name" = params["atom_name"],
|
|
"where_target_type" = params["where_target_type"] || WHERE_FLOOR_BELOW_MOB,
|
|
"atom_icon_size" = params["atom_icon_size"],
|
|
"offset_type" = params["offset_type"] || OFFSET_RELATIVE,
|
|
"apply_icon_override" = apply_icon_override,
|
|
)
|
|
|
|
if(apply_icon_override)
|
|
spawn_params["selected_atom_icon"] = selected_atom_icon
|
|
spawn_params["selected_atom_icon_state"] = selected_atom_icon_state
|
|
|
|
spawn_atom(spawn_params, usr)
|
|
return TRUE
|
|
|
|
if("toggle-precise-mode")
|
|
var/precise_type = params["newPreciseType"]
|
|
if(precise_type == PRECISE_MODE_TARGET && params["where_target_type"])
|
|
where_target_type = params["where_target_type"]
|
|
toggle_precise_mode(precise_type)
|
|
return TRUE
|
|
|
|
if("update-settings")
|
|
if(params["atom_amount"])
|
|
atom_amount = text2num(params["atom_amount"])
|
|
if(params["atom_dir"])
|
|
atom_dir = text2num(params["atom_dir"])
|
|
if(params["offset"])
|
|
var/list/temp_offset = params["offset"]
|
|
offset["X"] = temp_offset[1]
|
|
offset["Y"] = temp_offset[2]
|
|
offset["Z"] = temp_offset[3]
|
|
if(params["atom_name"])
|
|
atom_name = params["atom_name"]
|
|
if(params["where_target_type"])
|
|
where_target_type = params["where_target_type"]
|
|
if(params["offset_type"])
|
|
offset_type = params["offset_type"]
|
|
if(params["atom_icon_size"])
|
|
atom_icon_size = text2num(params["atom_icon_size"])
|
|
if(params["selected_atom_icon"])
|
|
selected_atom_icon = params["selected_atom_icon"]
|
|
if(params["selected_atom_icon_state"])
|
|
selected_atom_icon_state = params["selected_atom_icon_state"]
|
|
return TRUE
|
|
|
|
/datum/spawnpanel/proc/toggle_precise_mode(precise_type)
|
|
precise_mode = precise_type
|
|
var/client/admin_client = usr.client
|
|
if (!admin_client)
|
|
return
|
|
|
|
admin_client.mouse_up_icon = null
|
|
admin_client.mouse_down_icon = null
|
|
admin_client.mouse_override_icon = null
|
|
admin_client.click_intercept = null
|
|
|
|
if (precise_mode != PRECISE_MODE_OFF)
|
|
admin_client.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_pickturf.dmi'
|
|
admin_client.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_pickturf_down.dmi'
|
|
admin_client.mouse_override_icon = admin_client.mouse_up_icon
|
|
admin_client.mouse_pointer_icon = admin_client.mouse_override_icon
|
|
admin_client.click_intercept = src
|
|
|
|
winset(admin_client, "mapwindow.map", "right-click=true")
|
|
else
|
|
winset(admin_client, "mapwindow.map", "right-click=false")
|
|
|
|
var/mob/holder_mob = admin_client.mob
|
|
holder_mob?.update_mouse_pointer()
|
|
|
|
/datum/spawnpanel/proc/InterceptClickOn(mob/user, params, atom/target)
|
|
var/list/modifiers = params2list(params)
|
|
var/left_click = LAZYACCESS(modifiers, LEFT_CLICK)
|
|
var/right_click = LAZYACCESS(modifiers, RIGHT_CLICK)
|
|
|
|
if(right_click)
|
|
toggle_precise_mode(PRECISE_MODE_OFF)
|
|
SStgui.update_uis(src)
|
|
return TRUE
|
|
|
|
if(left_click)
|
|
if(istype(target,/atom/movable/screen))
|
|
return FALSE
|
|
|
|
var/turf/clicked_turf = get_turf(target)
|
|
if(!clicked_turf)
|
|
return FALSE
|
|
|
|
switch(precise_mode)
|
|
if(PRECISE_MODE_TARGET)
|
|
var/list/spawn_params = list(
|
|
"selected_atom" = selected_atom,
|
|
"atom_amount" = atom_amount,
|
|
"offset" = "0,0,0",
|
|
"atom_dir" = atom_dir,
|
|
"atom_name" = atom_name,
|
|
"atom_desc" = atom_desc,
|
|
"offset_type" = OFFSET_ABSOLUTE,
|
|
"where_target_type" = where_target_type,
|
|
"target" = target,
|
|
"atom_icon_size" = atom_icon_size,
|
|
"apply_icon_override" = apply_icon_override,
|
|
)
|
|
|
|
if(apply_icon_override)
|
|
spawn_params["selected_atom_icon"] = selected_atom_icon
|
|
spawn_params["selected_atom_icon_state"] = selected_atom_icon_state
|
|
|
|
if(where_target_type == WHERE_TARGETED_LOCATION || where_target_type == WHERE_TARGETED_LOCATION_POD)
|
|
spawn_params["X"] = clicked_turf.x
|
|
spawn_params["Y"] = clicked_turf.y
|
|
spawn_params["Z"] = clicked_turf.z
|
|
|
|
spawn_atom(spawn_params, user)
|
|
|
|
if(PRECISE_MODE_MARK)
|
|
var/client/admin_client = user.client
|
|
admin_client.mark_datum(target)
|
|
to_chat(user, span_notice("Marked object: [icon2html(target, user)] [span_bold("[target]")]"))
|
|
toggle_precise_mode(PRECISE_MODE_OFF)
|
|
SStgui.update_uis(src)
|
|
|
|
if(PRECISE_MODE_COPY)
|
|
to_chat(user, span_notice("Picked object: [icon2html(target, user)] [span_bold("[target]")]"))
|
|
selected_atom = target
|
|
toggle_precise_mode(PRECISE_MODE_OFF)
|
|
SStgui.update_uis(src)
|
|
|
|
return TRUE
|
|
|
|
/datum/spawnpanel/ui_data(mob/user)
|
|
var/data = list()
|
|
data["icon"] = selected_atom_icon
|
|
data["iconState"] = selected_atom_icon_state
|
|
data["iconSize"] = atom_icon_size
|
|
data["apply_icon_override"] = apply_icon_override
|
|
var/list/states = list()
|
|
if(available_icon_states)
|
|
for(var/state in available_icon_states)
|
|
states += state
|
|
data["iconStates"] = states
|
|
data["precise_mode"] = precise_mode
|
|
data["selected_object"] = selected_atom ? "[selected_atom.type]" : ""
|
|
return data
|
|
|
|
/datum/spawnpanel/ui_assets(mob/user)
|
|
return list(
|
|
get_asset_datum(/datum/asset/json/spawnpanel),
|
|
)
|
|
|
|
#undef WHERE_FLOOR_BELOW_MOB
|
|
#undef WHERE_SUPPLY_BELOW_MOB
|
|
#undef WHERE_MOB_HAND
|
|
#undef WHERE_MARKED_OBJECT
|
|
#undef WHERE_IN_MARKED_OBJECT
|
|
#undef WHERE_TARGETED_LOCATION
|
|
#undef WHERE_TARGETED_LOCATION_POD
|
|
#undef WHERE_TARGETED_MOB_HAND
|
|
#undef PRECISE_MODE_OFF
|
|
#undef PRECISE_MODE_TARGET
|
|
#undef PRECISE_MODE_MARK
|
|
#undef PRECISE_MODE_COPY
|
|
#undef OFFSET_ABSOLUTE
|
|
#undef OFFSET_RELATIVE
|