mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
Add wired creator tools monitor and inspection UI
- add the new :wired inspection/monitor panel with furni, user and global tabs - add live variables, previews, inline editing and keep-selected behavior - add global room diagnostics placeholders, monitor artwork and server/client timezone display - add editor support for wf_xtra_text_output_furni_name and related UI texts/assets
This commit is contained in:
+23
-1
@@ -38,5 +38,27 @@
|
|||||||
"wiredfurni.params.texts.placeholder_type": "Tipo di segnaposto:",
|
"wiredfurni.params.texts.placeholder_type": "Tipo di segnaposto:",
|
||||||
"wiredfurni.params.texts.placeholder_type.1": "Singolo",
|
"wiredfurni.params.texts.placeholder_type.1": "Singolo",
|
||||||
"wiredfurni.params.texts.placeholder_type.2": "Multiplo",
|
"wiredfurni.params.texts.placeholder_type.2": "Multiplo",
|
||||||
"wiredfurni.params.texts.select_delimiter": "Seleziona il delimitatore:"
|
"wiredfurni.params.texts.select_delimiter": "Seleziona il delimitatore:",
|
||||||
|
"widget.memenu.dance1": "Ballo 1",
|
||||||
|
"widget.memenu.dance2": "Ballo 2",
|
||||||
|
"widget.memenu.dance3": "Ballo 3",
|
||||||
|
"widget.memenu.dance4": "Ballo 4",
|
||||||
|
"wiredfurni.params.action.sign.0": "Cartello 0",
|
||||||
|
"wiredfurni.params.action.sign.1": "Cartello 1",
|
||||||
|
"wiredfurni.params.action.sign.2": "Cartello 2",
|
||||||
|
"wiredfurni.params.action.sign.3": "Cartello 3",
|
||||||
|
"wiredfurni.params.action.sign.4": "Cartello 4",
|
||||||
|
"wiredfurni.params.action.sign.5": "Cartello 5",
|
||||||
|
"wiredfurni.params.action.sign.6": "Cartello 6",
|
||||||
|
"wiredfurni.params.action.sign.7": "Cartello 7",
|
||||||
|
"wiredfurni.params.action.sign.8": "Cartello 8",
|
||||||
|
"wiredfurni.params.action.sign.9": "Cartello 9",
|
||||||
|
"wiredfurni.params.action.sign.10": "Cartello 10",
|
||||||
|
"wiredfurni.params.action.sign.11": "Cartello 11",
|
||||||
|
"wiredfurni.params.action.sign.12": "Cartello 12",
|
||||||
|
"wiredfurni.params.action.sign.13": "Cartello 13",
|
||||||
|
"wiredfurni.params.action.sign.14": "Cartello 14",
|
||||||
|
"wiredfurni.params.action.sign.15": "Cartello 15",
|
||||||
|
"wiredfurni.params.action.sign.16": "Cartello 16",
|
||||||
|
"wiredfurni.params.action.sign.17": "Cartello 17"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
"game.center.enabled": false,
|
"game.center.enabled": false,
|
||||||
"guides.enabled": true,
|
"guides.enabled": true,
|
||||||
"toolbar.hide.quests": true,
|
"toolbar.hide.quests": true,
|
||||||
"catalog.style.new": true,
|
"catalog.style.new": false,
|
||||||
"navigator.room.models": [{
|
"navigator.room.models": [{
|
||||||
"clubLevel": 0,
|
"clubLevel": 0,
|
||||||
"tileSize": 104,
|
"tileSize": 104,
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ export class AvatarInfoFurni implements IAvatarInfo
|
|||||||
public availableForBuildersClub: boolean = false;
|
public availableForBuildersClub: boolean = false;
|
||||||
public tileSizeX: number = 1;
|
public tileSizeX: number = 1;
|
||||||
public tileSizeY: number = 1;
|
public tileSizeY: number = 1;
|
||||||
|
public allowStack: boolean = false;
|
||||||
|
public allowSit: boolean = false;
|
||||||
|
public allowLay: boolean = false;
|
||||||
|
public allowWalk: boolean = false;
|
||||||
|
public teleportTargetId: number = 0;
|
||||||
|
|
||||||
constructor(public readonly type: string)
|
constructor(public readonly type: string)
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -152,6 +152,18 @@ export class AvatarInfoUtilities
|
|||||||
furniInfo.ownerId = model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID);
|
furniInfo.ownerId = model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID);
|
||||||
furniInfo.ownerName = model.getValue<string>(RoomObjectVariable.FURNITURE_OWNER_NAME);
|
furniInfo.ownerName = model.getValue<string>(RoomObjectVariable.FURNITURE_OWNER_NAME);
|
||||||
furniInfo.usagePolicy = model.getValue<number>(RoomObjectVariable.FURNITURE_USAGE_POLICY);
|
furniInfo.usagePolicy = model.getValue<number>(RoomObjectVariable.FURNITURE_USAGE_POLICY);
|
||||||
|
furniInfo.allowStack = (model.getValue<number>(RoomObjectVariable.FURNITURE_ALLOW_STACK) > 0);
|
||||||
|
furniInfo.allowSit = (model.getValue<number>(RoomObjectVariable.FURNITURE_ALLOW_SIT) > 0);
|
||||||
|
furniInfo.allowLay = (model.getValue<number>(RoomObjectVariable.FURNITURE_ALLOW_LAY) > 0);
|
||||||
|
furniInfo.allowWalk = (model.getValue<number>(RoomObjectVariable.FURNITURE_ALLOW_WALK) > 0);
|
||||||
|
furniInfo.teleportTargetId = Number(model.getValue<number>(RoomObjectVariable.FURNITURE_TELEPORT_TARGET_ID) ?? 0);
|
||||||
|
|
||||||
|
const dimensionsX = model.getValue<number>(RoomObjectVariable.FURNITURE_DIMENSIONS_X);
|
||||||
|
const dimensionsY = model.getValue<number>(RoomObjectVariable.FURNITURE_DIMENSIONS_Y);
|
||||||
|
|
||||||
|
if(dimensionsX > 0) furniInfo.tileSizeX = dimensionsX;
|
||||||
|
|
||||||
|
if(dimensionsY > 0) furniInfo.tileSizeY = dimensionsY;
|
||||||
|
|
||||||
const guildId = model.getValue<number>(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_GUILD_ID);
|
const guildId = model.getValue<number>(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_GUILD_ID);
|
||||||
|
|
||||||
|
|||||||
@@ -66,4 +66,5 @@ export class WiredActionLayoutCode
|
|||||||
public static EXECUTION_LIMIT_EXTRA: number = 65;
|
public static EXECUTION_LIMIT_EXTRA: number = 65;
|
||||||
public static OR_EVAL_EXTRA: number = 66;
|
public static OR_EVAL_EXTRA: number = 66;
|
||||||
public static TEXT_OUTPUT_USERNAME_EXTRA: number = 67;
|
public static TEXT_OUTPUT_USERNAME_EXTRA: number = 67;
|
||||||
|
public static TEXT_OUTPUT_FURNI_NAME_EXTRA: number = 68;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
File diff suppressed because it is too large
Load Diff
@@ -60,6 +60,7 @@ import { WiredExtraMoveNoAnimationView } from '../extras/WiredExtraMoveNoAnimati
|
|||||||
import { WiredExtraOrEvalView } from '../extras/WiredExtraOrEvalView';
|
import { WiredExtraOrEvalView } from '../extras/WiredExtraOrEvalView';
|
||||||
import { WiredExtraMovePhysicsView } from '../extras/WiredExtraMovePhysicsView';
|
import { WiredExtraMovePhysicsView } from '../extras/WiredExtraMovePhysicsView';
|
||||||
import { WiredExtraRandomView } from '../extras/WiredExtraRandomView';
|
import { WiredExtraRandomView } from '../extras/WiredExtraRandomView';
|
||||||
|
import { WiredExtraTextOutputFurniNameView } from '../extras/WiredExtraTextOutputFurniNameView';
|
||||||
import { WiredExtraTextOutputUsernameView } from '../extras/WiredExtraTextOutputUsernameView';
|
import { WiredExtraTextOutputUsernameView } from '../extras/WiredExtraTextOutputUsernameView';
|
||||||
import { WiredExtraUnseenView } from '../extras/WiredExtraUnseenView';
|
import { WiredExtraUnseenView } from '../extras/WiredExtraUnseenView';
|
||||||
|
|
||||||
@@ -195,6 +196,8 @@ export const WiredActionLayoutView = (code: number) =>
|
|||||||
return <WiredExtraOrEvalView />;
|
return <WiredExtraOrEvalView />;
|
||||||
case WiredActionLayoutCode.TEXT_OUTPUT_USERNAME_EXTRA:
|
case WiredActionLayoutCode.TEXT_OUTPUT_USERNAME_EXTRA:
|
||||||
return <WiredExtraTextOutputUsernameView />;
|
return <WiredExtraTextOutputUsernameView />;
|
||||||
|
case WiredActionLayoutCode.TEXT_OUTPUT_FURNI_NAME_EXTRA:
|
||||||
|
return <WiredExtraTextOutputFurniNameView />;
|
||||||
case WiredActionLayoutCode.SEND_SIGNAL:
|
case WiredActionLayoutCode.SEND_SIGNAL:
|
||||||
return <WiredActionSendSignalView />;
|
return <WiredActionSendSignalView />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
|
import { LocalizeText, WiredFurniType } from '../../../../api';
|
||||||
|
import { Text } from '../../../../common';
|
||||||
|
import { useWired } from '../../../../hooks';
|
||||||
|
import { NitroInput } from '../../../../layout';
|
||||||
|
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||||
|
import { WiredExtraBaseView } from './WiredExtraBaseView';
|
||||||
|
|
||||||
|
const TYPE_SINGLE = 1;
|
||||||
|
const TYPE_MULTIPLE = 2;
|
||||||
|
const DEFAULT_PLACEHOLDER_NAME = '';
|
||||||
|
const DEFAULT_DELIMITER = ', ';
|
||||||
|
const MAX_PLACEHOLDER_NAME_LENGTH = 32;
|
||||||
|
const MAX_DELIMITER_LENGTH = 16;
|
||||||
|
const PLACEHOLDER_WRAPPER_PATTERN = /^\$\((.*)\)$/;
|
||||||
|
|
||||||
|
const normalizePlaceholderType = (value: number) => ((value === TYPE_MULTIPLE) ? TYPE_MULTIPLE : TYPE_SINGLE);
|
||||||
|
const normalizeFurniSource = (value: number) => ((value === 0) || (value === 100) || (value === 200) || (value === 201) ? value : 0);
|
||||||
|
const normalizePlaceholderName = (value: string) =>
|
||||||
|
{
|
||||||
|
let normalizedValue = (value ?? '').trim().replace(/[\t\r\n]/g, '');
|
||||||
|
|
||||||
|
if(PLACEHOLDER_WRAPPER_PATTERN.test(normalizedValue))
|
||||||
|
{
|
||||||
|
normalizedValue = normalizedValue.substring(2, normalizedValue.length - 1).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizedValue.slice(0, MAX_PLACEHOLDER_NAME_LENGTH);
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizeDelimiter = (value: string) =>
|
||||||
|
{
|
||||||
|
if(value === undefined || value === null) return DEFAULT_DELIMITER;
|
||||||
|
|
||||||
|
return value.replace(/[\t\r\n]/g, '').slice(0, MAX_DELIMITER_LENGTH);
|
||||||
|
};
|
||||||
|
|
||||||
|
const splitStringData = (value: string) =>
|
||||||
|
{
|
||||||
|
if(!value?.length) return [ DEFAULT_PLACEHOLDER_NAME, DEFAULT_DELIMITER ];
|
||||||
|
|
||||||
|
const parts = value.split('\t');
|
||||||
|
|
||||||
|
if(parts.length <= 1) return [ value, DEFAULT_DELIMITER ];
|
||||||
|
|
||||||
|
return [ parts[0], parts[1] ];
|
||||||
|
};
|
||||||
|
|
||||||
|
const escapeHtml = (value: string) => value
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
|
||||||
|
export const WiredExtraTextOutputFurniNameView: FC<{}> = () =>
|
||||||
|
{
|
||||||
|
const { trigger = null, setIntParams = null, setStringParam = null } = useWired();
|
||||||
|
const [ placeholderName, setPlaceholderName ] = useState(DEFAULT_PLACEHOLDER_NAME);
|
||||||
|
const [ placeholderType, setPlaceholderType ] = useState(TYPE_SINGLE);
|
||||||
|
const [ delimiter, setDelimiter ] = useState(DEFAULT_DELIMITER);
|
||||||
|
const [ furniSource, setFurniSource ] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!trigger) return;
|
||||||
|
|
||||||
|
const [ nextPlaceholderName, nextDelimiter ] = splitStringData(trigger.stringData);
|
||||||
|
|
||||||
|
setPlaceholderName(normalizePlaceholderName(nextPlaceholderName));
|
||||||
|
setDelimiter(normalizeDelimiter(nextDelimiter));
|
||||||
|
setPlaceholderType(normalizePlaceholderType((trigger.intData.length > 0) ? trigger.intData[0] : TYPE_SINGLE));
|
||||||
|
setFurniSource(normalizeFurniSource((trigger.intData.length > 1) ? trigger.intData[1] : 0));
|
||||||
|
}, [ trigger ]);
|
||||||
|
|
||||||
|
const previewToken = useMemo(() =>
|
||||||
|
{
|
||||||
|
const effectiveName = normalizePlaceholderName(placeholderName) || 'placeholder';
|
||||||
|
|
||||||
|
return `$(${ effectiveName })`;
|
||||||
|
}, [ placeholderName ]);
|
||||||
|
|
||||||
|
const previewHtml = useMemo(() => LocalizeText('wiredfurni.params.texts.placeholder_preview', [ 'placeholder' ], [ escapeHtml(previewToken) ]), [ previewToken ]);
|
||||||
|
|
||||||
|
const save = () =>
|
||||||
|
{
|
||||||
|
setIntParams([ normalizePlaceholderType(placeholderType), normalizeFurniSource(furniSource) ]);
|
||||||
|
setStringParam(`${ normalizePlaceholderName(placeholderName) }\t${ normalizeDelimiter(delimiter) }`);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<WiredExtraBaseView
|
||||||
|
hasSpecialInput={ true }
|
||||||
|
requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT }
|
||||||
|
save={ save }
|
||||||
|
cardStyle={ { width: 400 } }
|
||||||
|
footer={ <WiredSourcesSelector showFurni={ true } furniSource={ furniSource } onChangeFurni={ value => setFurniSource(normalizeFurniSource(value)) } /> }>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<Text>{ LocalizeText('wiredfurni.params.texts.placeholder_name') }</Text>
|
||||||
|
<NitroInput maxLength={ MAX_PLACEHOLDER_NAME_LENGTH } type="text" value={ placeholderName } onChange={ event => setPlaceholderName(normalizePlaceholderName(event.target.value)) } />
|
||||||
|
</div>
|
||||||
|
<Text dangerouslySetInnerHTML={ { __html: previewHtml } } />
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<Text>{ LocalizeText('wiredfurni.params.texts.placeholder_type') }</Text>
|
||||||
|
<label className="flex items-center gap-1 cursor-pointer">
|
||||||
|
<input checked={ (placeholderType === TYPE_SINGLE) } className="form-check-input" name="wiredTextOutputFurniNameType" type="radio" onChange={ () => setPlaceholderType(TYPE_SINGLE) } />
|
||||||
|
<Text>{ LocalizeText('wiredfurni.params.texts.placeholder_type.1') }</Text>
|
||||||
|
</label>
|
||||||
|
<label className="flex items-center gap-1 cursor-pointer">
|
||||||
|
<input checked={ (placeholderType === TYPE_MULTIPLE) } className="form-check-input" name="wiredTextOutputFurniNameType" type="radio" onChange={ () => setPlaceholderType(TYPE_MULTIPLE) } />
|
||||||
|
<Text>{ LocalizeText('wiredfurni.params.texts.placeholder_type.2') }</Text>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{ placeholderType === TYPE_MULTIPLE &&
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<Text>{ LocalizeText('wiredfurni.params.texts.select_delimiter') }</Text>
|
||||||
|
<NitroInput maxLength={ MAX_DELIMITER_LENGTH } type="text" value={ delimiter } onChange={ event => setDelimiter(normalizeDelimiter(event.target.value)) } />
|
||||||
|
</div> }
|
||||||
|
</div>
|
||||||
|
</WiredExtraBaseView>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user