Skip to content

Commit 6f94562

Browse files
authored
Create Dimension Storage
1 parent 423d882 commit 6f94562

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/**
2+
* Storage Management
3+
* !storageconfig — Opens the configuration menu.
4+
5+
*Configuration Commands
6+
* !setbagmax [number] — Sets the max weight for the Dimension Bag.
7+
* !setsackmax [number] — Sets the max weight for the Sack.
8+
* !setholemax — Resets the Moveable Hole to unlimited weight.
9+
* !setcoins [comma-separated values] — Updates the order of coin types (e.g., !setcoins PP, GP, SP, CP).
10+
* !setcolor [color name or hex] — Changes the text color for item quantity.
11+
12+
*Storage Commands
13+
* !dimensionbag add "Bag Name" [quantity] [item] [weight] — Adds an item to a Dimension Bag.
14+
* !dimensionbag remove "Bag Name" [quantity] [item] — Removes an item from a Dimension Bag.
15+
* !sack add "Sack Name" [quantity] [item] [weight] — Adds an item to a Sack.
16+
* !sack remove "Sack Name" [quantity] [item] — Removes an item from a Sack.
17+
* !hole add "Hole Name" [quantity] [item] [weight] — Adds an item to a Moveable Hole.
18+
* !hole remove "Hole Name" [quantity] [item] — Removes an item from a Moveable Hole.
19+
*Each storage type has its own max weight (except the hole, which is unlimited).
20+
*/
21+
on('ready', () => {
22+
let CONFIG = {
23+
bagMaxWeight: 500,
24+
sackMaxWeight: 900,
25+
holeMaxWeight: Infinity,
26+
coinOrder: ['PP', 'GP', 'EP', 'SP', 'CP'],
27+
quantityColor: 'blue'
28+
};
29+
30+
const showConfigMenu = () => {
31+
let menu = `/w gm &{template:default} ` +
32+
`{{name=Storage Configuration}} ` +
33+
`{{Bag Max Weight=[${CONFIG.bagMaxWeight}](!setbagmax ?{New Max Weight})}} ` +
34+
`{{Sack Max Weight=[${CONFIG.sackMaxWeight}](!setsackmax ?{New Max Weight})}} ` +
35+
`{{Hole Max Weight=[Unlimited](!setholemax)}} ` +
36+
`{{Coin Order=[${CONFIG.coinOrder.join(', ')}](!setcoins ?{Enter Coins Separated by Commas})}} ` +
37+
`{{Quantity Color=[${CONFIG.quantityColor}](!setcolor ?{Enter Color Name or Hex})}}`;
38+
sendChat('Storage', menu);
39+
};
40+
41+
on('chat:message', (msg) => {
42+
if (msg.type !== 'api') return;
43+
44+
if (msg.content === '!storageconfig') {
45+
showConfigMenu();
46+
return;
47+
}
48+
49+
let match;
50+
if (match = msg.content.match(/^!setbagmax (\d+)$/)) {
51+
CONFIG.bagMaxWeight = parseInt(match[1], 10);
52+
} else if (match = msg.content.match(/^!setsackmax (\d+)$/)) {
53+
CONFIG.sackMaxWeight = parseInt(match[1], 10);
54+
} else if (match = msg.content.match(/^!setcoins (.+)$/)) {
55+
CONFIG.coinOrder = match[1].split(',').map(c => c.trim());
56+
} else if (match = msg.content.match(/^!setcolor (.+)$/)) {
57+
CONFIG.quantityColor = match[1];
58+
} else {
59+
return;
60+
}
61+
showConfigMenu();
62+
});
63+
64+
const getOrCreateHandout = (handoutName) => {
65+
let handout = findObjs({ type: 'handout', name: handoutName })[0];
66+
if (!handout) {
67+
handout = createObj('handout', {
68+
name: handoutName,
69+
inplayerjournals: 'all',
70+
notes: '<b>Total Weight: 0 lbs</b><br><br>'
71+
});
72+
}
73+
return handout;
74+
};
75+
76+
const parseHandoutContent = (notes) => {
77+
let items = {};
78+
(notes || '').split('<br>').forEach(line => {
79+
let match = line.match(/<b>(.+?)<\/b>: <span style='color:(.*?)'>(\d+)<\/span> \((.*?) lbs\)/);
80+
if (match) {
81+
let [, item, , quantity, weight] = match;
82+
items[item] = { quantity: parseInt(quantity, 10), weight: parseFloat(weight) };
83+
}
84+
});
85+
return items;
86+
};
87+
88+
const updateHandout = (handoutName, items) => {
89+
let totalWeight = Object.entries(items).reduce((sum, [_, { quantity, weight }]) => sum + (quantity * weight), 0);
90+
let sortedItems = Object.entries(items).sort(([a], [b]) => {
91+
let aIndex = CONFIG.coinOrder.indexOf(a);
92+
let bIndex = CONFIG.coinOrder.indexOf(b);
93+
if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;
94+
if (aIndex !== -1) return -1;
95+
if (bIndex !== -1) return 1;
96+
return a.localeCompare(b);
97+
});
98+
99+
let content = `<b>Total Weight: ${totalWeight.toFixed(2)} lbs</b><br><br>`;
100+
sortedItems.forEach(([item, { quantity, weight }]) => {
101+
content += `<b>${item}</b>: <span style='color:${CONFIG.quantityColor}'>${quantity}</span> (${weight} lbs)<br>`;
102+
});
103+
104+
let handout = getOrCreateHandout(handoutName);
105+
handout.set('notes', content);
106+
};
107+
108+
const addItem = (count, item, weight, handoutName, maxWeight) => {
109+
let handout = getOrCreateHandout(handoutName);
110+
handout.get('notes', (notes) => {
111+
let items = parseHandoutContent(notes);
112+
count = parseInt(count, 10);
113+
weight = parseFloat(weight);
114+
let currentWeight = Object.entries(items).reduce((sum, [_, { quantity, weight }]) => sum + (quantity * weight), 0);
115+
if (currentWeight + (count * weight) > maxWeight) {
116+
sendChat(handoutName, `&{template:default} {{name=${handoutName}}} {{Warning=The ${handoutName} is overloaded and its contents are lost.}}`);
117+
return;
118+
}
119+
items[item] = items[item] || { quantity: 0, weight };
120+
items[item].quantity += count;
121+
updateHandout(handoutName, items);
122+
});
123+
};
124+
125+
const removeItem = (count, item, handoutName) => {
126+
let handout = getOrCreateHandout(handoutName);
127+
handout.get('notes', (notes) => {
128+
let items = parseHandoutContent(notes);
129+
count = parseInt(count, 10);
130+
if (!items[item] || items[item].quantity < count) {
131+
sendChat(handoutName, `/w gm &{template:default} {{name=${handoutName}}} {{Warning=Not enough ${item} to remove!}}`);
132+
return;
133+
}
134+
items[item].quantity -= count;
135+
if (items[item].quantity <= 0) delete items[item];
136+
updateHandout(handoutName, items);
137+
});
138+
};
139+
140+
on('chat:message', (msg) => {
141+
if (msg.type !== 'api') return;
142+
let args = msg.content.match(/^!(dimensionbag|sack|hole) (add|remove) "(.+?)" (.+)$/);
143+
if (!args) return;
144+
145+
let type = args[1];
146+
let action = args[2];
147+
let storageName = args[3];
148+
let commandArgs = args[4].split(' ');
149+
let maxWeight = type === 'dimensionbag' ? CONFIG.bagMaxWeight : type === 'sack' ? CONFIG.sackMaxWeight : CONFIG.holeMaxWeight;
150+
151+
if (action === 'add' && commandArgs.length >= 3) {
152+
let count = commandArgs.shift();
153+
let weight = commandArgs.pop();
154+
let item = commandArgs.join(' ');
155+
addItem(count, item, weight, storageName, maxWeight);
156+
} else if (action === 'remove' && commandArgs.length >= 2) {
157+
let count = commandArgs.shift();
158+
let item = commandArgs.join(' ');
159+
removeItem(count, item, storageName);
160+
}
161+
});
162+
});

0 commit comments

Comments
 (0)