RPTools / maptool

Virtual Tabletop for playing roleplaying games with remote players or face to face.
http://rptools.net
GNU Affero General Public License v3.0
787 stars 259 forks source link

[Feature]: Add new MT Table functions to improve access to, and searching of, all table entries #4859

Open Baaaaaz opened 2 months ago

Baaaaaz commented 2 months ago

Describe the Problem

  1. Unable to search a MT table by the contents of the Value column. e.g. if I store an Image (asset) in a table entry along with a name (in the corresponding Value column) I cannot easily nor reliably find this image again solely by the name in MT script.

  2. Not assured to get all table entries comprehensively from a table via MT Script (well without first relying on careful data entry, scripting, gap/deduplication handling, and some other assumptions).

The Solution you'd like

To make MT Tables a bit more user friendly for storing and retrieving data I'd like:

A. a new function: getMatchingTableEntries(name, pattern). Similar to getTableEntry() but instead of taking a roll argument, takes a regex pattern to enable searching the contents of the Value column in the specified table, returning a json ARRAY of OBJECTS of raw table data of entries where the Value column's contents matches the pattern, or an empty ARRAY [] where there are no matches.

B. a new function: tableMatchingImages(name, pattern [, size]). Similar to tableImage(name, row [, size]) combined with point A above, but returns a JSON array of image asset values.

C. a new function: getTableEntries(name) to return a json ARRAY of OBJECTS of raw table data for all table entries for the specified table. i.e. similar to getTableEntry() but returns all tables entries, or an empty ARRAY if the table has no entries. Being able to get all entry data from a table natively may also enable other great things such as scripted re-sorting of entries, generating smaller filtered tables, creating merged tables, error checking, picking from a relevant selection of images when creating a token, etc.

Arguably B could be achieved via A with one or two extra MT scripting steps. Arguably C could be achieved via A if the pattern could be set to match all values.

Alternatives that you've considered.

  1. Creating a separate searchable index of row keys, storing it somewhere, and then searching this index to find the roll number to get the table entry from the table. e.g. Aliasmask's imageDB stores this index in the same table at roll = 0. However, creating and maintaining such an index when adding or removing table rows is problematic as it is not natively integrated with the table itself and sometimes one has to make assumptions such as row roll values incrementation and you also have to enter table data to match that assumption.

  2. Determining the table range (via getTableRoll() and then iterating through each row using getTableEntry() (assuming that the table roll range is representative of the actual row rolls however - which it may not be as it can be set independently of the actual entry roll ranges), and then finding any value matches on each iteration but also accounting for any gaps or duplicate results.

  3. Waiting for... https://github.com/RPTools/maptool/issues/103

Additional Context

Proposed function names based on existing getTableEntry() and getMatchingProperties().

Requested changes should not break existing table functionality but extends their usefulness and perhaps makes them more intuitive for storing and retrieving text/images, and perhaps lowers any entry barrier for new campaign/framework developers by not forcing them down the json route from day 1. Also provides another option for seasoned campaign/framework developers.