Skip to content

Commit bcb1b66

Browse files
authored
Merge pull request #2227 from shdwjk/TheAaron-2026-05-17
Fixed issue with getAttribute and setAttribute doing redundant legacy…
2 parents 950f7b6 + 445609a commit bcb1b66

6 files changed

Lines changed: 112 additions & 150 deletions

File tree

.types/index.d.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,9 @@ declare function getAllObjs(): Roll20Object<AnyRoll20Object>[];
554554
*/
555555
declare function getAttrByName(character_id: string, attribute_name: string, value_type?: "current" | "max"): string;
556556

557+
type SheetItemOptions = { allowThrow?: boolean };
558+
type SheetItemValueTYpe = "current" | "max";
559+
557560
/**
558561
* Gets the value of a sheet item for a character (beacon sheets)
559562
* @param character_id The ID of the character
@@ -570,7 +573,7 @@ declare function getAttrByName(character_id: string, attribute_name: string, val
570573
* @example Get a character's maximum hit points
571574
* const maxHp = await getSheetItem("-KxUZ0wYG9gDCGukimEE", "hp", "max");
572575
*/
573-
declare function getSheetItem(character_id: string, item_name: string, value_type?: "current" | "max"): Promise<string | undefined>;
576+
declare function getSheetItem(character_id: string, item_name: string, value_type?: SheetItemValueType | SheetItemOptions, options?: SheetItemOptions): Promise<string | undefined>;
574577

575578
/**
576579
* Sets the value of a sheet item for a character (beacon sheets)
@@ -589,7 +592,7 @@ declare function getSheetItem(character_id: string, item_name: string, value_typ
589592
* @example Set a character's maximum hit points
590593
* await setSheetItem("-KxUZ0wYG9gDCGukimEE", "hp", 20, "max");
591594
*/
592-
declare function setSheetItem(character_id: string, item_name: string, value: any, value_type?: "current" | "max"): Promise<boolean>;
595+
declare function setSheetItem(character_id: string, item_name: string, value: any, value_type?: SheetItemValueType | SheetItemOptions, options?: SheetItemOptions): Promise<boolean>;
593596

