218 lines
7.9 KiB
TypeScript
218 lines
7.9 KiB
TypeScript
import {BaseTexture, Texture} from "@pixi/core";
|
|
import {decompressFrames, parseGIF} from "gifuct-js";
|
|
|
|
import {
|
|
GetAssetManager,
|
|
IAssetData,
|
|
IRoomGeometry,
|
|
MapDataType,
|
|
MouseEventType,
|
|
RoomObjectVariable,
|
|
RoomWidgetEnumItemExtradataParameter,
|
|
} from "../../../../../api";
|
|
import {RoomObjectRoomAdEvent, RoomSpriteMouseEvent} from "../../../../../events";
|
|
import {RoomObjectUpdateMessage} from "../../../../../room";
|
|
import {Nitro} from "../../../../Nitro";
|
|
import {ObjectAdUpdateMessage, ObjectDataUpdateMessage} from "../../../messages";
|
|
import {FurnitureLogic} from "./FurnitureLogic";
|
|
|
|
export class FurnitureRoomBrandingLogic extends FurnitureLogic {
|
|
public static STATE: string = "state";
|
|
public static IMAGEURL_KEY: string = "imageUrl";
|
|
public static CLICKURL_KEY: string = "clickUrl";
|
|
public static OFFSETX_KEY: string = "offsetX";
|
|
public static OFFSETY_KEY: string = "offsetY";
|
|
public static OFFSETZ_KEY: string = "offsetZ";
|
|
|
|
protected _disableFurnitureSelection: boolean;
|
|
protected _hasClickUrl: boolean;
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
this._disableFurnitureSelection = true;
|
|
this._hasClickUrl = false;
|
|
}
|
|
|
|
public override getEventTypes(): string[] {
|
|
const types = [RoomObjectRoomAdEvent.ROOM_AD_LOAD_IMAGE];
|
|
|
|
return this.mergeTypes(super.getEventTypes(), types);
|
|
}
|
|
|
|
public override initialize(asset: IAssetData): void {
|
|
super.initialize(asset);
|
|
|
|
if (this._disableFurnitureSelection) {
|
|
this.object.model.setValue(RoomObjectVariable.FURNITURE_SELECTION_DISABLED, 1);
|
|
}
|
|
}
|
|
|
|
public override processUpdateMessage(message: RoomObjectUpdateMessage): void {
|
|
super.processUpdateMessage(message);
|
|
|
|
if (message instanceof ObjectDataUpdateMessage) this.processAdDataUpdateMessage(message);
|
|
|
|
if (message instanceof ObjectAdUpdateMessage) this.processAdUpdate(message);
|
|
}
|
|
|
|
private processAdDataUpdateMessage(message: ObjectDataUpdateMessage): void {
|
|
if (!message) return;
|
|
|
|
const objectData = new MapDataType();
|
|
|
|
objectData.initializeFromRoomObjectModel(this.object.model);
|
|
|
|
const state = parseInt(objectData.getValue(FurnitureRoomBrandingLogic.STATE));
|
|
|
|
if (!isNaN(state) && this.object.getState(0) !== state) this.object.setState(state, 0);
|
|
|
|
const imageUrl = objectData.getValue(FurnitureRoomBrandingLogic.IMAGEURL_KEY);
|
|
const existingUrl = this.object.model.getValue<string>(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_URL);
|
|
|
|
if (!existingUrl || existingUrl !== imageUrl) {
|
|
this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_URL, imageUrl);
|
|
this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_STATUS, 0);
|
|
|
|
this.downloadBackground();
|
|
}
|
|
|
|
const clickUrl = objectData.getValue(FurnitureRoomBrandingLogic.CLICKURL_KEY);
|
|
|
|
if (clickUrl) {
|
|
const existingUrl = this.object.model.getValue<string>(RoomObjectVariable.FURNITURE_BRANDING_URL);
|
|
|
|
if (!existingUrl || existingUrl !== clickUrl) {
|
|
if (this.object.model) this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_URL, clickUrl);
|
|
}
|
|
}
|
|
|
|
const offsetX = parseInt(objectData.getValue(FurnitureRoomBrandingLogic.OFFSETX_KEY));
|
|
const offsetY = parseInt(objectData.getValue(FurnitureRoomBrandingLogic.OFFSETY_KEY));
|
|
const offsetZ = parseInt(objectData.getValue(FurnitureRoomBrandingLogic.OFFSETZ_KEY));
|
|
|
|
if (!isNaN(offsetX)) this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_X, offsetX);
|
|
if (!isNaN(offsetY)) this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Y, offsetY);
|
|
if (!isNaN(offsetZ)) this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Z, offsetZ);
|
|
|
|
let options = FurnitureRoomBrandingLogic.IMAGEURL_KEY + "=" + (imageUrl !== null ? imageUrl : "") + "\t";
|
|
|
|
if (this._hasClickUrl) {
|
|
options = options + (FurnitureRoomBrandingLogic.CLICKURL_KEY + "=" + (clickUrl !== null ? clickUrl : "") + "\t");
|
|
}
|
|
|
|
options = options + (FurnitureRoomBrandingLogic.OFFSETX_KEY + "=" + offsetX + "\t");
|
|
options = options + (FurnitureRoomBrandingLogic.OFFSETY_KEY + "=" + offsetY + "\t");
|
|
options = options + (FurnitureRoomBrandingLogic.OFFSETZ_KEY + "=" + offsetZ + "\t");
|
|
|
|
this.object.model.setValue(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM, RoomWidgetEnumItemExtradataParameter.BRANDING_OPTIONS + options);
|
|
}
|
|
|
|
private processAdUpdate(message: ObjectAdUpdateMessage): void {
|
|
if (!message || !this.object) return;
|
|
|
|
switch (message.type) {
|
|
case ObjectAdUpdateMessage.IMAGE_LOADED:
|
|
this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_STATUS, 1);
|
|
break;
|
|
case ObjectAdUpdateMessage.IMAGE_LOADING_FAILED:
|
|
this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_STATUS, -1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public override mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void {
|
|
if (!event || !geometry) return;
|
|
|
|
if (event.type === MouseEventType.MOUSE_MOVE || event.type === MouseEventType.DOUBLE_CLICK) return;
|
|
|
|
super.mouseEvent(event, geometry);
|
|
}
|
|
|
|
private async downloadBackground(): Promise<void> {
|
|
const model = this.object && this.object.model;
|
|
|
|
if (!model) return;
|
|
|
|
const imageUrl = model.getValue<string>(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_URL);
|
|
const imageStatus = model.getValue<number>(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_STATUS);
|
|
|
|
if (!imageUrl || imageUrl === "" || imageStatus === 1) return;
|
|
|
|
if (imageUrl.endsWith(".gif")) {
|
|
this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IS_ANIMATED, true);
|
|
|
|
fetch(imageUrl)
|
|
.then(resp => resp.arrayBuffer())
|
|
.then(buff => parseGIF(buff))
|
|
.then(gif => {
|
|
const width = gif.lsd.width;
|
|
const height = gif.lsd.height;
|
|
const wh = width * height;
|
|
const frames = decompressFrames(gif, false);
|
|
const textures = [];
|
|
const durations = [];
|
|
|
|
let frame = new Uint8Array(wh * 4);
|
|
|
|
for (let ind = 0; ind < frames.length; ind++) {
|
|
if (ind > 0) frame = frame.slice(0);
|
|
|
|
const pixels = frames[ind].pixels;
|
|
const colorTable = frames[ind].colorTable;
|
|
const trans = frames[ind].transparentIndex;
|
|
const dims = frames[ind].dims;
|
|
|
|
for (let j = 0; j < dims.height; j++) {
|
|
for (let i = 0; i < dims.width; i++) {
|
|
const pixel = pixels[j * dims.width + i];
|
|
const coord = (j + dims.top) * width + (i + dims.left);
|
|
|
|
if (trans !== pixel) {
|
|
const c = colorTable[pixel];
|
|
|
|
frame[4 * coord] = c[0];
|
|
frame[4 * coord + 1] = c[1];
|
|
frame[4 * coord + 2] = c[2];
|
|
frame[4 * coord + 3] = 255;
|
|
}
|
|
}
|
|
}
|
|
|
|
const baseTexture = BaseTexture.fromBuffer(frame, width, height);
|
|
|
|
textures.push(new Texture(baseTexture));
|
|
durations.push(frames[ind].delay);
|
|
}
|
|
|
|
Nitro.instance.roomEngine.roomContentLoader.createGifCollection(imageUrl, textures, durations);
|
|
|
|
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED));
|
|
})
|
|
.catch(error => {
|
|
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADING_FAILED));
|
|
});
|
|
} else {
|
|
const asset = GetAssetManager();
|
|
|
|
if (!asset) return;
|
|
|
|
const texture = asset.getTexture(imageUrl);
|
|
|
|
if (!texture) {
|
|
const status = await asset.downloadAsset(imageUrl);
|
|
|
|
if (!status) {
|
|
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADING_FAILED));
|
|
} else {
|
|
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED));
|
|
}
|
|
}
|
|
}
|