UNPKG

@csegames/camelot-unchained

Version:

Camelot Unchained Client Library

155 lines (128 loc) 5.92 kB
/** * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import BuildingMaterial from './classes/BuildingMaterial'; import BuildingBlock from './classes/BuildingBlock'; import client from '../core/client'; import events from '../events'; const materialsLoaded: boolean = false; let materialsRequested: boolean = false; let numBlocksToLoad: number = 0; const loadCallbacks: { (subs: BuildingMaterial[]): void }[] = []; const materialsMap: { [key: number]: BuildingMaterial } = {}; const materialsList: BuildingMaterial[] = []; const blocks: { [key: number]: BuildingBlock } = {}; // tslint:disable-next-line const BLANK_IMAGE = 'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOWwzfk4AAALxSURBVHhe5dlLiI1xGMfx30pCRFkJCyXFYiRSsmBByWIipMiOWYiNjZSirCxcsrUZuUzKZSGxULNT5JJsKaXspJlcVsd7zDn1zPN+z5n38v/bPIvP5nee37//M73TnN5Rp9MJDcNIMIwEw0gwjATDSDCMBMNIMIwEw0gwjATDSDCMBMNIMIwEw8akHYXNhU1gBXaqkrYWuufvLKH5ijBsTDr470j2BjtVSNfdWdYe7FSEYSvShLmcdx47w0ij7gzrKnZqwLA1adpc0tuIHSItLnwzXesjdmrCsDVpxFzUm8QOke65rrUQOzVhmIR00VzWO4MdSxpzHWsXdhrAMBnptbm0tx47XdLawh8za13GTkMYJiMtMBf3nmKnS3rmZvve4XwLGCYlHTELeKdg/qybsZaX5lvCMDnpllnC+llYbea2mc+80VlnJoJhFtIXs4x118x8dp/1Jf29tzDMQtpiFvJOF+64rO8VnpcIhtlI58xiVa3CsxLBMCvpuVluLofxjIQwzEpaUvjdW3CYG9hPDMPspP1mUfIWexlg+F9I18zC3hh2MsAwu5lviN97y5IfhfnYTQzD7KT7vUWHeYjdxDDMSjphlpxL+atyYhhmI60xy1W1Ds9KBMNspJdmMWuy8Mhlfe/xrEQwzEK6YJbyFvVmvrq870rpvEQwTE7abpbxjpm5ve4za/esMxPBMDlpyixiPYHZQa/Ap0qzCWCYlDRulvBmHn1Lmlf4ZGasx6X5ljBMZvg/Sg5hp0va52at49hpCMMkpGXm0t4EdizpputYS7HTAIZJDH8jXH70vZkf4KCvyx+w0wCGrQ1/8TH40feko65rXcJOTRi2Im0wl/TGsTOM9MCdYY1gpwYMW5F+mQta3T+Fcz/6nrTSnOFNY6cGDBsb/GKzq/qj70kn3VnWbexUhGEj0gFzKa/+o+9JL9yZVuP/GWAYCYaRYBgJhpFgGAmGkWAYCYaRYBgJhpFgGAmGkWAYCYaRYBhHR38Boj2hpYws8QsAAAAASUVORK5CYII='; function getBlockForShapeId(shapeId: number, blocks: BuildingBlock[]) { for (const i in blocks) { const block = blocks[i]; if (block.shapeId === shapeId) { return block; } } return blocks[0]; } function getShapeIdFromBlockId(id: number) { return id >> 21 & 31; } function getMaterialIdFromBlockId(id: number) { return id >> 2 & 4095; } function recieveMaterials(subsRecieved: { [key: number]: string }) { for (const i in subsRecieved) { const id = parseInt(i, 10); const material = new BuildingMaterial({ id, icon: subsRecieved[i], tags: [], blocks: [], } as BuildingMaterial); materialsMap[id] = material; materialsList.push(material); } client.RequestBlocks(); } function recieveBlocks(blocksRecieved: any) { for (const i in blocksRecieved) { numBlocksToLoad++; const id = parseInt(i, 10); blocks[id] = { id, icon: blocksRecieved[i], materialTags: [], shapeTags: [], } as BuildingBlock; } for (const i in blocksRecieved) { const id = parseInt(i, 10); client.RequestBlockTags(id); } } function recieveBlockTags(id: number, tags: any) { const block: BuildingBlock = blocks[id]; block.shapeId = getShapeIdFromBlockId(id); block.shapeTags = tags.Shapes; block.materialId = getMaterialIdFromBlockId(id); block.materialTags = tags.Types; const material = materialsMap[block.materialId]; if (material == null) { console.log('unknown material ' + block.materialId + ' for block ' + id + '-' + tags.Types.join(',')); } else { material.tags = tags.Types; material.blocks.push(block); } if (--numBlocksToLoad === 0) { // finished loading shapes and types events.fire(events.buildingEventTopics.handlesBlocks, { materials: materialsList }); } } function getBlockForBlockId(blockid: number): BuildingBlock { const matId = getMaterialIdFromBlockId(blockid); const shapeId = getShapeIdFromBlockId(blockid); const sub = materialsMap[matId]; if (sub == null) return null; // select by shape instead of by block id, it is more reliable, the block id sent back // can have extra information stored in it return getBlockForShapeId(shapeId, sub.blocks); } function getMaterialForBlockId(blockid: number): BuildingMaterial { const matId = getMaterialIdFromBlockId(blockid); return materialsMap[matId]; } function requestBlockSelect(block: BuildingBlock): void { client.ChangeBlockType(block.id); } // some blocks don't show up in the list retrieved by Request Substances or RequestBlocks // make up the information based on the block id, so we can at least display the shape and material type to the user // returning this information as a promise in case it is possible to request meta data on the material function getMissingMaterial(blockid: number): { material: BuildingMaterial, block: BuildingBlock } { const block: BuildingBlock = new BuildingBlock({ id: blockid, shapeId: getShapeIdFromBlockId(blockid), materialId: getMaterialIdFromBlockId(blockid), icon: BLANK_IMAGE, } as BuildingBlock); blocks[block.id] = block; const material: BuildingMaterial = new BuildingMaterial({ id: block.materialId, blocks: [block], icon: BLANK_IMAGE } as BuildingMaterial); materialsMap[material.id] = material; materialsList.push(material); events.fire(events.buildingEventTopics.handlesBlocks, { materials: materialsList }); return { material, block }; } function requestMaterials() { if (!materialsRequested) { materialsRequested = false; client.OnReceiveSubstances(recieveMaterials); client.OnReceiveBlocks(recieveBlocks); client.OnReceiveBlockTags(recieveBlockTags); client.RequestSubstances(); } } export * from './blueprints'; export * from './building-actions'; export { requestMaterials, getMissingMaterial, requestBlockSelect, getBlockForBlockId, getMaterialForBlockId };