diff --git a/package.json b/package.json index c5538c5..cf4b046 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,8 @@ "dependencies": { "howler": "^2.2.4", "pako": "^2.1.0", - "pixi-filters": "^6.0.5", - "pixi.js": "^8.8.1", + "pixi-filters": "^6.1.5", + "pixi.js": "^8.15.0", "clientjs": "^0.2.1" }, "devDependencies": { diff --git a/packages/room/src/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts index 67a6c36..5c68a27 100644 --- a/packages/room/src/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts +++ b/packages/room/src/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts @@ -1,69 +1,132 @@ -import { RoomObjectVariable } from '@nitrots/api'; +import { IGraphicAsset, IRoomObjectSprite, RoomObjectVariable } from '@nitrots/api'; +import { GetConfiguration } from '@nitrots/configuration'; +import { GetSessionDataManager } from '@nitrots/session'; +import { Texture } from 'pixi.js'; import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; export class FurnitureBadgeDisplayVisualization extends FurnitureAnimatedVisualization { - private static BADGE: string = 'BADGE'; + private static readonly BADGE_TAG = 'BADGE'; + private static readonly BADGE_LAYER_ID = 1; - private _badgeId: string = ''; - private _badgeAssetNameNormalScale: string = ''; - private _badgeAssetNameSmallScale: string = ''; - private _badgeVisibleInState: number = -1; + private _badgeId = ''; + private _badgeAssetNameNormalScale = ''; + private _badgeAssetNameSmallScale = ''; + private _badgeVisibleInState = -1; + + public getTexture(scale: number, layerId: number, asset: IGraphicAsset): Texture + { + return super.getTexture(scale, layerId, asset); + } + + public get sprites(): IRoomObjectSprite[] +{ + const sprites = super.sprites; + + for(const sprite of sprites) + { + if(!sprite) continue; + + if(sprite.name === this._badgeAssetNameNormalScale || sprite.name === this._badgeAssetNameSmallScale) + { + sprite.relativeDepth = 0.01; + } + } + + return sprites; +} protected updateModel(scale: number): boolean { - let updateModel = super.updateModel(scale); + let needsUpdate = super.updateModel(scale); const badgeStatus = this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS); const badgeId = this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_ASSET_NAME); - if(badgeStatus === -1) + if (badgeStatus === -1) { + this._badgeId = ''; this._badgeAssetNameNormalScale = ''; this._badgeAssetNameSmallScale = ''; + this._badgeVisibleInState = -1; + + return needsUpdate; } - else if((badgeStatus === 1) && (badgeId !== this._badgeId)) + if ((badgeStatus === 1) && badgeId && (badgeId !== this._badgeId)) { this._badgeId = badgeId; - this._badgeAssetNameNormalScale = this._badgeId; - - if(this._badgeAssetNameSmallScale === '') this._badgeAssetNameSmallScale = this._badgeAssetNameNormalScale + '_32'; + this._badgeAssetNameNormalScale = badgeId; + this._badgeAssetNameSmallScale = `${badgeId}_32`; const visibleInState = this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_VISIBLE_IN_STATE); + this._badgeVisibleInState = isNaN(visibleInState) ? -1 : visibleInState; - if(!isNaN(visibleInState)) this._badgeVisibleInState = visibleInState; + this.addBadgeToAssetCollection(badgeId); - updateModel = true; + const layerId = FurnitureBadgeDisplayVisualization.BADGE_LAYER_ID; + this._assetNames[layerId] = undefined; + this._updatedLayers[layerId] = undefined; + this._spriteTags[layerId] = undefined; + + this.updateObjectCounter = -1; + needsUpdate = true; } - return updateModel; + return needsUpdate; } protected getSpriteAssetName(scale: number, layerId: number): string { const tag = this.getLayerTag(scale, this.direction, layerId); - if((tag !== FurnitureBadgeDisplayVisualization.BADGE) || ((this._badgeVisibleInState !== -1) && (this.object.getState(0) !== this._badgeVisibleInState))) return super.getSpriteAssetName(scale, layerId); + if (tag !== FurnitureBadgeDisplayVisualization.BADGE_TAG) + { + return super.getSpriteAssetName(scale, layerId); + } - if(scale === 32) return this._badgeAssetNameSmallScale; + if ((this._badgeVisibleInState !== -1) && (this.object.getState(0) !== this._badgeVisibleInState)) + { + return super.getSpriteAssetName(scale, layerId); + } - return this._badgeAssetNameNormalScale; + const assetName = (scale === 32) ? this._badgeAssetNameSmallScale : this._badgeAssetNameNormalScale; + if (!assetName) return super.getSpriteAssetName(scale, layerId); + + const a = this.getAsset(assetName, layerId); + if (!a || !a.texture) return super.getSpriteAssetName(scale, layerId); + + return assetName; + } + + protected updateSprite(sprite: IRoomObjectSprite, asset: IGraphicAsset, scale: number, layerId: number): void + { + super.updateSprite(sprite, asset, scale, layerId); + + const tag = this.getLayerTag(scale, this.direction, layerId); + + if (tag === FurnitureBadgeDisplayVisualization.BADGE_TAG) + { + sprite.visible = true; + sprite.alpha = 255; + sprite.color = 0xFFFFFF; + } } protected getLayerXOffset(scale: number, direction: number, layerId: number): number { let offset = super.getLayerXOffset(scale, direction, layerId); - if(this.getLayerTag(scale, direction, layerId) === FurnitureBadgeDisplayVisualization.BADGE) + if (this.getLayerTag(scale, direction, layerId) === FurnitureBadgeDisplayVisualization.BADGE_TAG) { - const asset = this.getAsset(((scale === 32) ? this._badgeAssetNameSmallScale : this._badgeAssetNameNormalScale), layerId); + const assetName = (scale === 32) ? this._badgeAssetNameSmallScale : this._badgeAssetNameNormalScale; + if (!assetName) return offset; - if(asset) - { - if(scale === 64) offset += ((40 - asset.width) / 2); - else offset += ((20 - asset.width) / 2); - } + const a = this.getAsset(assetName, layerId); + if (!a) return offset; + + const targetW = (scale === 64) ? 40 : 20; + offset += ((targetW - a.width) / 2); } return offset; @@ -73,17 +136,48 @@ export class FurnitureBadgeDisplayVisualization extends FurnitureAnimatedVisuali { let offset = super.getLayerYOffset(scale, direction, layerId); - if(this.getLayerTag(scale, direction, layerId) === FurnitureBadgeDisplayVisualization.BADGE) + if (this.getLayerTag(scale, direction, layerId) === FurnitureBadgeDisplayVisualization.BADGE_TAG) { - const asset = this.getAsset(((scale === 32) ? this._badgeAssetNameSmallScale : this._badgeAssetNameNormalScale), layerId); + const assetName = (scale === 32) ? this._badgeAssetNameSmallScale : this._badgeAssetNameNormalScale; + if (!assetName) return offset; - if(asset) - { - if(scale === 64) offset += ((40 - asset.height) / 2); - else offset += ((20 - asset.height) / 2); - } + const a = this.getAsset(assetName, layerId); + if (!a) return offset; + + const targetH = (scale === 64) ? 40 : 20; + offset += ((targetH - a.height) / 2); } return offset; } + + private addBadgeToAssetCollection(badgeId: string): void + { + const sessionDataManager = GetSessionDataManager(); + + let tex = sessionDataManager.getBadgeImage(badgeId); + if (!tex) tex = sessionDataManager.getGroupBadgeImage(badgeId); + + if (!tex || !this.asset) return; + + const canvas = (tex.source as any).resource as HTMLCanvasElement; + const ctx = canvas.getContext('2d'); + const imageData = ctx.getImageData(0, 0, 1, 1); + const isEmpty = imageData.data[3] === 0; + + if (isEmpty) { + const badgeUrl = GetConfiguration().getValue('badge.asset.url', '').replace('%badgename%', badgeId); + + const img = new Image(); + img.crossOrigin = 'anonymous'; + img.onload = () => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.drawImage(img, 0, 0, canvas.width, canvas.height); + tex.source.update(); + }; + img.src = badgeUrl; + } + + this.asset.addAsset(badgeId, tex, true, 0, 0, false, false); + } } diff --git a/packages/room/src/renderer/RoomSpriteCanvas.ts b/packages/room/src/renderer/RoomSpriteCanvas.ts index 5786f24..05d5bcf 100644 --- a/packages/room/src/renderer/RoomSpriteCanvas.ts +++ b/packages/room/src/renderer/RoomSpriteCanvas.ts @@ -169,15 +169,12 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas if(!this._mask) { this._mask = new Sprite(Texture.WHITE); - - this._mask.tint = 0xFF0000; this._mask.width = width; this._mask.height = height; if(this._master) { this._master.addChild(this._mask); - if(this._display) this._display.mask = this._mask; } } @@ -193,7 +190,6 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas if(this._master.filterArea) { const filterArea = this._master.filterArea; - filterArea.width = width; filterArea.height = height; } @@ -461,6 +457,13 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas sortableSprite.y = (spriteY - this._screenOffsetY); sortableSprite.z = ((z + sprite.relativeDepth) + (3.7E-11 * count)); + // Ensure badge renders on top of furniture + const isBadgeSprite = sprite.name && sprite.name.length < 10 && /^[A-Z]{2}[0-9]/.test(sprite.name); + + if(isBadgeSprite) { + sortableSprite.z = -999; + } + spriteCount++; count++; } @@ -494,7 +497,7 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas { if(index >= this._spriteCount) { - this.createAndAddSprite(sprite); + this.createAndAddSprite(sprite, index); return true; } @@ -505,7 +508,7 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas const extendedSprite = this.getExtendedSprite(index); if(!objectSprite || !extendedSprite) return false; - + if(extendedSprite.varyingDepth !== objectSprite.varyingDepth) { if(extendedSprite.varyingDepth && !objectSprite.varyingDepth) @@ -541,28 +544,15 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas if(extendedSprite.blendMode !== objectSprite.blendMode) extendedSprite.blendMode = objectSprite.blendMode; if(extendedSprite.texture !== objectSprite.texture) extendedSprite.setTexture(objectSprite.texture); + + + const sx = Math.abs(extendedSprite.scale.x) || 1; + const sy = Math.abs(extendedSprite.scale.y) || 1; - if(objectSprite.flipH) - { - if(extendedSprite.scale.x !== -1) extendedSprite.scale.x = -1; - } - else - { - if(extendedSprite.scale.x !== 1) extendedSprite.scale.x = 1; - } - - if(objectSprite.flipV) - { - if(extendedSprite.scale.y !== -1) extendedSprite.scale.y = -1; - } - else - { - if(extendedSprite.scale.y !== 1) extendedSprite.scale.y = 1; - } - - this.updateEnterRoomEffect(extendedSprite, objectSprite); + extendedSprite.scale.x = objectSprite.flipH ? -sx : sx; + extendedSprite.scale.y = objectSprite.flipV ? -sy : sy; } - + extendedSprite.x = Math.round(sprite.x); extendedSprite.y = Math.round(sprite.y); @@ -613,7 +603,6 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas if(!textureSet) extendedSprite.setTexture(sprite.texture); if(sprite.flipH) extendedSprite.scale.x = -1; - if(sprite.flipV) extendedSprite.scale.y = -1; this.updateEnterRoomEffect(extendedSprite, sprite); @@ -1188,4 +1177,4 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas { this._canvasUpdated = flag; } -} +} \ No newline at end of file