diff --git a/demos/stefan/untitled-board-game/ubg-card.js b/demos/stefan/untitled-board-game/ubg-card.js
index ddedd001b..648376c62 100644
--- a/demos/stefan/untitled-board-game/ubg-card.js
+++ b/demos/stefan/untitled-board-game/ubg-card.js
@@ -39,15 +39,6 @@ export default class Card {
}
}
-// getType() {
-// return this.versions.last.type;
-// }
-
-// setType(type) {
-// this.ensureUnprintedVersion();
-// this.versions.last.type = type;
-// }
-
getTypes() {
const type = this.versions.last.type;
diff --git a/src/components/widgets/ubg-card.js b/src/components/widgets/ubg-card.js
index fdc0150f9..a36db2d69 100644
--- a/src/components/widgets/ubg-card.js
+++ b/src/components/widgets/ubg-card.js
@@ -52,7 +52,13 @@ class FileCache {
this.files = {};
}
- dirtyFolder(path) {}
+ dirtyFolder(folderPath) {
+ for (const filePath in this.files) {
+ if (filePath.startsWith(folderPath)) {
+ delete this.files[filePath];
+ }
+ }
+ }
getFile(path, callback) {
if (this.files[path]) {
@@ -89,7 +95,9 @@ export default class UbgCard extends Morph {
/*MD ## Build MD*/
async fetchAssetsInfo() {
- return (await this.assetsFolder.fetchStats()).contents;
+ return globalThis.__ubg_file_cache__.getFile(this.assetsFolder, async url => {
+ return (await url.fetchStats()).contents;
+ })
}
/*MD ## Extract Card Info MD*/
@@ -245,12 +253,14 @@ background: ${color};
}
async loadImage(filePath) {
- return new Promise((resolve, reject) => {
- const image = new Image();
- image.addEventListener('load', resolve);
- image.addEventListener('error', reject);
- image.src = filePath;
- });
+ return globalThis.__ubg_file_cache__.getFile(filePath, filePath => {
+ return new Promise((resolve, reject) => {
+ const image = new Image();
+ image.addEventListener('load', resolve);
+ image.addEventListener('error', reject);
+ image.src = filePath;
+ });
+ })
}
/*MD ## Rendering MD*/
diff --git a/src/components/widgets/ubg-cards.js b/src/components/widgets/ubg-cards.js
index 33656fea1..e92529c8f 100644
--- a/src/components/widgets/ubg-cards.js
+++ b/src/components/widgets/ubg-cards.js
@@ -4,7 +4,6 @@ import Morph from 'src/components/widgets/lively-morph.js';
import ContextMenu from 'src/client/contextmenu.js';
import "src/external/pdf.js";
import { shake } from 'utils';
-import { Point } from 'src/client/graphics.js'
import OpenAI from "demos/openai/openai.js"
@@ -12,7 +11,7 @@ import d3 from 'https://d3js.org/d3.v7.min.js'
import { uuid, without, getTempKeyFor, getObjectFor, flatMap, listAsDragImage } from 'utils';
-import paper from 'src/client/paperjs-wrapper.js'
+// import paper from 'src/client/paperjs-wrapper.js'
import 'https://lively-kernel.org/lively4/ubg-assets/load-assets.js';
import { querySelectorAllDeep } from 'src/external/querySelectorDeep/querySelectorDeep.js';
@@ -31,245 +30,128 @@ function identity(value) {
return value;
}
-const fire = ;
-const water = ;
-const earth = ;
-const wind = ;
-const gray = ;
-const question = ;
-
-class PathDataScaleCache {
- static getPathData(element, size = lively.pt(10, 10)) {
- if (!this.cache) {
- this.cache = {}
- }
+// const fire = ;
+// const water = ;
+// const earth = ;
+// const wind = ;
+// const gray = ;
+// const question = ;
+
+// class PathDataScaleCache {
+// static getPathData(element, size = lively.pt(10, 10)) {
+// if (!this.cache) {
+// this.cache = {}
+// }
- const key = `${element}-${size.x}-${size.y}`;
- if (!this.cache[key]) {
- // lively.notify(`${element}-${size.x}-${size.y}`, 'cache miss')
- this.cache[key] = this._scalePathData(element, size)
- }
+// const key = `${element}-${size.x}-${size.y}`;
+// if (!this.cache[key]) {
+// // lively.notify(`${element}-${size.x}-${size.y}`, 'cache miss')
+// this.cache[key] = this._scalePathData(element, size)
+// }
- return this.cache[key]
- }
-
- static _scalePathData(element, size) {
- const { glyph } = forElement(element);
- const path = new paper.Path(glyph.getAttribute('d'));
-
- path.scale(1, -1);
-
- const margin = size.scaleBy(0.1);
- const boundingRect = new paper.Path.Rectangle({
- point: margin.toPair(),
- size: size.subPt(margin.scaleBy(2)).toPair()
- });
- path.fitBounds(boundingRect.bounds);
-
- return path.pathData;
- }
-}
-
-function tenTenPathData(element) {
- return PathDataScaleCache.getPathData(element, lively.pt(10, 10));
-}
-
-const elementInfo = {
- fire: {
- name: 'fire',
- faIcon: 'book',
- glyph: fire,
- get pathData() { return tenTenPathData('fire') },
- pathWidth: parseInt(fire.getAttribute('horiz-adv-x')),
- pathHeight: parseInt(fire.getAttribute('vert-adv-y')),
- fill: '#ffbbbb',
- stroke: '#ff0000',
- others: ['water', 'earth', 'wind']
- },
- water: {
- name: 'water',
- faIcon: 'droplet',
- glyph: water,
- get pathData() { return tenTenPathData('water') },
- pathWidth: parseInt(water.getAttribute('horiz-adv-x')),
- pathHeight: parseInt(water.getAttribute('vert-adv-y')),
- fill: '#8888ff',
- stroke: '#0000ff',
- others: ['fire', 'earth', 'wind']
- },
- earth: {
- name: 'earth',
- faIcon: 'mountain',
- glyph: earth,
- get pathData() { return tenTenPathData('earth') },
- pathWidth: parseInt(earth.getAttribute('horiz-adv-x')),
- pathHeight: parseInt(earth.getAttribute('vert-adv-y')),
- fill: 'rgb(255, 255, 183)',
- stroke: '#ffd400',
- others: ['fire', 'water', 'wind']
- },
- wind: {
- name: 'wind',
- faIcon: 'cloud',
- glyph: wind,
- get pathData() { return tenTenPathData('wind') },
- pathWidth: parseInt(wind.getAttribute('horiz-adv-x')),
- pathHeight: parseInt(wind.getAttribute('vert-adv-y')),
- fill: '#bbffbb',
- stroke: '#00ff00',
- others: ['fire', 'water', 'earth']
- },
- gray: {
- name: 'gray',
- faIcon: 'circle',
- glyph: gray,
- get pathData() { return tenTenPathData('gray') },
- pathWidth: parseInt(gray.getAttribute('horiz-adv-x')),
- pathHeight: parseInt(gray.getAttribute('vert-adv-y')),
- fill: '#dddddd',
- stroke: '#5A5A5A',
- others: ['gray', 'gray', 'gray']
- },
- unknown: {
- name: 'unknown',
- faIcon: 'question',
- glyph: question,
- get pathData() { return tenTenPathData('question') },
- pathWidth: parseInt(question.getAttribute('horiz-adv-x')),
- pathHeight: parseInt(question.getAttribute('vert-adv-y')),
- fill: 'pink',
- stroke: 'violet',
- others: ['question', 'question', 'question']
- }
-};
-
-function forElement(element) {
- const cleanElement = (element || '').toLowerCase();
- return elementInfo[cleanElement] || elementInfo.unknown;
-}
-
-class SVG {
-
- static inlineSVG(children, bounds = lively.rect(0, 0, 10, 10), attrs = '', style = '') {
- return ``;
- }
-
- /*MD ## Basic Shapes MD*/
- static circleRing(center, innerRadius, outerRadius, attrs) {
- return ``
- }
-
- static circle(center, radius, attrs) {
- return ``
- }
-
- /*MD ## Icons MD*/
- static elementGlyph(element, center, radius, attrs) {
- const pathData = PathDataScaleCache.getPathData(element, lively.pt(2 * radius, 2 * radius));
- return ``
- }
-
- static elementSymbol(element, center, radius) {
- const { name: elementName, fill, stroke } = forElement(element);
- const innerRadius = .9 * radius;
- return `${SVG.circle(center, innerRadius, `fill="${fill}"`)}
-${SVG.elementGlyph(elementName, center, innerRadius, `fill="${stroke}"`)}
- ${SVG.circleRing(center, innerRadius, radius, `fill="${stroke}"`)}`
- }
-}
-
-const castIcon = do {
- const size = 100;
- const bounds = lively.rect(0, 0, size, size)
- const innerBounds = bounds.insetBy(5);
-
- const innerRadius = innerBounds.width / 2;
- const outerCircle = SVG.circleRing(bounds.center(), innerRadius, bounds.width / 2, `fill="#7A7A7A"`);
-
- const sqrt2 = 2**.5
- const radius = innerRadius * 1 / (sqrt2 + 1);
- const distToMiddle = innerRadius * sqrt2 / (sqrt2 + 1);
- const elements = ['water', 'earth', 'fire', 'wind'];
- const mainElements = elements.map((element, i) => {
- const center = bounds.center().addPt(Point.polar(distToMiddle, Math.PI / 2 * i));
- return SVG.elementSymbol(element, center, radius)
- }).join('\n');
-
- SVG.inlineSVG(`${outerCircle}
-${mainElements}`, bounds);
-}
-
-
-function previewSVG(svg) {
- const hedronTemp = document.getElementById(svg.id)
- if (hedronTemp) {
- hedronTemp.remove()
- }
- document.body.insertAdjacentHTML("afterbegin", svg.outerHTML)
-}
-
-
-function rectToViewBox(rect) {
- return `${rect.x} ${rect.y} ${rect.width} ${rect.height}`
-}
-
-
-const CARD_COST_VIEWBOX = lively.rect(0, 0, 376, 326);
-const cardCostTwoSVG = do {
- const C_OUTER = 'rgb(243, 243, 243)'
- const C_INNER = 'rgb(129, 129, 129)'
- const C_TOP = 'rgb(162, 165, 168)'
- const C_IMAGE = 'rgb(148, 147, 152)'
- const C_BOTTOM = C_TOP;
+// return this.cache[key]
+// }
- const svg = (
-);
-svg
-};
-
-// previewSVG(cardCostTwoSVG)
-
-class FileCache {
-
- constructor() {
- this.files = {};
- }
-
- dirtyFolder(path) {}
-
- getFile(path, callback) {
- if (this.files[path]) {
- // lively.notify('cache hit')
- } else {
- // lively.notify('cache miss')
- this.files[path] = callback(path);
- }
-
- return this.files[path];
- }
-
-}
-
-if (globalThis.__ubg_file_cache__) {
- globalThis.__ubg_file_cache__.migrateTo(FileCache);
-} else {
- globalThis.__ubg_file_cache__ = new FileCache();
-}
+// static _scalePathData(element, size) {
+// const { glyph } = forElement(element);
+// const path = new paper.Path(glyph.getAttribute('d'));
+
+// path.scale(1, -1);
+
+// const margin = size.scaleBy(0.1);
+// const boundingRect = new paper.Path.Rectangle({
+// point: margin.toPair(),
+// size: size.subPt(margin.scaleBy(2)).toPair()
+// });
+// path.fitBounds(boundingRect.bounds);
+
+// return path.pathData;
+// }
+// }
+
+// function tenTenPathData(element) {
+// return PathDataScaleCache.getPathData(element, lively.pt(10, 10));
+// }
+
+// const elementInfo = {
+// fire: {
+// name: 'fire',
+// faIcon: 'book',
+// glyph: fire,
+// get pathData() { return tenTenPathData('fire') },
+// pathWidth: parseInt(fire.getAttribute('horiz-adv-x')),
+// pathHeight: parseInt(fire.getAttribute('vert-adv-y')),
+// fill: '#ffbbbb',
+// stroke: '#ff0000',
+// others: ['water', 'earth', 'wind']
+// },
+// water: {
+// name: 'water',
+// faIcon: 'droplet',
+// glyph: water,
+// get pathData() { return tenTenPathData('water') },
+// pathWidth: parseInt(water.getAttribute('horiz-adv-x')),
+// pathHeight: parseInt(water.getAttribute('vert-adv-y')),
+// fill: '#8888ff',
+// stroke: '#0000ff',
+// others: ['fire', 'earth', 'wind']
+// },
+// earth: {
+// name: 'earth',
+// faIcon: 'mountain',
+// glyph: earth,
+// get pathData() { return tenTenPathData('earth') },
+// pathWidth: parseInt(earth.getAttribute('horiz-adv-x')),
+// pathHeight: parseInt(earth.getAttribute('vert-adv-y')),
+// fill: 'rgb(255, 255, 183)',
+// stroke: '#ffd400',
+// others: ['fire', 'water', 'wind']
+// },
+// wind: {
+// name: 'wind',
+// faIcon: 'cloud',
+// glyph: wind,
+// get pathData() { return tenTenPathData('wind') },
+// pathWidth: parseInt(wind.getAttribute('horiz-adv-x')),
+// pathHeight: parseInt(wind.getAttribute('vert-adv-y')),
+// fill: '#bbffbb',
+// stroke: '#00ff00',
+// others: ['fire', 'water', 'earth']
+// },
+// gray: {
+// name: 'gray',
+// faIcon: 'circle',
+// glyph: gray,
+// get pathData() { return tenTenPathData('gray') },
+// pathWidth: parseInt(gray.getAttribute('horiz-adv-x')),
+// pathHeight: parseInt(gray.getAttribute('vert-adv-y')),
+// fill: '#dddddd',
+// stroke: '#5A5A5A',
+// others: ['gray', 'gray', 'gray']
+// },
+// unknown: {
+// name: 'unknown',
+// faIcon: 'question',
+// glyph: question,
+// get pathData() { return tenTenPathData('question') },
+// pathWidth: parseInt(question.getAttribute('horiz-adv-x')),
+// pathHeight: parseInt(question.getAttribute('vert-adv-y')),
+// fill: 'pink',
+// stroke: 'violet',
+// others: ['question', 'question', 'question']
+// }
+// };
+
+// function forElement(element) {
+// const cleanElement = (element || '').toLowerCase();
+// return elementInfo[cleanElement] || elementInfo.unknown;
+// }
const SORT_BY = {
ID: 'id',
NAME: 'name'
};
-const OUTSIDE_BORDER_ROUNDING = lively.pt(3, 3)
-
export default class Cards extends Morph {
async initialize() {
this.setAttribute("exportparts", 'danger');
@@ -379,7 +261,7 @@ export default class Cards extends Morph {
return function filterFunction(card) {
const id = card.getId();
const name = card.getName();
- const cardType = card.getType()
+ const cardType = card.getTypes()
const element = card.getElement();
const cost = card.getCost();
const text = card.getText();
@@ -1239,7 +1121,7 @@ export default class Cards extends Morph {
if (that && that.localName === 'lively-code-mirror' && document.contains(that)) {
lively.showElement(that)
- const matches = that.value.matchAll(/^([^0-9]+)?\s([0-9]+)?\s?([a-zA-Z ]+)?\s?(?:\(([0-9,]+)(\+?\-?\*?)\))?(?:\s?([0-9*+-]+))?\.\s(.*)?$/gmi);
+ const matches = that.value.matchAll(/^([^0-9]+)?\s([0-9]+)?\s?((?:[a-zA-Z]+\s)*[a-zA-Z]+)?\s?(?:\(([0-9,]+)(\+?\-?\*?)\))?(?:\s?([0-9*+-]+))?\.\s(.*)?$/gmi);
const newCards = [...matches].map(match => {
const card = new Card();
@@ -1257,13 +1139,27 @@ export default class Cards extends Morph {
const typesAndElements = match[3];
if (typesAndElements) {
- let type = ''
+ const types = []
let element;
match[3].split(' ').forEach(te => {
if (!te) {
return;
}
+ if (['fire', 'water', 'earth', 'wind', 'gray', 'dark', 'void'].includes(te.toLowerCase())) {
+ if (!element) {
+ element = te
+ } else if (Array.isArray(element)) {
+ element.push(te)
+ } else {
+ element = [element, te]
+ }
+
+ return
+ }
+
+ // not an element, so it is a type
+ types.push(te)
// Transmutation & Transformation
// Flux, Shift, Metamorph
@@ -1287,23 +1183,10 @@ export default class Cards extends Morph {
// Hierarchies & Secret Orders
// Order, Guild, Circle
-
- if (['gadget', 'character', 'spell'].includes(te.toLowerCase())) {
- type += te
- return
- }
-
- if (!element) {
- element = te
- } else if (Array.isArray(element)) {
- element.push(te)
- } else {
- element = [element, te]
- }
})
- if (type) {
- card.setType(type)
+ if (types.length > 0) {
+ card.setTypes(types)
}
if (element) {
@@ -1593,10 +1476,11 @@ export default class Cards extends Morph {
evt.preventDefault();
const menu = new ContextMenu(this, [
- ["foo", () => {
- lively.notify(123)
- }], ["bar", () => {
- lively.notify(456)
+ ["Clear Assets File Cache", () => {
+ globalThis.__ubg_file_cache__.dirtyFolder(this.assetsFolder)
+ lively.success(123)
+ }], ["...", () => {
+ lively.notify('More to come...')
}]
]);
menu.openIn(document.body, evt, this);
diff --git a/src/components/widgets/ubg-rules-text.js b/src/components/widgets/ubg-rules-text.js
index 9e79f5f24..5763c70f4 100644
--- a/src/components/widgets/ubg-rules-text.js
+++ b/src/components/widgets/ubg-rules-text.js
@@ -361,34 +361,6 @@ const cardCostTwoSVG = do {
svg
};
-
-class FileCache {
-
- constructor() {
- this.files = {};
- }
-
- dirtyFolder(path) {}
-
- getFile(path, callback) {
- if (this.files[path]) {
- // lively.notify('cache hit')
- } else {
- // lively.notify('cache miss')
- this.files[path] = callback(path);
- }
-
- return this.files[path];
- }
-
-}
-
-if (globalThis.__ubg_file_cache__) {
- globalThis.__ubg_file_cache__.migrateTo(FileCache);
-} else {
- globalThis.__ubg_file_cache__ = new FileCache();
-}
-
const VP_FILL = 'violet';
const VP_STROKE = '#9400d3'; // darkviolet
const VP_FILL_ZERO = '#ddd';