:fix Furniture Badges & update pixijs

This commit is contained in:
duckietm
2026-01-29 11:02:58 +01:00
parent b07cda1991
commit 53c6ecfbc3
3 changed files with 145 additions and 62 deletions
+2 -2
View File
@@ -30,8 +30,8 @@
"dependencies": { "dependencies": {
"howler": "^2.2.4", "howler": "^2.2.4",
"pako": "^2.1.0", "pako": "^2.1.0",
"pixi-filters": "^6.0.5", "pixi-filters": "^6.1.5",
"pixi.js": "^8.8.1", "pixi.js": "^8.15.0",
"clientjs": "^0.2.1" "clientjs": "^0.2.1"
}, },
"devDependencies": { "devDependencies": {
@@ -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'; import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization';
export class FurnitureBadgeDisplayVisualization extends 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 _badgeId = '';
private _badgeAssetNameNormalScale: string = ''; private _badgeAssetNameNormalScale = '';
private _badgeAssetNameSmallScale: string = ''; private _badgeAssetNameSmallScale = '';
private _badgeVisibleInState: number = -1; 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 protected updateModel(scale: number): boolean
{ {
let updateModel = super.updateModel(scale); let needsUpdate = super.updateModel(scale);
const badgeStatus = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS); const badgeStatus = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS);
const badgeId = this.object.model.getValue<string>(RoomObjectVariable.FURNITURE_BADGE_ASSET_NAME); const badgeId = this.object.model.getValue<string>(RoomObjectVariable.FURNITURE_BADGE_ASSET_NAME);
if(badgeStatus === -1) if (badgeStatus === -1)
{ {
this._badgeId = '';
this._badgeAssetNameNormalScale = ''; this._badgeAssetNameNormalScale = '';
this._badgeAssetNameSmallScale = ''; 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._badgeId = badgeId;
this._badgeAssetNameNormalScale = this._badgeId; this._badgeAssetNameNormalScale = badgeId;
this._badgeAssetNameSmallScale = `${badgeId}_32`;
if(this._badgeAssetNameSmallScale === '') this._badgeAssetNameSmallScale = this._badgeAssetNameNormalScale + '_32';
const visibleInState = this.object.model.getValue<number>(RoomObjectVariable.FURNITURE_BADGE_VISIBLE_IN_STATE); const visibleInState = this.object.model.getValue<number>(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 protected getSpriteAssetName(scale: number, layerId: number): string
{ {
const tag = this.getLayerTag(scale, this.direction, layerId); 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 protected getLayerXOffset(scale: number, direction: number, layerId: number): number
{ {
let offset = super.getLayerXOffset(scale, direction, layerId); 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) const a = this.getAsset(assetName, layerId);
{ if (!a) return offset;
if(scale === 64) offset += ((40 - asset.width) / 2);
else offset += ((20 - asset.width) / 2); const targetW = (scale === 64) ? 40 : 20;
} offset += ((targetW - a.width) / 2);
} }
return offset; return offset;
@@ -73,17 +136,48 @@ export class FurnitureBadgeDisplayVisualization extends FurnitureAnimatedVisuali
{ {
let offset = super.getLayerYOffset(scale, direction, layerId); 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) const a = this.getAsset(assetName, layerId);
{ if (!a) return offset;
if(scale === 64) offset += ((40 - asset.height) / 2);
else offset += ((20 - asset.height) / 2); const targetH = (scale === 64) ? 40 : 20;
} offset += ((targetH - a.height) / 2);
} }
return offset; 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<string>('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);
}
} }
+17 -28
View File
@@ -169,15 +169,12 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
if(!this._mask) if(!this._mask)
{ {
this._mask = new Sprite(Texture.WHITE); this._mask = new Sprite(Texture.WHITE);
this._mask.tint = 0xFF0000;
this._mask.width = width; this._mask.width = width;
this._mask.height = height; this._mask.height = height;
if(this._master) if(this._master)
{ {
this._master.addChild(this._mask); this._master.addChild(this._mask);
if(this._display) this._display.mask = this._mask; if(this._display) this._display.mask = this._mask;
} }
} }
@@ -193,7 +190,6 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
if(this._master.filterArea) if(this._master.filterArea)
{ {
const filterArea = this._master.filterArea; const filterArea = this._master.filterArea;
filterArea.width = width; filterArea.width = width;
filterArea.height = height; filterArea.height = height;
} }
@@ -461,6 +457,13 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
sortableSprite.y = (spriteY - this._screenOffsetY); sortableSprite.y = (spriteY - this._screenOffsetY);
sortableSprite.z = ((z + sprite.relativeDepth) + (3.7E-11 * count)); 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++; spriteCount++;
count++; count++;
} }
@@ -494,7 +497,7 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
{ {
if(index >= this._spriteCount) if(index >= this._spriteCount)
{ {
this.createAndAddSprite(sprite); this.createAndAddSprite(sprite, index);
return true; return true;
} }
@@ -505,7 +508,7 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
const extendedSprite = this.getExtendedSprite(index); const extendedSprite = this.getExtendedSprite(index);
if(!objectSprite || !extendedSprite) return false; if(!objectSprite || !extendedSprite) return false;
if(extendedSprite.varyingDepth !== objectSprite.varyingDepth) if(extendedSprite.varyingDepth !== objectSprite.varyingDepth)
{ {
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.blendMode !== objectSprite.blendMode) extendedSprite.blendMode = objectSprite.blendMode;
if(extendedSprite.texture !== objectSprite.texture) extendedSprite.setTexture(objectSprite.texture); 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) extendedSprite.scale.x = objectSprite.flipH ? -sx : sx;
{ extendedSprite.scale.y = objectSprite.flipV ? -sy : sy;
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.x = Math.round(sprite.x); extendedSprite.x = Math.round(sprite.x);
extendedSprite.y = Math.round(sprite.y); extendedSprite.y = Math.round(sprite.y);
@@ -613,7 +603,6 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
if(!textureSet) extendedSprite.setTexture(sprite.texture); if(!textureSet) extendedSprite.setTexture(sprite.texture);
if(sprite.flipH) extendedSprite.scale.x = -1; if(sprite.flipH) extendedSprite.scale.x = -1;
if(sprite.flipV) extendedSprite.scale.y = -1; if(sprite.flipV) extendedSprite.scale.y = -1;
this.updateEnterRoomEffect(extendedSprite, sprite); this.updateEnterRoomEffect(extendedSprite, sprite);
@@ -1188,4 +1177,4 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas
{ {
this._canvasUpdated = flag; this._canvasUpdated = flag;
} }
} }