import { show } from 'fp-ts' import * as uuid from 'uuid' interface _Filter { id: string name: string enabled: boolean rule: FilterRule } export function defaultLeaf(): FilterLeaf { return { type: 'leaf', id: uuid.v4(), name: '', enabled: true, rule: {}, show: true, } } export function defaultGroup(): FilterGroup { return { type: 'group', id: uuid.v4(), name: '', enabled: true, rule: {}, filters: [], } } export interface FilterConfig { filters: Filter[] } export type FilterLeaf = _Filter & { type: 'leaf' show: boolean } export type FilterGroup = _Filter & { type: 'group' filters: Filter[] } export type Filter = FilterLeaf | FilterGroup export type ItemClass = any // Replace with actual type definition export type ItemBaseType = any // Replace with actual type definition export type Op = any // Replace with actual type definition export type Level = RangedNumber<1, 100> // Replace with actual type definition export type ItemRarity = string // Replace with actual type definition export type GameColor = any // Replace with actual type definition export type MinimapIconShape = any // Replace with actual type definition export interface RangedNumber { value: number min: T max: U } export interface Color { r: number g: number b: number } export interface FilterRule { class?: string[] // base_type?: string[] // area_level?: [string, number] // drop_level?: [string, number] // item_level?: [string, number] // rarity?: [string, string] // sockets?: [string, number] // quality?: [string, number] // stack_size?: [string, number] // // waystones waystone_tier?: [string, number] // // effects set_font_size?: number // set_text_color?: Color // set_border_color?: Color // set_background_color?: Color // play_alert_sound?: [number, number] // play_effect?: string // minimap_icon?: [number, string, string] // } export interface FilterNode { key: string parent?: FilterNode data: Filter children?: FilterNode[] } export function toLines(rule: FilterRule): string[] { let r: string[] = [] if (rule.class && rule.class.length > 0) { r.push(`Class ${rule.class.map((c) => `"${c}"`).join(' ')}`) } if (rule.base_type && rule.base_type.length > 0) { r.push(`BaseType ${rule.base_type.map((c) => `"${c}"`).join(' ')}`) } if (rule.rarity) { r.push(`Rarity ${rule.rarity[0]} ${rule.rarity[1]}`) } if (rule.sockets) { r.push(`Sockets ${rule.sockets[0]} ${rule.sockets[1]}`) } if (rule.quality) { r.push(`Quality ${rule.quality[0]} ${rule.quality[1]}`) } if (rule.stack_size) { r.push(`StackSize ${rule.stack_size[0]} ${rule.stack_size[1]}`) } if (rule.area_level) { r.push(`AreaLevel ${rule.area_level[0]} ${rule.area_level[1]}`) } if (rule.drop_level) { r.push(`DropLevel ${rule.drop_level[0]} ${rule.drop_level[1]}`) } if (rule.item_level) { r.push(`ItemLevel ${rule.item_level[0]} ${rule.item_level[1]}`) } if (rule.waystone_tier) { r.push(`WaystoneTier ${rule.waystone_tier[0]} ${rule.waystone_tier[1]}`) } if (rule.set_font_size) { r.push(`SetFontSize ${rule.set_font_size}`) } if (rule.set_text_color) { r.push(`SetTextColor ${formatColor(rule.set_text_color)}`) } if (rule.set_background_color) { r.push(`SetBackgroundColor ${formatColor(rule.set_background_color)}`) } if (rule.set_border_color) { r.push(`SetBorderColor ${formatColor(rule.set_border_color)}`) } if (rule.play_alert_sound) { r.push(`PlayAlertSound ${rule.play_alert_sound[0]} ${rule.play_alert_sound[1]}`) } if (rule.minimap_icon) { r.push(`MinimapIcon ${rule.minimap_icon[0]} ${rule.minimap_icon[1]} ${rule.minimap_icon[2]}`) } if (rule.play_effect) { r.push(`PlayEffect ${rule.play_effect}`) } return r } function formatColor(color: Color) { return `${color.r} ${color.g} ${color.b}` } export function generateFilterText(filters: Filter[]): string { let flat = flatten(filters) return flat .map((f) => { let lines = toLines(f.rule) if (lines.length < 1) { return undefined } lines.unshift(f.show ? 'Show' : 'Hide') return lines.join('\n') }) .filter((s) => s != undefined) .reverse() .join('\n\n') } function flatten(filters: Filter[]): Omit[] { return filters.flatMap((f) => { if (!f.enabled) { return [] } if (f.type === 'group') { let children = flatten(f.filters) return children.map((c) => { let rule = c.rule as any Object.entries(f.rule).forEach(([k, v]) => { if (v != undefined) { rule[k] = v } }) return { show: c.show, rule, } }) } else { return [{ show: f.show, rule: f.rule }] } }) }