From 9c43cb240ed9a06ae94f0841975d87b228fbef6c Mon Sep 17 00:00:00 2001 From: DuckieTM Date: Sat, 7 Feb 2026 11:25:38 +0100 Subject: [PATCH] :up: Fix Effects (enable) --- .../avatar/src/data/HabboAvatarActions.ts | 361 ++++++++++++++++++ .../object/visualization/room/RoomPlane.ts | 12 +- .../room/src/renderer/RoomSpriteCanvas.ts | 2 +- .../room/src/renderer/utils/ExtendedSprite.ts | 2 +- .../utils/src/filters/PaletteMapFilter.ts | 22 +- 5 files changed, 384 insertions(+), 15 deletions(-) create mode 100644 packages/avatar/src/data/HabboAvatarActions.ts diff --git a/packages/avatar/src/data/HabboAvatarActions.ts b/packages/avatar/src/data/HabboAvatarActions.ts new file mode 100644 index 0000000..72fa9db --- /dev/null +++ b/packages/avatar/src/data/HabboAvatarActions.ts @@ -0,0 +1,361 @@ +export const HabboAvatarActions = { + 'actions': [ + { + 'id': 'Default', + 'state': 'std', + 'precedence': 1000, + 'main': true, + 'isDefault': true, + 'geometryType': 'vertical', + 'activePartSet': 'figure', + 'assetPartDefinition': 'std', + 'prevents': [], + 'animation': false + }, + { + 'id': 'Lay', + 'state': 'lay', + 'precedence': 900, + 'main': true, + 'geometryType': 'laying', + 'activePartSet': 'figure', + 'assetPartDefinition': 'lay', + 'prevents': ['sit', 'float', 'swim'], + 'animation': false + }, + { + 'id': 'Float', + 'state': 'float', + 'precedence': 850, + 'main': true, + 'geometryType': 'vertical', + 'activePartSet': 'figure', + 'assetPartDefinition': 'std', + 'prevents': ['sit', 'lay'], + 'animation': false + }, + { + 'id': 'Swim', + 'state': 'swim', + 'precedence': 820, + 'main': true, + 'geometryType': 'vertical', + 'activePartSet': 'figure', + 'assetPartDefinition': 'swm', + 'prevents': ['sit', 'lay'], + 'animation': true + }, + { + 'id': 'Sit', + 'state': 'sit', + 'precedence': 800, + 'main': true, + 'geometryType': 'sitting', + 'activePartSet': 'figure', + 'assetPartDefinition': 'sit', + 'prevents': ['lay', 'float', 'swim'], + 'animation': false + }, + { + 'id': 'Move', + 'state': 'mv', + 'precedence': 700, + 'main': true, + 'geometryType': 'vertical', + 'activePartSet': 'figure', + 'assetPartDefinition': 'wlk', + 'prevents': ['sit', 'lay'], + 'animation': true + }, + { + 'id': 'Talk', + 'state': 'talk', + 'precedence': 600, + 'activePartSet': 'head', + 'assetPartDefinition': 'tlk', + 'prevents': [], + 'animation': true + }, + { + 'id': 'Wave', + 'state': 'wave', + 'precedence': 500, + 'activePartSet': 'handRight', + 'assetPartDefinition': 'wav', + 'prevents': [], + 'animation': true + }, + { + 'id': 'Blow', + 'state': 'blow', + 'precedence': 500, + 'activePartSet': 'handRight', + 'assetPartDefinition': 'blw', + 'prevents': [], + 'animation': true + }, + { + 'id': 'Laugh', + 'state': 'laugh', + 'precedence': 500, + 'activePartSet': 'head', + 'assetPartDefinition': 'laugh', + 'prevents': [], + 'animation': true + }, + { + 'id': 'Cry', + 'state': 'cry', + 'precedence': 500, + 'activePartSet': 'head', + 'assetPartDefinition': 'cry', + 'prevents': [], + 'animation': true + }, + { + 'id': 'Idle', + 'state': 'idle', + 'precedence': 500, + 'activePartSet': 'head', + 'assetPartDefinition': 'idle', + 'prevents': [], + 'animation': true + }, + { + 'id': 'Respect', + 'state': 'respect', + 'precedence': 500, + 'activePartSet': 'handLeft', + 'assetPartDefinition': 'respect', + 'prevents': [], + 'animation': true + }, + { + 'id': 'Sign', + 'state': 'sign', + 'precedence': 400, + 'activePartSet': 'handLeft', + 'assetPartDefinition': 'sig', + 'prevents': [], + 'animation': true + }, + { + 'id': 'Sleep', + 'state': 'sleep', + 'precedence': 300, + 'activePartSet': 'eye', + 'assetPartDefinition': 'eyb', + 'prevents': [], + 'animation': false + }, + { + 'id': 'Dance', + 'state': 'dance', + 'precedence': 500, + 'main': true, + 'geometryType': 'vertical', + 'activePartSet': 'figure', + 'assetPartDefinition': '', + 'prevents': [], + 'animation': true, + 'preventHeadTurn': true, + 'types': [ + { + 'id': 1, + 'animated': true, + 'prevents': [], + 'preventHeadTurn': false + }, + { + 'id': 2, + 'animated': true, + 'prevents': ['wave', 'cri', 'usei'], + 'preventHeadTurn': true + }, + { + 'id': 3, + 'animated': true, + 'prevents': ['wave', 'cri', 'usei'], + 'preventHeadTurn': true + }, + { + 'id': 4, + 'animated': true, + 'prevents': ['wave', 'cri', 'usei'], + 'preventHeadTurn': true + } + ] + }, + { + 'id': 'CarryItem', + 'state': 'cri', + 'precedence': 500, + 'activePartSet': 'handRight', + 'assetPartDefinition': 'crr', + 'prevents': [], + 'animation': false, + 'params': [ + { 'id': 'default', 'value': '1' } + ] + }, + { + 'id': 'UseItem', + 'state': 'usei', + 'precedence': 500, + 'activePartSet': 'handRight', + 'assetPartDefinition': 'drk', + 'prevents': [], + 'animation': true, + 'params': [ + { 'id': 'default', 'value': '1' } + ] + }, + { + 'id': 'AvatarEffect', + 'state': 'fx', + 'precedence': 500, + 'activePartSet': 'figure', + 'assetPartDefinition': '', + 'prevents': [], + 'animation': true, + 'startFromFrameZero': true + }, + { + 'id': 'Vote', + 'state': 'vote', + 'precedence': 500, + 'activePartSet': 'handLeft', + 'assetPartDefinition': 'vote', + 'prevents': [], + 'animation': true + }, + { + 'id': 'Typing', + 'state': 'typing', + 'precedence': 100, + 'activePartSet': 'handLeft', + 'assetPartDefinition': '', + 'prevents': [], + 'animation': false + }, + { + 'id': 'RideJump', + 'state': 'ridejump', + 'precedence': 500, + 'activePartSet': 'figure', + 'assetPartDefinition': '', + 'prevents': [], + 'animation': true, + 'startFromFrameZero': true + }, + { + 'id': 'SnowBoardOllie', + 'state': 'sbollie', + 'precedence': 500, + 'activePartSet': 'figure', + 'assetPartDefinition': '', + 'prevents': [], + 'animation': true, + 'startFromFrameZero': true + }, + { + 'id': 'SnowBoard360', + 'state': 'sb360', + 'precedence': 500, + 'activePartSet': 'figure', + 'assetPartDefinition': '', + 'prevents': [], + 'animation': true, + 'startFromFrameZero': true + }, + { + 'id': 'SnowWarRun', + 'state': 'swrun', + 'precedence': 700, + 'main': true, + 'geometryType': 'vertical', + 'activePartSet': 'figure', + 'assetPartDefinition': 'swm', + 'prevents': ['sit', 'lay'], + 'animation': true + }, + { + 'id': 'SnowWarDieFront', + 'state': 'swdiefront', + 'precedence': 900, + 'main': true, + 'geometryType': 'vertical', + 'activePartSet': 'figure', + 'assetPartDefinition': 'std', + 'prevents': [], + 'animation': false + }, + { + 'id': 'SnowWarDieBack', + 'state': 'swdieback', + 'precedence': 900, + 'main': true, + 'geometryType': 'vertical', + 'activePartSet': 'figure', + 'assetPartDefinition': 'std', + 'prevents': [], + 'animation': false + }, + { + 'id': 'SnowWarPick', + 'state': 'swpick', + 'precedence': 500, + 'activePartSet': 'handRight', + 'assetPartDefinition': 'crr', + 'prevents': [], + 'animation': true, + 'startFromFrameZero': true + }, + { + 'id': 'SnowWarThrow', + 'state': 'swthrow', + 'precedence': 500, + 'activePartSet': 'handRight', + 'assetPartDefinition': 'drk', + 'prevents': [], + 'animation': true, + 'startFromFrameZero': true + }, + { + 'id': 'GestureSmile', + 'state': 'sml', + 'precedence': 200, + 'activePartSet': 'head', + 'assetPartDefinition': 'sml', + 'prevents': [], + 'animation': false + }, + { + 'id': 'GestureAggravated', + 'state': 'agr', + 'precedence': 200, + 'activePartSet': 'head', + 'assetPartDefinition': 'agr', + 'prevents': [], + 'animation': false + }, + { + 'id': 'GestureSurprised', + 'state': 'srp', + 'precedence': 200, + 'activePartSet': 'head', + 'assetPartDefinition': 'srp', + 'prevents': [], + 'animation': false + }, + { + 'id': 'GestureSad', + 'state': 'sad', + 'precedence': 200, + 'activePartSet': 'head', + 'assetPartDefinition': 'sad', + 'prevents': [], + 'animation': false + } + ] +}; diff --git a/packages/room/src/object/visualization/room/RoomPlane.ts b/packages/room/src/object/visualization/room/RoomPlane.ts index 66dc088..9a2feaf 100644 --- a/packages/room/src/object/visualization/room/RoomPlane.ts +++ b/packages/room/src/object/visualization/room/RoomPlane.ts @@ -885,7 +885,7 @@ export class RoomPlane implements IRoomPlane const visibleAvatarIds = new Set(); const addReflectionSprite = (texture: Texture, location: IVector3D, alpha: number): boolean => { - if(!texture || !location || alpha < 0) return false; + if(!texture?.source || !location || alpha < 0) return false; const relative = Vector3d.dif(location, this._location); const planeDistance = Math.abs(Vector3d.scalarProjection(relative, this._normal)); @@ -922,7 +922,7 @@ export class RoomPlane implements IRoomPlane for(const avatar of avatars) { - if(!avatar?.texture || !avatar.location) continue; + if(!avatar?.texture?.source || !avatar.location) continue; let firstSeenAt = this._windowReflectionFirstSeenAt.get(avatar.id); @@ -955,6 +955,14 @@ export class RoomPlane implements IRoomPlane { if(visibleAvatarIds.has(id) || this._windowReflectionFadeOut.has(id)) continue; + if(!lastVisible.texture?.source) + { + this._windowReflectionLastVisible.delete(id); + this._windowReflectionFirstSeenAt.delete(id); + + continue; + } + this._windowReflectionFadeOut.set(id, { texture: lastVisible.texture, location: lastVisible.location, diff --git a/packages/room/src/renderer/RoomSpriteCanvas.ts b/packages/room/src/renderer/RoomSpriteCanvas.ts index a37a758..0c52850 100644 --- a/packages/room/src/renderer/RoomSpriteCanvas.ts +++ b/packages/room/src/renderer/RoomSpriteCanvas.ts @@ -409,7 +409,7 @@ export class RoomSpriteCanvas implements IRoomRenderingCanvas const texture = sprite.texture; const baseTexture = texture && texture.source; - if(!texture || !baseTexture) continue; + if(!texture || !baseTexture || baseTexture.destroyed) continue; const spriteX = ((x + sprite.offsetX) + this._screenOffsetX); const spriteY = ((y + sprite.offsetY) + this._screenOffsetY); diff --git a/packages/room/src/renderer/utils/ExtendedSprite.ts b/packages/room/src/renderer/utils/ExtendedSprite.ts index f3b08be..99ec957 100644 --- a/packages/room/src/renderer/utils/ExtendedSprite.ts +++ b/packages/room/src/renderer/utils/ExtendedSprite.ts @@ -29,7 +29,7 @@ export class ExtendedSprite extends Sprite public setTexture(texture: Texture): void { - if(!texture) texture = Texture.EMPTY; + if(!texture || texture.source?.destroyed) texture = Texture.EMPTY; if(texture === this.texture) return; diff --git a/packages/utils/src/filters/PaletteMapFilter.ts b/packages/utils/src/filters/PaletteMapFilter.ts index ac83420..f007975 100644 --- a/packages/utils/src/filters/PaletteMapFilter.ts +++ b/packages/utils/src/filters/PaletteMapFilter.ts @@ -61,7 +61,7 @@ export class PaletteMapFilter extends Filter uniform sampler2D uTexture; uniform sampler2D uLutTexture; - uniform int channel; + uniform int uChannel; void main(void) { vec4 currentColor = texture(uTexture, vTextureCoord); @@ -69,15 +69,15 @@ export class PaletteMapFilter extends Filter if(currentColor.a > 0.0) { - if(channel == 0) + if(uChannel == 0) { - adjusted = texture2D(uLutTexture, vec2((currentColor.r * 255.0 + 0.5) / 256.0, 0.5)); - } else if(channel == 1) { - adjusted = texture2D(uLutTexture, vec2((currentColor.g * 255.0 + 0.5) / 256.0, 0.5)); - } else if(channel == 2) { - adjusted = texture2D(uLutTexture, vec2((currentColor.b * 255.0 + 0.5) / 256.0, 0.5)); - } else if(channel == 3) { - adjusted = texture2D(uLutTexture, vec2((currentColor.a * 255.0 + 0.5) / 256.0, 0.5)); + adjusted = texture(uLutTexture, vec2((currentColor.r * 255.0 + 0.5) / 256.0, 0.5)); + } else if(uChannel == 1) { + adjusted = texture(uLutTexture, vec2((currentColor.g * 255.0 + 0.5) / 256.0, 0.5)); + } else if(uChannel == 2) { + adjusted = texture(uLutTexture, vec2((currentColor.b * 255.0 + 0.5) / 256.0, 0.5)); + } else if(uChannel == 3) { + adjusted = texture(uLutTexture, vec2((currentColor.a * 255.0 + 0.5) / 256.0, 0.5)); } } @@ -102,7 +102,7 @@ export class PaletteMapFilter extends Filter glProgram, resources: { paletteMapUniforms: { - uChannel: { value: options.channel, type: 'int' } + uChannel: { value: options.channel, type: 'i32' } }, uLutTexture: lutTexture.source }, @@ -133,7 +133,7 @@ export class PaletteMapFilter extends Filter lookUpTable[(i * 4) + PaletteMapFilter.CHANNEL_RED] = ((data[i] >> 16) & 0xFF); lookUpTable[(i * 4) + PaletteMapFilter.CHANNEL_GREEN] = ((data[i] >> 8) & 0xFF); lookUpTable[(i * 4) + PaletteMapFilter.CHANNEL_BLUE] = (data[i] & 0xFF); - lookUpTable[(i * 4) + PaletteMapFilter.CHANNEL_ALPHA] = ((data[i] >> 24) & 0xFF); + lookUpTable[(i * 4) + PaletteMapFilter.CHANNEL_ALPHA] = 255; } return lookUpTable;