diff --git a/ambient.d.ts b/ambient.d.ts index 4d24f03..23ff1b1 100644 --- a/ambient.d.ts +++ b/ambient.d.ts @@ -20,6 +20,7 @@ declare namespace LILY { zones: AssetGroupName[] craft: CraftingItem rgb: string[] + speed: number timeout: NodeJS.Timeout | undefined set_rgb(item: Item, index: number): boolean next_rgb(): boolean @@ -28,6 +29,7 @@ declare namespace LILY { stop(): boolean dim(): boolean clear(): boolean + set_speed(seconds: number): void check(zone: AssetGroupName): Item | undefined get item(): Item | undefined } diff --git a/lily.user.js b/lily.user.js index 6e63553..00fbf71 100644 --- a/lily.user.js +++ b/lily.user.js @@ -34,36 +34,55 @@ get item() {return U.ass(W.Player, p => U.ass(Belt.users[p.MemberNumber ?? -1], u => U.ass(W.InventoryGet(p, u.zone), i => i.Craft?.Name === u.name ? i : $)))}, get enabled() {return U.with(Box.item, i => i !== $ && U.with(i?.Property?.OverridePriority, op => typeof op !== 'object' || !Object.hasOwn(op, 'Light') || (op['Light'] ?? 1) > 0))}, // TODO check if the light is above the box } - /** @type {LILY.Eyes} */ const Eyes = {timeout: $, zones: ['ItemHead', 'Mask'], + /** @type {LILY.Eyes} */ const Eyes = {timeout: $, speed: 1500, zones: ['Eyes', 'Eyes2'], rgb: [ - '#990000', '#990f00', '#991f00', '#992e00', '#993d00', '#994d00', '#995c00', '#996b00', '#997a00', '#998a00', - '#999900', '#8a9900', '#7a9900', '#6b9900', '#5c9900', '#4d9900', '#3d9900', '#2e9900', '#1f9900', '#0f9900', - '#009900', '#00990f', '#00991f', '#00992e', '#00993d', '#00994d', '#00995c', '#00996b', '#00997a', '#00998a', - '#009999', '#008a99', '#007a99', '#006b99', '#005c99', '#004d99', '#003d99', '#002e99', '#001f99', '#000f99', - '#000099', '#0f0099', '#1f0099', '#2e0099', '#3d0099', '#4d0099', '#5c0099', '#6b0099', '#7a0099', '#8a0099', - '#990099', '#99008a', '#99007a', '#99006b', '#99005c', '#99004d', '#99003d', '#99002e', '#99001f', '#99000f', + '#ff4d4d', '#ff714d', '#ff944d', '#ffb84d', '#ffe04d', '#e4ff4d', '#c0ff4d', '#9cff4d', '#78ff4d', '#55ff4d', + '#4dff62', '#4dff85', '#4dffa8', '#4dffcc', '#4dfff0', '#4ddcff', '#4db8ff', '#4d94ff', '#4d70ff', '#4d4dff', + '#704dff', '#944dff', '#b84dff', '#dc4dff', '#ff4df0', '#ff4dcc', '#ff4da8', '#ff4d85', '#ff4d62', '#ff4d4d', + '#ff6a4d', '#ff874d', '#ffa44d', '#ffc14d', '#ffde4d', '#e3ff4d', '#c6ff4d', '#a9ff4d', '#8cff4d', '#6fff4d', + '#4dff4d', '#4dff6f', '#4dff8c', '#4dffaa', '#4dffc7', '#4dffe4', '#4dffff', '#4ddcff', '#4dbfff', '#4da3ff', + '#4d86ff', '#4d6aff', '#4d4dff', '#6a4dff', '#864dff', '#a34dff', '#bf4dff', '#dc4dff', '#ff4dff', '#ff4ddc', + '#ff4dbf', '#ff4da3', '#ff4d86', '#ff4d6a', '#ff4d4d', '#ff6e4d', '#ff914d', '#ffb44d', '#ffd84d', '#f1ff4d', + '#ceff4d', '#abff4d', '#88ff4d', '#65ff4d', '#4dff5b', '#4dff7e', '#4dffa1', '#4dffc4', '#4dffe7', '#4dffff', + '#4dcfff', '#4dacff', '#4d89ff', '#4d66ff', '#4d4dff', '#664dff', '#894dff', '#ac4dff', '#cf4dff', '#f24dff', + '#ff4dce', '#ff4dab', '#ff4d88', '#ff4d65', '#ff4d4d', '#ff774d', '#ff9f4d', '#ffc74d', '#fff04d', '#d4ff4d', + '#acff4d', '#84ff4d', '#5cff4d', '#4dff74', '#4dff9c', '#4dffc4', '#4dffee', '#4dbdff', '#4d95ff', '#4d6dff', + '#6d4dff', '#954dff', '#bd4dff', '#e54dff', '#ff4dd5', '#ff4dad', '#ff4d85', '#ff4d5d' ], craft: {Item: 'AnimeLenses', Name: 'Akihabara souvenir', Description: 'you will never be the same uwu', Color: '#FFFFFF,Default,#FFFFFF,Default', Property: 'Thick', Lock: '', Private: true, ItemProperty: {}, Type: null, TypeRecord: null, MemberNumber: 71_240, MemberName: 'Mute'}, set_rgb: (item, n) => U.true(() => item.Color = [Eyes.rgb[n] ?? 'Default', 'Default', Eyes.rgb[n] ?? 'Default', 'Default']), next_rgb: () => Eyes.check('ItemHead') === $ && U.with(Eyes.check('Mask'), i => i !== $ && U.with(Eyes.rgb.indexOf(i.Color?.[0] ?? Eyes.rgb[0] ?? '') + 1, n => Eyes.set_rgb(i, n))), roll_rgb: () => Eyes.next_rgb() && void W.ChatRoomCharacterItemUpdate(W.Player, 'Mask'), - start: () => Eyes.check('Mask') !== $ && Eyes.timeout === $ && Boolean(Eyes.timeout = setInterval(Eyes.roll_rgb, 1000)), + start: () => Eyes.check('Mask') !== $ && Eyes.timeout === $ && Boolean(Eyes.timeout = setInterval(Eyes.roll_rgb, Eyes.speed)), stop: () => Eyes.check('Mask') !== $ && Eyes.timeout !== $ && U.true(() => Eyes.timeout = void clearInterval(Eyes.timeout)), + set_speed(seconds) {const ms = Math.max(100, seconds * 1000); Eyes.speed = ms; if (Eyes.timeout !== $) {clearInterval(Eyes.timeout); Eyes.timeout = setInterval(Eyes.roll_rgb, Eyes.speed);}}, dim: () => U.send(() => Eyes.check('ItemHead') === $ && U.true(() => W.InventoryWear(W.Player, 'AnimeLenses', 'ItemHead', ['#FFFFFF', 'Default', '#FFFFFF', 'Default'], $, 71_240, Eyes.craft))), clear: () => U.send(() => Eyes.check('ItemHead') !== $ && U.true(() => void W.InventoryRemove(W.Player, 'ItemHead'))), check: zone => U.with(Eyes.item, item => item?.Asset.Group.Name === zone ? item : $), get item() {return Eyes.zones.map(z => W.InventoryGet(W.Player, z)).find(item => item?.Asset.Name === 'AnimeLenses') ?? $}, } - /** @type {LILY.Belt} */ const Belt = {admins: [71_240, 67_994], + /** @type {LILY.Belt} */ const Belt = {admins: [71_240, 67_994, 21_504], users: { 119_643: {zone: 'ItemNeckAccessories', name: 'Lily\'s voicebox'}, //154_662: '?hell if I remember?', 62_808: {zone: 'ItemNeck', name: 'CKO voicebox'}, }, cli: {'#LILY': { - status: _ => '200 OK', + status: _ => '200 OK[User is currently operating in her own Beta Branch]', box: {on: Box.on, off: Box.off}, - eyes: {start: Eyes.start, stop: Eyes.stop, dim: Eyes.dim, clear: Eyes.clear}, + version: _ => `LILY version ${GM_info?.script?.version ?? 'unknown'}`, + eyes: { + start: Eyes.start, + stop: Eyes.stop, + dim: Eyes.dim, + clear: Eyes.clear, + speed(s) { + const seconds = parseFloat(s); + if (isNaN(seconds) || seconds <= 0) return 'invalid speed'; + Eyes.set_speed(seconds); + return `Eye speed set to ${seconds}s`; + } + }, }}, /** @type {LILY.Belt['is_cb']} */ is_cb: s => typeof s === 'function', run(tokens) { /** @type {string | undefined} */ let t, /** @type {LILY.Commands | LILY.CommandCB} */ cmd = Belt.cli