594597
/**
595598
* Logs a message to the API console on the Script Editor page

Concentration/.README.md.swp

-12 KB
Binary file not shown.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// libSmartAttributes v0.0.3 by GUD Team | libSmartAttributes provides an interface for managing beacon attributes in a slightly smarter way.
2+
var libSmartAttributes = (function () {
3+
'use strict';
4+
5+
async function getAttribute(characterId, name, type = "current") {
6+
// Try for a legacy attribute or beacon computed
7+
const attr = await getSheetItem(characterId, name, type);
8+
if (attr !== null && attr !== undefined) {
9+
return attr;
10+
}
11+
// Then try for the user attribute
12+
const userAttr = await getSheetItem(characterId, `user.${name}`, type);
13+
if (userAttr !== null && userAttr !== undefined) {
14+
return userAttr;
15+
}
16+
log(`Attribute ${name} not found on character ${characterId}`);
17+
return undefined;
18+
}
19+
async function setAttribute(characterId, name, value, type = "current", options) {
20+
try {
21+
await setSheetItem(characterId, name, value, type, { allowThrow: true });
22+
return;
23+
}
24+
catch {
25+
// throw will happen on beacon sheets if the computed doesn't exist or is read-only
26+
}
27+
// Guard against creating user attributes if noCreate is set
28+
if (options?.noCreate) {
29+
log(`Attribute ${name} not found on character ${characterId}, and noCreate option is set. Skipping creation.`);
30+
return;
31+
}
32+
// Then default to a user attribute
33+
setSheetItem(characterId, `user.${name}`, value, type);
34+
return;
35+
}
36+
async function deleteAttribute(characterId, name, type = "current") {
37+
// Try for legacy attribute first
38+
const legacyAttr = findObjs({
39+
_type: "attribute",
40+
_characterid: characterId,
41+
name: name,
42+
})[0];
43+
if (legacyAttr) {
44+
legacyAttr.remove();
45+
return;
46+
}
47+
// Then try for the beacon computed
48+
const beaconAttr = await getSheetItem(characterId, name, type);
49+
if (beaconAttr !== null && beaconAttr !== undefined) {
50+
log(`Cannot delete beacon computed attribute ${name} on character ${characterId}. Setting to undefined instead`);
51+
setSheetItem(characterId, name, undefined, type);
52+
return;
53+
}
54+
// Then try for the user attribute
55+
const userAttr = await getSheetItem(characterId, `user.${name}`, type);
56+
if (userAttr !== null && userAttr !== undefined) {
57+
log(`Deleting user attribute ${name} on character ${characterId}`);
58+
setSheetItem(characterId, `user.${name}`, undefined, type);
59+
return;
60+
}
61+
log(`Attribute ${type} not found on character ${characterId}, nothing to delete`);
62+
return;
63+
}
64+
var index = {
65+
getAttribute,
66+
setAttribute,
67+
deleteAttribute,
68+
};
69+
70+
return index;
71+
72+
})();

libSmartAttributes/script.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "libSmartAttributes",
3-
"version": "0.0.2",
3+
"version": "0.0.3",
44
"description": "libSmartAttributes provides an interface for managing beacon attributes in a slightly smarter way.",
55
"authors": "GUD Team",
66
"roll20userid": "8705027",
@@ -10,6 +10,7 @@
1010
"script": "libSmartAttributes.js",
1111
"useroptions": [],
1212
"previousversions": [
13+
"0.0.2",
1314
"0.0.1"
1415
]
15-
}
16+
}

libSmartAttributes/src/index.ts

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
1-
type AttributeType = "current" | "max";
1+
type AttributeType = "current" | "max" ;
22

33
async function getAttribute(
44
characterId: string,
55
name: string,
66
type: AttributeType = "current"
77
) {
8-
// Try for legacy attribute first
9-
const legacyAttr = findObjs({
10-
_type: "attribute",
11-
_characterid: characterId,
12-
name: name,
13-
})[0];
14-
15-
if (legacyAttr) {
16-
return legacyAttr.get(type);
17-
}
18-
19-
// Then try for the beacon computed
20-
const beaconAttr = await getSheetItem(characterId, name, type);
21-
if (beaconAttr !== null && beaconAttr !== undefined) {
22-
return beaconAttr;
8+
// Try for a legacy attribute or beacon computed
9+
const attr = await getSheetItem(characterId, name, type);
10+
if (attr !== null && attr !== undefined) {
11+
return attr;
2312
}
2413

2514
// Then try for the user attribute
@@ -33,7 +22,6 @@ async function getAttribute(
3322
};
3423

3524
type SetOptions = {
36-
setWithWorker?: boolean;
3725
noCreate?: boolean;
3826
};
3927

@@ -44,28 +32,12 @@ async function setAttribute(
4432
type: AttributeType = "current",
4533
options?: SetOptions
4634
) {
47-
// Try for legacy attribute first
48-
const legacyAttr = findObjs({
49-
_type: "attribute",
50-
_characterid: characterId,
51-
name: name,
52-
})[0];
53-
54-
if (legacyAttr && options?.setWithWorker) {
55-
legacyAttr.setWithWorker({ [type]: value });
56-
return;
57-
}
5835

59-
else if (legacyAttr) {
60-
legacyAttr.set({ [type]: value });
61-
return;
62-
}
63-
64-
// Then try for the beacon computed
65-
const beaconAttr = await getSheetItem(characterId, name, type);
66-
if (beaconAttr !== null && beaconAttr !== undefined) {
67-
setSheetItem(characterId, name, value);
36+
try {
37+
await setSheetItem(characterId, name, value, type, {allowThrow: true});
6838
return;
39+
} catch {
40+
// throw will happen on beacon sheets if the computed doesn't exist or is read-only
6941
}
7042

7143
// Guard against creating user attributes if noCreate is set
@@ -116,4 +88,4 @@ export default {
11688
getAttribute,
11789
setAttribute,
11890
deleteAttribute,
119-
};
91+
};

0 commit comments

Comments
 (0)