@@ -64,11 +64,13 @@ interface ConfigDefinition {
6464}
6565
6666export class ConfigClass {
67+ datapack : Datapack ;
6768 datapack_id : string ;
6869 file : { config ?: ConfigDefinition } ;
6970 widgets : Array < WidgetDefinition > = [ ] ;
7071
7172 constructor ( datapack : Datapack ) {
73+ this . datapack = datapack ;
7274 this . datapack_id = datapack . id ;
7375 this . file = datapack . rawConfig as { config : ConfigDefinition } ;
7476 this . widgets = this . file . config ?. widgets || [ ] ;
@@ -194,3 +196,161 @@ function updateDisplayedValue(event: Event) {
194196 valueElement . innerText = valueToDisplay . toString ( ) + suffix ;
195197 }
196198}
199+
200+ ////////// ACCESSOR LOGIC //////////
201+
202+ type Accessor = {
203+ method : string ;
204+ file_path : string ;
205+ value_path : string ;
206+ } ;
207+
208+ const AccessorMethods : ReadonlyArray < string > = [
209+ "multiply" ,
210+ "divide" ,
211+ "add" ,
212+ "subtract" ,
213+ "set" ,
214+ "multiply_int" ,
215+ "divide_int" ,
216+ "add_int" ,
217+ "subtract_int" ,
218+ "remove" ,
219+ "pop"
220+ ] ;
221+
222+ ///// ACCESSOR FUNCTIONS /////
223+
224+ function readAccessors ( datapack : Datapack , accessor_list : Array < object > ) {
225+ let refined_accessor_list = accessor_list . map (
226+ ( accessor ) => {
227+ return asAccessor ( datapack , accessor ) ;
228+ }
229+ ) as Array < Accessor | null > ;
230+
231+ refined_accessor_list = refined_accessor_list . filter (
232+ ( accessor ) => accessor != null ) ;
233+
234+ return refined_accessor_list as Array < Accessor > ;
235+ }
236+
237+ function asAccessor ( datapack : Datapack , accessor : object ) {
238+ if ( accessorIsValid ( datapack , accessor ) ) {
239+ return accessor as Accessor ;
240+ }
241+ else return null ;
242+ }
243+
244+ function accessorIsValid ( datapack : Datapack , accessor : object ) {
245+ if ( "method" in accessor && "file_path" in accessor && "value_path" in accessor ) {
246+ if ( AccessorMethods . includes ( accessor [ "method" ] as string ) ) {
247+ const files = findMatchingFiles ( datapack , accessor [ "file_path" ] as string ) ;
248+ if ( files . length != 0 ) {
249+ return true ;
250+ }
251+ }
252+ }
253+ return false ;
254+ }
255+
256+ function findMatchingFiles ( datapack : Datapack , file_path : string ) {
257+ let file_names : Array < string > = [ ] ;
258+
259+ for ( const key in datapack . zip . files ) {
260+ if ( Object . prototype . hasOwnProperty . call ( datapack . zip . files , key ) ) {
261+ if ( key . includes ( file_path ) ) {
262+ file_names . push ( key ) ;
263+ }
264+ }
265+ }
266+ return file_names ;
267+ }
268+
269+ ////////// TRANSFORMER LOGIC //////////
270+
271+ type Transformer = string | number | ifElseTransformer | mathTransformerTwoArgs | mathTransformerSingleArg ;
272+
273+ type mathTransformerTwoArgs = {
274+ function : "add" | "multiply" ;
275+ argument : Transformer ;
276+ argument1 : Transformer ;
277+ }
278+
279+ type mathTransformerSingleArg = {
280+ function : "int" | "square" | "square_root" ;
281+ argument : Transformer ;
282+ }
283+
284+ type ifElseTransformer = {
285+ function : "if_else" ;
286+ argument : Transformer ;
287+ argument1 : Transformer ;
288+ operator : "==" | ">=" | ">" ;
289+ true : Transformer ;
290+ false : Transformer ;
291+ }
292+
293+ function processTransformer ( method_input : number , slot_values : { [ key : string ] : number } , transformer : Transformer ) : string | number {
294+
295+ if ( typeof transformer === "number" ) {
296+ return transformer as number ;
297+ }
298+
299+ else if ( typeof transformer === "string" ) {
300+ if ( transformer . charAt ( 0 ) == "$" || transformer == "input" ) {
301+ if ( transformer == "$input" || transformer == "$in" || transformer == "input" ) {
302+ return method_input ;
303+ }
304+ else {
305+ const variable = transformer . slice ( 1 ) ;
306+ if ( variable in slot_values ) {
307+ return slot_values [ variable ] ;
308+ }
309+ }
310+ }
311+ return transformer as string ;
312+ }
313+
314+ else {
315+ switch ( transformer . function ) {
316+ // Math transformers with two arguments
317+ case "add" :
318+ return ( processTransformer ( method_input , slot_values , transformer . argument ) as number ) + ( processTransformer ( method_input , slot_values , transformer . argument1 ) as number ) ;
319+
320+ case "multiply" :
321+ return ( processTransformer ( method_input , slot_values , transformer . argument ) as number ) * ( processTransformer ( method_input , slot_values , transformer . argument1 ) as number ) ;
322+
323+ // Math transformers with a single argument
324+ case "int" :
325+ return Math . round ( processTransformer ( method_input , slot_values , transformer . argument ) as number ) ;
326+
327+ case "square_root" :
328+ return Math . sqrt ( processTransformer ( method_input , slot_values , transformer . argument ) as number ) ;
329+
330+ case "square" :
331+ return Math . pow ( processTransformer ( method_input , slot_values , transformer . argument ) as number , 2 ) ;
332+
333+ // if-else transformer
334+ case "if_else" :
335+ if ( transformer . operator == "==" ) {
336+ if ( transformer . argument == transformer . argument1 ) return processTransformer ( method_input , slot_values , transformer . true ) ;
337+ else return processTransformer ( method_input , slot_values , transformer . false ) ;
338+ }
339+
340+ else if ( transformer . operator == ">=" ) {
341+ if ( transformer . argument >= transformer . argument1 ) return processTransformer ( method_input , slot_values , transformer . true ) ;
342+ else return processTransformer ( method_input , slot_values , transformer . false ) ;
343+ }
344+
345+ else if ( transformer . operator == ">" ) {
346+ if ( transformer . argument > transformer . argument1 ) return processTransformer ( method_input , slot_values , transformer . true ) ;
347+ else return processTransformer ( method_input , slot_values , transformer . false ) ;
348+ }
349+
350+ throw new Error ( "Couldn't process if-else transformer" ) ;
351+
352+ default :
353+ throw new Error ( "Couldn't process unknown transformer" ) ;
354+ }
355+ }
356+ }
0 commit comments