diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 6be76b4df87..b87878e7453 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -32,7 +32,7 @@ GLOBAL_PROTECT(href_token) var/deadmined - var/datum/filter_editor/filteriffic + var/datum/filter_editor/filterrific var/datum/particle_editor/particle_test var/datum/colorblind_tester/color_test var/datum/plane_master_debug/plane_debug diff --git a/code/modules/admin/view_variables/filterrific.dm b/code/modules/admin/view_variables/filterrific.dm index f8dbd7fee43..89172c46e12 100644 --- a/code/modules/admin/view_variables/filterrific.dm +++ b/code/modules/admin/view_variables/filterrific.dm @@ -10,7 +10,7 @@ /datum/filter_editor/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "Filteriffic") + ui = new(user, src, "Filterrific") ui.open() /datum/filter_editor/ui_static_data(mob/user) @@ -21,7 +21,14 @@ /datum/filter_editor/ui_data() var/list/data = list() data["target_name"] = target.name - data["target_filter_data"] = target.filter_data + var/list/target_filter_data = list() + for (var/list/filter_info as anything in target.filter_data) + filter_info = deep_copy_list(filter_info) + if (filter_info["transform"]) + var/matrix/filter_transform = filter_info["transform"] + filter_info["transform"] = list("a" = filter_transform.a, "b" = filter_transform.b, "c" = filter_transform.c, "d" = filter_transform.d, "e" = filter_transform.e, "f" = filter_transform.f) + target_filter_data += list(filter_info) + data["target_filter_data"] = target_filter_data return data /datum/filter_editor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) @@ -59,7 +66,7 @@ target.modify_filter(params["name"], params["new_data"]) . = TRUE if("modify_color_value") - var/new_color = input(usr, "Pick new filter color", "Filteriffic Colors!") as color|null + var/new_color = input(usr, "Pick new filter color", "Filterrific Colors!") as color|null if(new_color) target.transition_filter(params["name"], list("color" = new_color), 4) . = TRUE @@ -68,6 +75,16 @@ if(new_icon) target.modify_filter(params["name"], list("icon" = new_icon)) . = TRUE + if("modify_transform_value") + var/list/filter_info = target.get_filter_data(params["name"]) + if (!filter_info) + return + var/matrix/new_transform = matrix(filter_info[params["field_name"]]) + if (!(params["transform_key"] in list("a", "b", "c", "d", "e", "f"))) + return + new_transform.vars[params["transform_key"]] = text2num(params["transform_value"]) + target.modify_filter(params["name"], list(params["field_name"] = new_transform)) + . = TRUE if("mass_apply") if(!check_rights_for(usr.client, R_FUN)) to_chat(usr, span_userdanger("Stay in your lane, jannie.")) diff --git a/code/modules/admin/view_variables/nobody_wants_to_learn_matrix_math.dm b/code/modules/admin/view_variables/nobody_wants_to_learn_matrix_math.dm index 4d057383284..db887d8053e 100644 --- a/code/modules/admin/view_variables/nobody_wants_to_learn_matrix_math.dm +++ b/code/modules/admin/view_variables/nobody_wants_to_learn_matrix_math.dm @@ -4,7 +4,7 @@ * * More than just a completely true statement, this datum is created as a tgui interface * allowing you to modify each vector until you know what you're doing. - * Much like filteriffic, 'nobody wants to learn matrix math' is meant for developers like you and I + * Much like filterrific, 'nobody wants to learn matrix math' is meant for developers like you and I * to implement interesting matrix transformations without the hassle if needing to know... algebra? Damn, i'm stupid. */ /datum/nobody_wants_to_learn_matrix_math diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index d9c1389c0cf..19bfebc0fe2 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -1126,8 +1126,8 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( /client/proc/open_filter_editor(atom/in_atom) if(holder) - holder.filteriffic = new /datum/filter_editor(in_atom) - holder.filteriffic.ui_interact(mob) + holder.filterrific = new /datum/filter_editor(in_atom) + holder.filterrific.ui_interact(mob) ///opens the particle editor UI for the in_atom object for this client /client/proc/open_particle_editor(atom/movable/in_atom) diff --git a/tgui/packages/tgui/interfaces/Filteriffic.jsx b/tgui/packages/tgui/interfaces/Filterrific.jsx similarity index 65% rename from tgui/packages/tgui/interfaces/Filteriffic.jsx rename to tgui/packages/tgui/interfaces/Filterrific.jsx index a82fecf8638..b1b28373853 100644 --- a/tgui/packages/tgui/interfaces/Filteriffic.jsx +++ b/tgui/packages/tgui/interfaces/Filterrific.jsx @@ -11,6 +11,7 @@ import { NoticeBox, NumberInput, Section, + Stack, } from 'tgui-core/components'; import { numberOfDecimalDigits, toFixed } from 'tgui-core/math'; @@ -193,6 +194,159 @@ const FilterOptionsEntry = (props) => { ); }; +const FilterTransformEntry = (props) => { + const { value, name, filterName } = props; + const { act } = useBackend(); + + return ( + <> + + {['a', 'b', 'c'].map((letter_key) => ( + + + {letter_key}: + + + act('modify_transform_value', { + name: filterName, + field_name: name, + transform_key: letter_key, + transform_value: value, + }) + } + /> + + ))} + + + {['d', 'e', 'f'].map((letter_key) => ( + + + {letter_key}: + + + act('modify_transform_value', { + name: filterName, + field_name: name, + transform_key: letter_key, + transform_value: value, + }) + } + /> + + ))} + + + ); +}; + +const FilterMatrixEntry = (props) => { + const { name, value, filterName, filterType } = props; + const { act } = useBackend(); + const matrix_sizes = [9, 12, 16, 20]; + const resize_matrix = (matrix, size) => { + let identity = [1, 0, 0, 0, 1, 0, 0, 0, 1]; + switch (size) { + case 12: + identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0]; + break; + case 16: + identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; + break; + case 20: + identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0]; + break; + } + if (matrix === null || matrix === undefined) return identity; + + for (let i = 0; i < Math.min(size, matrix.length); i++) { + if (matrix.length === 9) + identity[i + Math.floor(i / 3)] = matrix[i]; // Account for skipped constants + else identity[i] = matrix[i]; + } + return identity; + }; + + let matrix = value; + + if (value === null || value === undefined) { + matrix = resize_matrix(value, 9); + } + + const processed_matrix = []; + const row_width = matrix.length > 9 ? 4 : 3; + for (let i = 0; i < (matrix.length > 9 ? matrix.length / 4 : 3); i++) { + const new_row = []; + for (let j = 0; j < row_width; j++) { + new_row.push(matrix[i * row_width + j]); + } + processed_matrix.push(new_row); + } + + return ( + + `${size} elements`)} + onSelected={(option) => + matrix.length === parseInt(option.split(' ')) + ? null + : act('modify_filter_value', { + name: filterName, + new_data: { + [name]: resize_matrix(matrix, parseInt(option.split(' '))), + }, + }) + } + /> + + {processed_matrix.map((matrix_row, row_index) => ( + + + {matrix_row.map((matrix_elem, elem_index) => ( + + { + matrix[row_index * row_width + elem_index] = value; + act('transition_filter_value', { + name: filterName, + new_data: { + [name]: matrix, + }, + }); + }} + /> + + ))} + + + ))} + + + ); +}; + const FilterDataEntry = (props) => { const { name, value, hasValue, filterName, filterType } = props; @@ -204,6 +358,8 @@ const FilterDataEntry = (props) => { icon: , flags: , options: , + transform: , + matrix: , plug: 'Not Implemented', }; @@ -214,7 +370,7 @@ const FilterDataEntry = (props) => { render_source: 'string', flags: 'flags', size: 'float', - color: { default: 'color', color: 'plug' }, + color: { default: 'color', color: 'matrix' }, offset: 'float', radius: 'int', falloff: 'float', @@ -225,7 +381,7 @@ const FilterDataEntry = (props) => { repeat: 'int', space: 'options', blend_mode: 'options', - transform: 'plug', + transform: 'transform', }; let filterInputType = filterEntryMap[name]; @@ -315,7 +471,7 @@ const FilterEntry = (props) => { ); }; -export const Filteriffic = (props) => { +export const Filterrific = (props) => { const { act, data } = useBackend(); const name = data.target_name || 'Unknown Object'; const filters = data.target_filter_data || {}; @@ -325,7 +481,7 @@ export const Filteriffic = (props) => { const [hiddenSecret, setHiddenSecret] = useState(false); return ( - + DO NOT MESS WITH EXISTING FILTERS IF YOU DO NOT KNOW THE CONSEQUENCES.