Skip to content

Commit fbf3db4

Browse files
committed
rename achievement support
1 parent 8c0b178 commit fbf3db4

File tree

1 file changed

+61
-0
lines changed
  • src/extensions/custom_achievements

1 file changed

+61
-0
lines changed

src/extensions/custom_achievements/index.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ class CustomAchievements {
6565
this._popupCloseResolve();
6666
this._popupCloseResolve = null;
6767
}
68+
} else if (data.action === 'ACHIEVEMENT_RENAMED') {
69+
this._renameAchievement(data.oldName, data.newName);
6870
}
6971
}
7072
});
@@ -139,6 +141,65 @@ class CustomAchievements {
139141
}
140142
}
141143

144+
/**
145+
* Renames an achievement in the cache and updates all blocks referencing it.
146+
* @param {string} oldName The previous name of the achievement
147+
* @param {string} newName The new name of the achievement
148+
*/
149+
_renameAchievement (oldName, newName) {
150+
if (!oldName || !newName || oldName === newName) return;
151+
152+
// 1. Update internal cache
153+
if (Object.prototype.hasOwnProperty.call(this._cache, oldName)) {
154+
this._cache[newName] = this._cache[oldName];
155+
delete this._cache[oldName];
156+
}
157+
158+
// 2. Update overridden set
159+
if (this._overriddenAchievements.has(oldName)) {
160+
this._overriddenAchievements.delete(oldName);
161+
this._overriddenAchievements.add(newName);
162+
}
163+
164+
// 3. Update blocks in the runtime
165+
const targets = this.runtime.targets;
166+
for (let i = 0; i < targets.length; i++) {
167+
const target = targets[i];
168+
const blocks = target.blocks;
169+
170+
for (const blockId in blocks._blocks) {
171+
if (!Object.prototype.hasOwnProperty.call(blocks._blocks, blockId)) continue;
172+
const block = blocks._blocks[blockId];
173+
174+
// Check if this is a custom achievements block
175+
if (block.opcode.startsWith('customAchievements_')) {
176+
// Check inputs (for menu arguments)
177+
if (block.inputs.ACHIEVEMENT) {
178+
const input = block.inputs.ACHIEVEMENT;
179+
// Usually extension menus are shadow blocks connected to the input
180+
const shadowBlockId = input.shadow;
181+
if (shadowBlockId) {
182+
const shadowBlock = blocks.getBlock(shadowBlockId);
183+
if (shadowBlock && shadowBlock.fields) {
184+
for (const fieldName in shadowBlock.fields) {
185+
if (shadowBlock.fields[fieldName].value === oldName) {
186+
shadowBlock.fields[fieldName].value = newName;
187+
}
188+
}
189+
}
190+
}
191+
}
192+
}
193+
}
194+
}
195+
196+
// 4. Refresh UI to show new name in dropdowns and blocks
197+
if (this.runtime.extensionManager) {
198+
this.runtime.extensionManager.refreshBlocks();
199+
}
200+
this.runtime.requestBlocksUpdate();
201+
}
202+
142203
/**
143204
* Fetches achievement data from the API.
144205
* @returns {Promise<void>}

0 commit comments

Comments
 (0)