mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 07:26:19 +00:00
feat(wired-ui): expand advanced wired editors
This commit is contained in:
@@ -5,31 +5,43 @@ import { Button, LayoutAvatarImageView, Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { NitroInput } from '../../../../layout';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { BOT_SOURCES, WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
const DEFAULT_FIGURE: string = 'hd-180-1.ch-210-66.lg-270-82.sh-290-81';
|
||||
const normalizeBotSource = (value: number, hasBotName = false) => (BOT_SOURCES.some(option => (option.value === value)) ? value : (hasBotName ? 100 : 0));
|
||||
|
||||
export const WiredActionBotChangeFigureView: FC<{}> = props =>
|
||||
{
|
||||
const [ botName, setBotName ] = useState('');
|
||||
const [ figure, setFigure ] = useState('');
|
||||
const { trigger = null, setStringParam = null } = useWired();
|
||||
const [ botSource, setBotSource ] = useState<number>(100);
|
||||
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
|
||||
|
||||
const save = () => setStringParam((botName + WIRED_STRING_DELIMETER + figure));
|
||||
const save = () =>
|
||||
{
|
||||
setStringParam(((botSource === 100) ? botName : '') + WIRED_STRING_DELIMETER + figure);
|
||||
setIntParams([ botSource ]);
|
||||
};
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const data = trigger.stringData.split(WIRED_STRING_DELIMETER);
|
||||
const nextBotName = (data.length > 0) ? data[0] : '';
|
||||
|
||||
if(data.length > 0) setBotName(data[0]);
|
||||
if(data.length > 0) setBotName(nextBotName);
|
||||
if(data.length > 1) setFigure(data[1].length > 0 ? data[1] : DEFAULT_FIGURE);
|
||||
else setFigure(DEFAULT_FIGURE);
|
||||
|
||||
setBotSource((trigger.intData.length > 0) ? normalizeBotSource(trigger.intData[0], (nextBotName.length > 0)) : normalizeBotSource(-1, (nextBotName.length > 0)));
|
||||
}, [ trigger ]);
|
||||
|
||||
return (
|
||||
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div>
|
||||
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save } footer={ <WiredSourcesSelector showUsers={ true } userSource={ botSource } userSources={ BOT_SOURCES } usersTitle="wiredfurni.params.sources.users.title.bots" onChangeUsers={ value => setBotSource(normalizeBotSource(value, (botName.length > 0))) } /> }>
|
||||
{ (botSource === 100) &&
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div> }
|
||||
<div className="flex items-center justify-center">
|
||||
<LayoutAvatarImageView direction={ 4 } figure={ figure } />
|
||||
<Button onClick={ event => setFigure(GetSessionDataManager().figure) }>{ LocalizeText('wiredfurni.params.capture.figure') }</Button>
|
||||
|
||||
@@ -4,13 +4,16 @@ import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { NitroInput } from '../../../../layout';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
import { BOT_SOURCES, WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
const normalizeBotSource = (value: number, hasBotName = false) => (BOT_SOURCES.some(option => (option.value === value)) ? value : (hasBotName ? 100 : 0));
|
||||
|
||||
export const WiredActionBotFollowAvatarView: FC<{}> = props =>
|
||||
{
|
||||
const [ botName, setBotName ] = useState('');
|
||||
const [ followMode, setFollowMode ] = useState(-1);
|
||||
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
|
||||
const [ botSource, setBotSource ] = useState<number>(100);
|
||||
const [ userSource, setUserSource ] = useState<number>(() =>
|
||||
{
|
||||
if(trigger?.intData?.length > 1) return trigger.intData[1];
|
||||
@@ -19,15 +22,17 @@ export const WiredActionBotFollowAvatarView: FC<{}> = props =>
|
||||
|
||||
const save = () =>
|
||||
{
|
||||
setStringParam(botName);
|
||||
setIntParams([ followMode, userSource ]);
|
||||
setStringParam((botSource === 100) ? botName : '');
|
||||
setIntParams([ followMode, userSource, botSource ]);
|
||||
};
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setBotName(trigger.stringData);
|
||||
const nextBotName = trigger.stringData || '';
|
||||
setBotName(nextBotName);
|
||||
setFollowMode((trigger.intData.length > 0) ? trigger.intData[0] : 0);
|
||||
setUserSource((trigger.intData.length > 1) ? trigger.intData[1] : 0);
|
||||
setBotSource((trigger.intData.length > 2) ? normalizeBotSource(trigger.intData[2], (nextBotName.length > 0)) : normalizeBotSource(-1, (nextBotName.length > 0)));
|
||||
}, [ trigger ]);
|
||||
|
||||
return (
|
||||
@@ -35,11 +40,18 @@ export const WiredActionBotFollowAvatarView: FC<{}> = props =>
|
||||
hasSpecialInput={ true }
|
||||
requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE }
|
||||
save={ save }
|
||||
footer={ <WiredSourcesSelector showUsers={ true } userSource={ userSource } onChangeUsers={ setUserSource } /> }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div>
|
||||
footer={
|
||||
<div className="flex flex-col gap-2">
|
||||
<WiredSourcesSelector showUsers={ true } userSource={ userSource } onChangeUsers={ setUserSource } />
|
||||
<hr className="m-0 bg-dark" />
|
||||
<WiredSourcesSelector showUsers={ true } userSource={ botSource } userSources={ BOT_SOURCES } usersTitle="wiredfurni.params.sources.users.title.bots" onChangeUsers={ value => setBotSource(normalizeBotSource(value, (botName.length > 0))) } />
|
||||
</div>
|
||||
}>
|
||||
{ (botSource === 100) &&
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div> }
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-center gap-1">
|
||||
<input checked={ (followMode === 1) } className="form-check-input" id="followMode1" name="followMode" type="radio" onChange={ event => setFollowMode(1) } />
|
||||
|
||||
@@ -4,32 +4,47 @@ import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { NitroInput } from '../../../../layout';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
import { WiredSourceOption, WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
import { WiredHandItemField } from '../WiredHandItemField';
|
||||
|
||||
const ALLOWED_HAND_ITEM_IDS: number[] = [ 2, 5, 7, 8, 9, 10, 27 ];
|
||||
const USER_SOURCE_OPTIONS: WiredSourceOption[] = [
|
||||
{ value: 0, label: 'wiredfurni.params.sources.users.0' },
|
||||
{ value: 200, label: 'wiredfurni.params.sources.users.200' },
|
||||
{ value: 201, label: 'wiredfurni.params.sources.users.201' }
|
||||
];
|
||||
|
||||
const BOT_SOURCE_OPTIONS: WiredSourceOption[] = [
|
||||
{ value: 0, label: 'wiredfurni.params.sources.users.0' },
|
||||
{ value: 100, label: 'wiredfurni.params.sources.users.100' },
|
||||
{ value: 200, label: 'wiredfurni.params.sources.users.200' },
|
||||
{ value: 201, label: 'wiredfurni.params.sources.users.201' }
|
||||
];
|
||||
|
||||
const normalizeUserSource = (value: number) => (USER_SOURCE_OPTIONS.some(option => (option.value === value)) ? value : 0);
|
||||
const normalizeBotSource = (value: number, hasBotName = false) => (BOT_SOURCE_OPTIONS.some(option => (option.value === value)) ? value : (hasBotName ? 100 : 0));
|
||||
|
||||
export const WiredActionBotGiveHandItemView: FC<{}> = props =>
|
||||
{
|
||||
const [ botName, setBotName ] = useState('');
|
||||
const [ handItemId, setHandItemId ] = useState(-1);
|
||||
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
|
||||
const [ userSource, setUserSource ] = useState<number>(() =>
|
||||
{
|
||||
if(trigger?.intData?.length > 1) return trigger.intData[1];
|
||||
return 0;
|
||||
});
|
||||
const [ userSource, setUserSource ] = useState<number>(0);
|
||||
const [ botSource, setBotSource ] = useState<number>(100);
|
||||
|
||||
const save = () =>
|
||||
{
|
||||
setStringParam(botName);
|
||||
setIntParams([ handItemId, userSource ]);
|
||||
setStringParam((botSource === 100) ? botName : '');
|
||||
setIntParams([ handItemId, userSource, botSource ]);
|
||||
};
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setBotName(trigger.stringData);
|
||||
const nextBotName = trigger.stringData || '';
|
||||
|
||||
setBotName(nextBotName);
|
||||
setHandItemId((trigger.intData.length > 0) ? trigger.intData[0] : 0);
|
||||
setUserSource((trigger.intData.length > 1) ? trigger.intData[1] : 0);
|
||||
setUserSource((trigger.intData.length > 1) ? normalizeUserSource(trigger.intData[1]) : 0);
|
||||
setBotSource((trigger.intData.length > 2) ? normalizeBotSource(trigger.intData[2], (nextBotName.length > 0)) : normalizeBotSource(-1, (nextBotName.length > 0)));
|
||||
}, [ trigger ]);
|
||||
|
||||
return (
|
||||
@@ -37,18 +52,23 @@ export const WiredActionBotGiveHandItemView: FC<{}> = props =>
|
||||
hasSpecialInput={ true }
|
||||
requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE }
|
||||
save={ save }
|
||||
footer={ <WiredSourcesSelector showUsers={ true } userSource={ userSource } onChangeUsers={ setUserSource } /> }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.handitem') }</Text>
|
||||
<select className="form-select form-select-sm" value={ handItemId } onChange={ event => setHandItemId(parseInt(event.target.value)) }>
|
||||
<option value="0">------</option>
|
||||
{ ALLOWED_HAND_ITEM_IDS.map(value => <option key={ value } value={ value }>{ LocalizeText(`handitem${ value }`) }</option>) }
|
||||
</select>
|
||||
footer={
|
||||
<div className="flex flex-col gap-2">
|
||||
<WiredSourcesSelector showUsers={ true } userSource={ userSource } userSources={ USER_SOURCE_OPTIONS } onChangeUsers={ setUserSource } />
|
||||
<hr className="m-0 bg-dark" />
|
||||
<WiredSourcesSelector showUsers={ true } userSource={ botSource } userSources={ BOT_SOURCE_OPTIONS } usersTitle="wiredfurni.params.sources.users.title.bots" onChangeUsers={ value => setBotSource(normalizeBotSource(value, (botName.length > 0))) } />
|
||||
</div>
|
||||
}>
|
||||
<div className="form-check">
|
||||
<input checked={ (botSource === 100) } className="form-check-input" id="botGiveHandItemUseNamedBot" type="checkbox" onChange={ event => setBotSource(event.target.checked ? 100 : 0) } />
|
||||
<label className="form-check-label" htmlFor="botGiveHandItemUseNamedBot">{ LocalizeText('wiredfurni.params.bot.usage') }</label>
|
||||
</div>
|
||||
{ (botSource === 100) &&
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div> }
|
||||
<WiredHandItemField handItemId={ handItemId } onChange={ setHandItemId } showCopyButton={ true } />
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,11 +4,14 @@ import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { NitroInput } from '../../../../layout';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
import { BOT_SOURCES, WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
const normalizeBotSource = (value: number, hasBotName = false) => (BOT_SOURCES.some(option => (option.value === value)) ? value : (hasBotName ? 100 : 0));
|
||||
|
||||
export const WiredActionBotMoveView: FC<{}> = props =>
|
||||
{
|
||||
const [ botName, setBotName ] = useState('');
|
||||
const [ botSource, setBotSource ] = useState<number>(100);
|
||||
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
|
||||
|
||||
const [ furniSource, setFurniSource ] = useState<number>(() =>
|
||||
@@ -19,18 +22,21 @@ export const WiredActionBotMoveView: FC<{}> = props =>
|
||||
|
||||
const save = () =>
|
||||
{
|
||||
setStringParam(botName);
|
||||
setIntParams([ furniSource ]);
|
||||
setStringParam((botSource === 100) ? botName : '');
|
||||
setIntParams([ furniSource, botSource ]);
|
||||
};
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!trigger) return;
|
||||
|
||||
setBotName(trigger.stringData);
|
||||
const nextBotName = trigger.stringData || '';
|
||||
setBotName(nextBotName);
|
||||
|
||||
if(trigger.intData.length >= 1) setFurniSource(trigger.intData[0]);
|
||||
else setFurniSource((trigger.selectedItems?.length ?? 0) > 0 ? 100 : 0);
|
||||
|
||||
setBotSource((trigger.intData.length >= 2) ? normalizeBotSource(trigger.intData[1], (nextBotName.length > 0)) : normalizeBotSource(-1, (nextBotName.length > 0)));
|
||||
}, [ trigger ]);
|
||||
|
||||
const onChangeFurniSource = (next: number) => setFurniSource(next);
|
||||
@@ -42,11 +48,18 @@ export const WiredActionBotMoveView: FC<{}> = props =>
|
||||
hasSpecialInput={ true }
|
||||
requiresFurni={ requiresFurni }
|
||||
save={ save }
|
||||
footer={ <WiredSourcesSelector showFurni={ true } furniSource={ furniSource } onChangeFurni={ onChangeFurniSource } /> }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div>
|
||||
footer={
|
||||
<div className="flex flex-col gap-2">
|
||||
<WiredSourcesSelector showFurni={ true } furniSource={ furniSource } onChangeFurni={ onChangeFurniSource } />
|
||||
<hr className="m-0 bg-dark" />
|
||||
<WiredSourcesSelector showUsers={ true } userSource={ botSource } userSources={ BOT_SOURCES } usersTitle="wiredfurni.params.sources.users.title.bots" onChangeUsers={ value => setBotSource(normalizeBotSource(value, (botName.length > 0))) } />
|
||||
</div>
|
||||
}>
|
||||
{ (botSource === 100) &&
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div> }
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,13 +4,16 @@ import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { NitroInput } from '../../../../layout';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
import { BOT_SOURCES, WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
const normalizeBotSource = (value: number, hasBotName = false) => (BOT_SOURCES.some(option => (option.value === value)) ? value : (hasBotName ? 100 : 0));
|
||||
|
||||
export const WiredActionBotTalkToAvatarView: FC<{}> = props =>
|
||||
{
|
||||
const [ botName, setBotName ] = useState('');
|
||||
const [ message, setMessage ] = useState('');
|
||||
const [ talkMode, setTalkMode ] = useState(-1);
|
||||
const [ botSource, setBotSource ] = useState<number>(100);
|
||||
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
|
||||
const [ userSource, setUserSource ] = useState<number>(() =>
|
||||
{
|
||||
@@ -20,19 +23,21 @@ export const WiredActionBotTalkToAvatarView: FC<{}> = props =>
|
||||
|
||||
const save = () =>
|
||||
{
|
||||
setStringParam(botName + WIRED_STRING_DELIMETER + message);
|
||||
setIntParams([ talkMode, userSource ]);
|
||||
setStringParam(((botSource === 100) ? botName : '') + WIRED_STRING_DELIMETER + message);
|
||||
setIntParams([ talkMode, userSource, botSource ]);
|
||||
};
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const data = trigger.stringData.split(WIRED_STRING_DELIMETER);
|
||||
const nextBotName = (data.length > 0) ? data[0] : '';
|
||||
|
||||
if(data.length > 0) setBotName(data[0]);
|
||||
if(data.length > 0) setBotName(nextBotName);
|
||||
if(data.length > 1) setMessage(data[1].length > 0 ? data[1] : '');
|
||||
|
||||
setTalkMode((trigger.intData.length > 0) ? trigger.intData[0] : 0);
|
||||
setUserSource((trigger.intData.length > 1) ? trigger.intData[1] : 0);
|
||||
setBotSource((trigger.intData.length > 2) ? normalizeBotSource(trigger.intData[2], (nextBotName.length > 0)) : normalizeBotSource(-1, (nextBotName.length > 0)));
|
||||
}, [ trigger ]);
|
||||
|
||||
return (
|
||||
@@ -40,11 +45,18 @@ export const WiredActionBotTalkToAvatarView: FC<{}> = props =>
|
||||
hasSpecialInput={ true }
|
||||
requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE }
|
||||
save={ save }
|
||||
footer={ <WiredSourcesSelector showUsers={ true } userSource={ userSource } onChangeUsers={ setUserSource } /> }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div>
|
||||
footer={
|
||||
<div className="flex flex-col gap-2">
|
||||
<WiredSourcesSelector showUsers={ true } userSource={ userSource } onChangeUsers={ setUserSource } />
|
||||
<hr className="m-0 bg-dark" />
|
||||
<WiredSourcesSelector showUsers={ true } userSource={ botSource } userSources={ BOT_SOURCES } usersTitle="wiredfurni.params.sources.users.title.bots" onChangeUsers={ value => setBotSource(normalizeBotSource(value, (botName.length > 0))) } />
|
||||
</div>
|
||||
}>
|
||||
{ (botSource === 100) &&
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div> }
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.message') }</Text>
|
||||
<NitroInput maxLength={ GetConfigurationValue<number>('wired.action.bot.talk.to.avatar.max.length', 64) } type="text" value={ message } onChange={ event => setMessage(event.target.value) } />
|
||||
|
||||
@@ -4,36 +4,43 @@ import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { NitroInput } from '../../../../layout';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { BOT_SOURCES, WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
const normalizeBotSource = (value: number, hasBotName = false) => (BOT_SOURCES.some(option => (option.value === value)) ? value : (hasBotName ? 100 : 0));
|
||||
|
||||
export const WiredActionBotTalkView: FC<{}> = props =>
|
||||
{
|
||||
const [ botName, setBotName ] = useState('');
|
||||
const [ message, setMessage ] = useState('');
|
||||
const [ talkMode, setTalkMode ] = useState(-1);
|
||||
const [ botSource, setBotSource ] = useState<number>(100);
|
||||
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
|
||||
|
||||
const save = () =>
|
||||
{
|
||||
setStringParam(botName + WIRED_STRING_DELIMETER + message);
|
||||
setIntParams([ talkMode ]);
|
||||
setStringParam(((botSource === 100) ? botName : '') + WIRED_STRING_DELIMETER + message);
|
||||
setIntParams([ talkMode, botSource ]);
|
||||
};
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const data = trigger.stringData.split(WIRED_STRING_DELIMETER);
|
||||
const nextBotName = (data.length > 0) ? data[0] : '';
|
||||
|
||||
if(data.length > 0) setBotName(data[0]);
|
||||
if(data.length > 0) setBotName(nextBotName);
|
||||
if(data.length > 1) setMessage(data[1].length > 0 ? data[1] : '');
|
||||
|
||||
setTalkMode((trigger.intData.length > 0) ? trigger.intData[0] : 0);
|
||||
setBotSource((trigger.intData.length > 1) ? normalizeBotSource(trigger.intData[1], (nextBotName.length > 0)) : normalizeBotSource(-1, (nextBotName.length > 0)));
|
||||
}, [ trigger ]);
|
||||
|
||||
return (
|
||||
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div>
|
||||
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save } footer={ <WiredSourcesSelector showUsers={ true } userSource={ botSource } userSources={ BOT_SOURCES } usersTitle="wiredfurni.params.sources.users.title.bots" onChangeUsers={ value => setBotSource(normalizeBotSource(value, (botName.length > 0))) } /> }>
|
||||
{ (botSource === 100) &&
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div> }
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.message') }</Text>
|
||||
<NitroInput maxLength={ GetConfigurationValue<number>('wired.action.bot.talk.max.length', 64) } type="text" value={ message } onChange={ event => setMessage(event.target.value) } />
|
||||
|
||||
@@ -4,11 +4,14 @@ import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { NitroInput } from '../../../../layout';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
import { BOT_SOURCES, WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
const normalizeBotSource = (value: number, hasBotName = false) => (BOT_SOURCES.some(option => (option.value === value)) ? value : (hasBotName ? 100 : 0));
|
||||
|
||||
export const WiredActionBotTeleportView: FC<{}> = props =>
|
||||
{
|
||||
const [ botName, setBotName ] = useState('');
|
||||
const [ botSource, setBotSource ] = useState<number>(100);
|
||||
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
|
||||
|
||||
const [ furniSource, setFurniSource ] = useState<number>(() =>
|
||||
@@ -19,18 +22,21 @@ export const WiredActionBotTeleportView: FC<{}> = props =>
|
||||
|
||||
const save = () =>
|
||||
{
|
||||
setStringParam(botName);
|
||||
setIntParams([ furniSource ]);
|
||||
setStringParam((botSource === 100) ? botName : '');
|
||||
setIntParams([ furniSource, botSource ]);
|
||||
};
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!trigger) return;
|
||||
|
||||
setBotName(trigger.stringData);
|
||||
const nextBotName = trigger.stringData || '';
|
||||
setBotName(nextBotName);
|
||||
|
||||
if(trigger.intData.length >= 1) setFurniSource(trigger.intData[0]);
|
||||
else setFurniSource((trigger.selectedItems?.length ?? 0) > 0 ? 100 : 0);
|
||||
|
||||
setBotSource((trigger.intData.length >= 2) ? normalizeBotSource(trigger.intData[1], (nextBotName.length > 0)) : normalizeBotSource(-1, (nextBotName.length > 0)));
|
||||
}, [ trigger ]);
|
||||
|
||||
const onChangeFurniSource = (next: number) => setFurniSource(next);
|
||||
@@ -42,11 +48,18 @@ export const WiredActionBotTeleportView: FC<{}> = props =>
|
||||
hasSpecialInput={ true }
|
||||
requiresFurni={ requiresFurni }
|
||||
save={ save }
|
||||
footer={ <WiredSourcesSelector showFurni={ true } furniSource={ furniSource } onChangeFurni={ onChangeFurniSource } /> }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div>
|
||||
footer={
|
||||
<div className="flex flex-col gap-2">
|
||||
<WiredSourcesSelector showFurni={ true } furniSource={ furniSource } onChangeFurni={ onChangeFurniSource } />
|
||||
<hr className="m-0 bg-dark" />
|
||||
<WiredSourcesSelector showUsers={ true } userSource={ botSource } userSources={ BOT_SOURCES } usersTitle="wiredfurni.params.sources.users.title.bots" onChangeUsers={ value => setBotSource(normalizeBotSource(value, (botName.length > 0))) } />
|
||||
</div>
|
||||
}>
|
||||
{ (botSource === 100) &&
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
|
||||
<NitroInput maxLength={ 32 } type="text" value={ botName } onChange={ event => setBotName(event.target.value) } />
|
||||
</div> }
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,24 +7,24 @@ import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
export const WiredActionGiveScoreToPredefinedTeamView: FC<{}> = props =>
|
||||
{
|
||||
const [ points, setPoints ] = useState(1);
|
||||
const [ time, setTime ] = useState(1);
|
||||
const [ operation, setOperation ] = useState(0);
|
||||
const [ selectedTeam, setSelectedTeam ] = useState(1);
|
||||
const { trigger = null, setIntParams = null } = useWired();
|
||||
|
||||
const save = () => setIntParams([ points, time, selectedTeam ]);
|
||||
const save = () => setIntParams([ points, operation, selectedTeam ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(trigger.intData.length >= 2)
|
||||
if(trigger.intData.length >= 3)
|
||||
{
|
||||
setPoints(trigger.intData[0]);
|
||||
setTime(trigger.intData[1]);
|
||||
setOperation(trigger.intData[1]);
|
||||
setSelectedTeam(trigger.intData[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
setPoints(1);
|
||||
setTime(1);
|
||||
setOperation(0);
|
||||
setSelectedTeam(1);
|
||||
}
|
||||
}, [ trigger ]);
|
||||
@@ -40,12 +40,13 @@ export const WiredActionGiveScoreToPredefinedTeamView: FC<{}> = props =>
|
||||
onChange={ event => setPoints(event) } />
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.settimesingame', [ 'times' ], [ time.toString() ]) }</Text>
|
||||
<Slider
|
||||
max={ 10 }
|
||||
min={ 1 }
|
||||
value={ time }
|
||||
onChange={ event => setTime(event) } />
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.choose_type') }</Text>
|
||||
{ [ 0, 1 ].map(value => (
|
||||
<label key={ value } className="flex items-center gap-1">
|
||||
<input checked={ (operation === value) } className="form-check-input" name="pointsOperation" type="radio" onChange={ () => setOperation(value) } />
|
||||
<Text>{ LocalizeText(`wiredfurni.params.points_operation.${ value }`) }</Text>
|
||||
</label>
|
||||
)) }
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.team') }</Text>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
export const WiredActionGiveScoreView: FC<{}> = props =>
|
||||
{
|
||||
const [ points, setPoints ] = useState(1);
|
||||
const [ time, setTime ] = useState(1);
|
||||
const [ operation, setOperation ] = useState(0);
|
||||
const { trigger = null, setIntParams = null } = useWired();
|
||||
const [ userSource, setUserSource ] = useState<number>(() =>
|
||||
{
|
||||
@@ -16,19 +16,19 @@ export const WiredActionGiveScoreView: FC<{}> = props =>
|
||||
return 0;
|
||||
});
|
||||
|
||||
const save = () => setIntParams([ points, time, userSource ]);
|
||||
const save = () => setIntParams([ points, operation, userSource ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(trigger.intData.length >= 2)
|
||||
{
|
||||
setPoints(trigger.intData[0]);
|
||||
setTime(trigger.intData[1]);
|
||||
setOperation(trigger.intData[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
setPoints(1);
|
||||
setTime(1);
|
||||
setOperation(0);
|
||||
}
|
||||
|
||||
setUserSource((trigger.intData.length > 2) ? trigger.intData[2] : 0);
|
||||
@@ -49,12 +49,13 @@ export const WiredActionGiveScoreView: FC<{}> = props =>
|
||||
onChange={ event => setPoints(event) } />
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.settimesingame', [ 'times' ], [ time.toString() ]) }</Text>
|
||||
<Slider
|
||||
max={ 10 }
|
||||
min={ 1 }
|
||||
value={ time }
|
||||
onChange={ event => setTime(event) } />
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.choose_type') }</Text>
|
||||
{ [ 0, 1 ].map(value => (
|
||||
<label key={ value } className="flex items-center gap-1">
|
||||
<input checked={ (operation === value) } className="form-check-input" name="pointsOperation" type="radio" onChange={ () => setOperation(value) } />
|
||||
<Text>{ LocalizeText(`wiredfurni.params.points_operation.${ value }`) }</Text>
|
||||
</label>
|
||||
)) }
|
||||
</div>
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
|
||||
@@ -7,20 +7,32 @@ import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
export const WiredActionJoinTeamView: FC<{}> = props =>
|
||||
{
|
||||
const [ selectedTeam, setSelectedTeam ] = useState(-1);
|
||||
const [ selectedTeamType, setSelectedTeamType ] = useState(0);
|
||||
const [ selectedTeam, setSelectedTeam ] = useState(1);
|
||||
const { trigger = null, setIntParams = null } = useWired();
|
||||
const [ userSource, setUserSource ] = useState<number>(() =>
|
||||
{
|
||||
if(trigger?.intData?.length > 2) return trigger.intData[2];
|
||||
if(trigger?.intData?.length > 1) return trigger.intData[1];
|
||||
return 0;
|
||||
});
|
||||
|
||||
const save = () => setIntParams([ selectedTeam, userSource ]);
|
||||
const save = () => setIntParams([ selectedTeamType, selectedTeam, userSource ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setSelectedTeam((trigger.intData.length > 0) ? trigger.intData[0] : 0);
|
||||
setUserSource((trigger.intData.length > 1) ? trigger.intData[1] : 0);
|
||||
if(trigger.intData.length > 2)
|
||||
{
|
||||
setSelectedTeamType(trigger.intData[0]);
|
||||
setSelectedTeam(trigger.intData[1]);
|
||||
setUserSource(trigger.intData[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
setSelectedTeamType(0);
|
||||
setSelectedTeam((trigger.intData.length > 0) ? trigger.intData[0] : 1);
|
||||
setUserSource((trigger.intData.length > 1) ? trigger.intData[1] : 0);
|
||||
}
|
||||
}, [ trigger ]);
|
||||
|
||||
return (
|
||||
@@ -29,6 +41,22 @@ export const WiredActionJoinTeamView: FC<{}> = props =>
|
||||
requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE }
|
||||
save={ save }
|
||||
footer={ <WiredSourcesSelector showUsers={ true } userSource={ userSource } onChangeUsers={ setUserSource } /> }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.choose_type') }</Text>
|
||||
{ [
|
||||
{ value: 0, label: 'Wired' },
|
||||
{ value: 1, label: 'Banzai' },
|
||||
{ value: 2, label: 'Freeze' }
|
||||
].map(option =>
|
||||
{
|
||||
return (
|
||||
<div key={ option.value } className="flex gap-1">
|
||||
<input checked={ (selectedTeamType === option.value) } className="form-check-input" id={ `selectedTeamType${ option.value }` } name="selectedTeamType" type="radio" onChange={ () => setSelectedTeamType(option.value) } />
|
||||
<Text>{ option.label }</Text>
|
||||
</div>
|
||||
);
|
||||
}) }
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.team') }</Text>
|
||||
{ [ 1, 2, 3, 4 ].map(team =>
|
||||
|
||||
@@ -9,8 +9,20 @@ import { WiredActionSendSignalView } from './WiredActionSendSignalView';
|
||||
import { WiredActionFurniAreaView } from '../selectors/WiredActionFurniAreaView';
|
||||
import { WiredSelectorFurniNeighborhoodView } from '../selectors/WiredSelectorFurniNeighborhoodView';
|
||||
import { WiredSelectorFurniByTypeView } from '../selectors/WiredSelectorFurniByTypeView';
|
||||
import { WiredSelectorFurniAltitudeView } from '../selectors/WiredSelectorFurniAltitudeView';
|
||||
import { WiredSelectorFurniOnFurniView } from '../selectors/WiredSelectorFurniOnFurniView';
|
||||
import { WiredSelectorFurniPicksView } from '../selectors/WiredSelectorFurniPicksView';
|
||||
import { WiredSelectorFurniSignalView } from '../selectors/WiredSelectorFurniSignalView';
|
||||
import { WiredSelectorUsersAreaView } from '../selectors/WiredSelectorUsersAreaView';
|
||||
import { WiredSelectorUsersByTypeView } from '../selectors/WiredSelectorUsersByTypeView';
|
||||
import { WiredSelectorUsersByActionView } from '../selectors/WiredSelectorUsersByActionView';
|
||||
import { WiredSelectorUsersByNameView } from '../selectors/WiredSelectorUsersByNameView';
|
||||
import { WiredSelectorUsersOnFurniView } from '../selectors/WiredSelectorUsersOnFurniView';
|
||||
import { WiredSelectorUsersGroupView } from '../selectors/WiredSelectorUsersGroupView';
|
||||
import { WiredSelectorUsersHandItemView } from '../selectors/WiredSelectorUsersHandItemView';
|
||||
import { WiredSelectorUsersNeighborhoodView } from '../selectors/WiredSelectorUsersNeighborhoodView';
|
||||
import { WiredSelectorUsersSignalView } from '../selectors/WiredSelectorUsersSignalView';
|
||||
import { WiredSelectorUsersTeamView } from '../selectors/WiredSelectorUsersTeamView';
|
||||
import { WiredActionBotFollowAvatarView } from './WiredActionBotFollowAvatarView';
|
||||
import { WiredActionBotGiveHandItemView } from './WiredActionBotGiveHandItemView';
|
||||
import { WiredActionBotMoveView } from './WiredActionBotMoveView';
|
||||
@@ -28,6 +40,7 @@ import { WiredActionJoinTeamView } from './WiredActionJoinTeamView';
|
||||
import { WiredActionKickFromRoomView } from './WiredActionKickFromRoomView';
|
||||
import { WiredActionLeaveTeamView } from './WiredActionLeaveTeamView';
|
||||
import { WiredActionMoveAndRotateFurniView } from './WiredActionMoveAndRotateFurniView';
|
||||
import { WiredActionMoveRotateUserView } from './WiredActionMoveRotateUserView';
|
||||
import { WiredActionMoveFurniToView } from './WiredActionMoveFurniToView';
|
||||
import { WiredActionMoveFurniView } from './WiredActionMoveFurniView';
|
||||
import { WiredActionMuteUserView } from './WiredActionMuteUserView';
|
||||
@@ -37,6 +50,8 @@ import { WiredActionSetFurniStateToView } from './WiredActionSetFurniStateToView
|
||||
import { WiredActionTeleportView } from './WiredActionTeleportView';
|
||||
import { WiredActionToggleFurniStateView } from './WiredActionToggleFurniStateView';
|
||||
import { WiredActionUnfreezeView } from './WiredActionUnfreezeView';
|
||||
import { WiredExtraFilterFurniView } from '../extras/WiredExtraFilterFurniView';
|
||||
import { WiredExtraFilterUserView } from '../extras/WiredExtraFilterUserView';
|
||||
|
||||
export const WiredActionLayoutView = (code: number) =>
|
||||
{
|
||||
@@ -92,6 +107,8 @@ export const WiredActionLayoutView = (code: number) =>
|
||||
return <WiredActionMoveFurniView />;
|
||||
case WiredActionLayoutCode.MOVE_AND_ROTATE_FURNI:
|
||||
return <WiredActionMoveAndRotateFurniView />;
|
||||
case WiredActionLayoutCode.MOVE_ROTATE_USER:
|
||||
return <WiredActionMoveRotateUserView />;
|
||||
case WiredActionLayoutCode.MOVE_FURNI_TO:
|
||||
return <WiredActionMoveFurniToView />;
|
||||
case WiredActionLayoutCode.MUTE_USER:
|
||||
@@ -116,10 +133,38 @@ export const WiredActionLayoutView = (code: number) =>
|
||||
return <WiredSelectorFurniNeighborhoodView />;
|
||||
case WiredActionLayoutCode.FURNI_BYTYPE_SELECTOR:
|
||||
return <WiredSelectorFurniByTypeView />;
|
||||
case WiredActionLayoutCode.FURNI_ALTITUDE_SELECTOR:
|
||||
return <WiredSelectorFurniAltitudeView />;
|
||||
case WiredActionLayoutCode.FURNI_ON_FURNI_SELECTOR:
|
||||
return <WiredSelectorFurniOnFurniView />;
|
||||
case WiredActionLayoutCode.FURNI_PICKS_SELECTOR:
|
||||
return <WiredSelectorFurniPicksView />;
|
||||
case WiredActionLayoutCode.FURNI_SIGNAL_SELECTOR:
|
||||
return <WiredSelectorFurniSignalView />;
|
||||
case WiredActionLayoutCode.USERS_AREA_SELECTOR:
|
||||
return <WiredSelectorUsersAreaView />;
|
||||
case WiredActionLayoutCode.USERS_NEIGHBORHOOD_SELECTOR:
|
||||
return <WiredSelectorUsersNeighborhoodView />;
|
||||
case WiredActionLayoutCode.USERS_SIGNAL_SELECTOR:
|
||||
return <WiredSelectorUsersSignalView />;
|
||||
case WiredActionLayoutCode.USERS_BY_TYPE_SELECTOR:
|
||||
return <WiredSelectorUsersByTypeView />;
|
||||
case WiredActionLayoutCode.USERS_BY_ACTION_SELECTOR:
|
||||
return <WiredSelectorUsersByActionView />;
|
||||
case WiredActionLayoutCode.USERS_BY_NAME_SELECTOR:
|
||||
return <WiredSelectorUsersByNameView />;
|
||||
case WiredActionLayoutCode.USERS_ON_FURNI_SELECTOR:
|
||||
return <WiredSelectorUsersOnFurniView />;
|
||||
case WiredActionLayoutCode.USERS_GROUP_SELECTOR:
|
||||
return <WiredSelectorUsersGroupView />;
|
||||
case WiredActionLayoutCode.USERS_HANDITEM_SELECTOR:
|
||||
return <WiredSelectorUsersHandItemView />;
|
||||
case WiredActionLayoutCode.USERS_TEAM_SELECTOR:
|
||||
return <WiredSelectorUsersTeamView />;
|
||||
case WiredActionLayoutCode.FILTER_FURNI_EXTRA:
|
||||
return <WiredExtraFilterFurniView />;
|
||||
case WiredActionLayoutCode.FILTER_USER_EXTRA:
|
||||
return <WiredExtraFilterUserView />;
|
||||
case WiredActionLayoutCode.SEND_SIGNAL:
|
||||
return <WiredActionSendSignalView />;
|
||||
}
|
||||
|
||||
@@ -2,34 +2,17 @@ import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeText, WiredFurniType } from '../../../../api';
|
||||
import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { WiredDirectionIcon, WIRED_DIRECTION_GRID } from '../WiredDirectionIcon';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
const directionOptions: { value: number, icon: string }[] = [
|
||||
{
|
||||
value: 0,
|
||||
icon: 'ne'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
icon: 'se'
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
icon: 'sw'
|
||||
},
|
||||
{
|
||||
value: 6,
|
||||
icon: 'nw'
|
||||
}
|
||||
];
|
||||
|
||||
const rotationOptions: number[] = [ 0, 1, 2, 3, 4, 5, 6 ];
|
||||
|
||||
export const WiredActionMoveAndRotateFurniView: FC<{}> = props =>
|
||||
{
|
||||
const [ movement, setMovement ] = useState(-1);
|
||||
const [ rotation, setRotation ] = useState(-1);
|
||||
const [ blockOnUserCollision, setBlockOnUserCollision ] = useState(false);
|
||||
const { trigger = null, setIntParams = null } = useWired();
|
||||
const [ furniSource, setFurniSource ] = useState<number>(() =>
|
||||
{
|
||||
@@ -37,7 +20,7 @@ export const WiredActionMoveAndRotateFurniView: FC<{}> = props =>
|
||||
return (trigger?.selectedItems?.length ?? 0) > 0 ? 100 : 0;
|
||||
});
|
||||
|
||||
const save = () => setIntParams([ movement, rotation, furniSource ]);
|
||||
const save = () => setIntParams([ movement, rotation, furniSource, blockOnUserCollision ? 1 : 0 ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@@ -54,6 +37,8 @@ export const WiredActionMoveAndRotateFurniView: FC<{}> = props =>
|
||||
|
||||
if(trigger.intData.length > 2) setFurniSource(trigger.intData[2]);
|
||||
else setFurniSource((trigger.selectedItems?.length ?? 0) > 0 ? 100 : 0);
|
||||
|
||||
setBlockOnUserCollision((trigger.intData?.length ?? 0) > 3 ? trigger.intData[3] === 1 : false);
|
||||
}, [ trigger ]);
|
||||
|
||||
const onChangeFurniSource = (next: number) => setFurniSource(next);
|
||||
@@ -68,18 +53,23 @@ export const WiredActionMoveAndRotateFurniView: FC<{}> = props =>
|
||||
footer={ <WiredSourcesSelector showFurni={ true } furniSource={ furniSource } onChangeFurni={ onChangeFurniSource } /> }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.startdir') }</Text>
|
||||
<div className="flex gap-1">
|
||||
{ directionOptions.map(option =>
|
||||
<div className="grid grid-cols-4 gap-2 max-w-[240px]">
|
||||
{ WIRED_DIRECTION_GRID.flatMap((row, rowIndex) => row.map((direction, columnIndex) =>
|
||||
{
|
||||
if(direction === null)
|
||||
{
|
||||
return <div key={ `move-to-dir-empty-${ rowIndex }-${ columnIndex }` } />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={ option.value } className="flex items-center gap-1">
|
||||
<input checked={ (movement === option.value) } className="form-check-input" id={ `movement${ option.value }` } name="movement" type="radio" onChange={ event => setMovement(option.value) } />
|
||||
<Text>
|
||||
<i className={ `icon icon-${ option.icon }` } />
|
||||
</Text>
|
||||
</div>
|
||||
<label key={ `move-to-dir-${ direction }` } className="flex items-center justify-center gap-[2px] cursor-pointer">
|
||||
<input checked={ (movement === direction) } className="form-check-input" id={ `movement${ direction }` } name="movement" type="radio" onChange={ () => setMovement(direction) } />
|
||||
<span className="inline-flex items-center justify-center">
|
||||
<WiredDirectionIcon direction={ direction } selected={ movement === direction } />
|
||||
</span>
|
||||
</label>
|
||||
);
|
||||
}) }
|
||||
})) }
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
@@ -94,6 +84,13 @@ export const WiredActionMoveAndRotateFurniView: FC<{}> = props =>
|
||||
);
|
||||
}) }
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.user_collide') }</Text>
|
||||
<label className="flex items-center gap-1 cursor-pointer">
|
||||
<input checked={ blockOnUserCollision } className="form-check-input" type="checkbox" onChange={ event => setBlockOnUserCollision(event.target.checked) } />
|
||||
<Text>{ LocalizeText('wiredfurni.params.user_collide.0') }</Text>
|
||||
</label>
|
||||
</div>
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,37 +2,44 @@ import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeText, WiredFurniType } from '../../../../api';
|
||||
import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import iconWiredDirE from '../../../../assets/images/wired/icon_wired_dir_e.png';
|
||||
import iconWiredDirHorizontalRandom from '../../../../assets/images/wired/icon_wired_dir_horizontal_random.png';
|
||||
import iconWiredDirN from '../../../../assets/images/wired/icon_wired_dir_n.png';
|
||||
import iconWiredDirNe from '../../../../assets/images/wired/icon_wired_dir_ne.png';
|
||||
import iconWiredDirNw from '../../../../assets/images/wired/icon_wired_dir_nw.png';
|
||||
import iconWiredDirRandom from '../../../../assets/images/wired/icon_wired_dir_random.png';
|
||||
import iconWiredDirS from '../../../../assets/images/wired/icon_wired_dir_s.png';
|
||||
import iconWiredDirSe from '../../../../assets/images/wired/icon_wired_dir_se.png';
|
||||
import iconWiredDirSw from '../../../../assets/images/wired/icon_wired_dir_sw.png';
|
||||
import iconWiredDirVerticalRandom from '../../../../assets/images/wired/icon_wired_dir_vertical_random.png';
|
||||
import iconWiredDirW from '../../../../assets/images/wired/icon_wired_dir_w.png';
|
||||
import { WiredDirectionIcon, WIRED_DIRECTION_GRID } from '../WiredDirectionIcon';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
const directionOptions: { value: number, icon: string }[] = [
|
||||
const NORMAL_DIRECTION_VALUE_MAP: Record<number, { value: number; icon: string }> = {
|
||||
0: { value: 6, icon: iconWiredDirN },
|
||||
1: { value: 8, icon: iconWiredDirNe },
|
||||
2: { value: 5, icon: iconWiredDirE },
|
||||
3: { value: 9, icon: iconWiredDirSe },
|
||||
4: { value: 4, icon: iconWiredDirS },
|
||||
5: { value: 10, icon: iconWiredDirSw },
|
||||
6: { value: 7, icon: iconWiredDirW },
|
||||
7: { value: 11, icon: iconWiredDirNw }
|
||||
};
|
||||
|
||||
const extraDirectionOptions: { value: number, icon: string }[] = [
|
||||
{
|
||||
value: 4,
|
||||
icon: 'ne'
|
||||
},
|
||||
{
|
||||
value: 5,
|
||||
icon: 'se'
|
||||
},
|
||||
{
|
||||
value: 6,
|
||||
icon: 'sw'
|
||||
},
|
||||
{
|
||||
value: 7,
|
||||
icon: 'nw'
|
||||
value: 1,
|
||||
icon: iconWiredDirRandom
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
icon: 'mv-2'
|
||||
icon: iconWiredDirHorizontalRandom
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
icon: 'mv-3'
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
icon: 'mv-1'
|
||||
icon: iconWiredDirVerticalRandom
|
||||
}
|
||||
];
|
||||
|
||||
@@ -84,17 +91,38 @@ export const WiredActionMoveFurniView: FC<{}> = props =>
|
||||
<input checked={ (movement === 0) } className="form-check-input" id="movement0" name="selectedTeam" type="radio" onChange={ event => setMovement(0) } />
|
||||
<Text>{ LocalizeText('wiredfurni.params.movefurni.0') }</Text>
|
||||
</div>
|
||||
<div className="flex gap-1">
|
||||
{ directionOptions.map(option =>
|
||||
<div className="grid grid-cols-4 gap-2 max-w-[240px]">
|
||||
{ WIRED_DIRECTION_GRID.flatMap((row, rowIndex) => row.map((direction, columnIndex) =>
|
||||
{
|
||||
if(direction === null)
|
||||
{
|
||||
return <div key={ `move-furni-empty-${ rowIndex }-${ columnIndex }` } />;
|
||||
}
|
||||
|
||||
const option = NORMAL_DIRECTION_VALUE_MAP[direction];
|
||||
|
||||
return (
|
||||
<label key={ `move-furni-${ direction }` } className="flex items-center justify-center gap-[2px] cursor-pointer">
|
||||
<input checked={ (movement === option.value) } className="form-check-input" id={ `movement${ option.value }` } name="movement" type="radio" onChange={ event => setMovement(option.value) } />
|
||||
<span className="inline-flex items-center justify-center">
|
||||
<WiredDirectionIcon direction={ option.value } iconSrc={ option.icon } selected={ movement === option.value } />
|
||||
</span>
|
||||
</label>
|
||||
);
|
||||
})) }
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{ extraDirectionOptions.map(option =>
|
||||
{
|
||||
return (
|
||||
<div key={ option.value } className="flex items-center gap-1">
|
||||
<label key={ `extra-${ option.value }` } className="flex items-center gap-[2px] cursor-pointer">
|
||||
<input checked={ (movement === option.value) } className="form-check-input" id={ `movement${ option.value }` } name="movement" type="radio" onChange={ event => setMovement(option.value) } />
|
||||
<i className={ `nitro.icon icon-${ option.icon }` } />
|
||||
</div>
|
||||
<span className="inline-flex items-center justify-center">
|
||||
<WiredDirectionIcon direction={ option.value } iconSrc={ option.icon } selected={ movement === option.value } />
|
||||
</span>
|
||||
</label>
|
||||
);
|
||||
}) }
|
||||
<div className="col" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeText, WiredFurniType } from '../../../../api';
|
||||
import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import iconRotateClockwise from '../../../../assets/images/wired/icon_wired_rotate_clockwise.png';
|
||||
import iconRotateCounterClockwise from '../../../../assets/images/wired/icon_wired_rotate_counter_clockwise.png';
|
||||
import { WiredDirectionIcon, WIRED_DIRECTION_GRID } from '../WiredDirectionIcon';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
const ROTATION_CLOCKWISE = 8;
|
||||
const ROTATION_COUNTER_CLOCKWISE = 9;
|
||||
|
||||
interface DirectionExtraOption
|
||||
{
|
||||
value: number;
|
||||
icon: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
interface DirectionPickerProps
|
||||
{
|
||||
name: string;
|
||||
title: string;
|
||||
noneLabel: string;
|
||||
value: number;
|
||||
onChange: (value: number) => void;
|
||||
extraOptions?: DirectionExtraOption[];
|
||||
}
|
||||
|
||||
const DirectionPicker: FC<DirectionPickerProps> = props =>
|
||||
{
|
||||
const { name = '', title = '', noneLabel = '', value = -1, onChange = null, extraOptions = [] } = props;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<Text bold>{ title }</Text>
|
||||
<label className="flex items-center gap-2 text-[12px]">
|
||||
<input checked={ (value === -1) } className="form-check-input" name={ name } type="radio" onChange={ () => onChange(-1) } />
|
||||
<span>{ noneLabel }</span>
|
||||
</label>
|
||||
<div className="grid grid-cols-4 gap-2 max-w-[240px]">
|
||||
{ WIRED_DIRECTION_GRID.flatMap((row, rowIndex) => row.map((direction, columnIndex) =>
|
||||
{
|
||||
if(direction === null)
|
||||
{
|
||||
return <div key={ `${ name }-empty-${ rowIndex }-${ columnIndex }` } />;
|
||||
}
|
||||
|
||||
const selected = (value === direction);
|
||||
|
||||
return (
|
||||
<label key={ `${ name }-${ direction }` } className="flex items-center justify-center gap-[2px] cursor-pointer">
|
||||
<input checked={ selected } className="form-check-input" name={ name } type="radio" onChange={ () => onChange(direction) } />
|
||||
<span className="inline-flex items-center justify-center">
|
||||
<WiredDirectionIcon direction={ direction } selected={ selected } />
|
||||
</span>
|
||||
</label>
|
||||
);
|
||||
})) }
|
||||
</div>
|
||||
{ extraOptions.length > 0 &&
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{ extraOptions.map(option => (
|
||||
<label key={ `${ name }-extra-${ option.value }` } className="flex items-center gap-[2px] cursor-pointer" title={ option.label }>
|
||||
<input checked={ (value === option.value) } className="form-check-input" name={ name } type="radio" onChange={ () => onChange(option.value) } />
|
||||
<img alt="" className="h-auto w-auto object-contain" draggable={ false } src={ option.icon } />
|
||||
</label>
|
||||
)) }
|
||||
</div> }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const WiredActionMoveRotateUserView: FC<{}> = props =>
|
||||
{
|
||||
const [ movementDirection, setMovementDirection ] = useState(-1);
|
||||
const [ rotationDirection, setRotationDirection ] = useState(-1);
|
||||
const { trigger = null, setIntParams = null } = useWired();
|
||||
const [ userSource, setUserSource ] = useState<number>(() =>
|
||||
{
|
||||
if(trigger?.intData?.length > 2) return trigger.intData[2];
|
||||
return 0;
|
||||
});
|
||||
|
||||
const save = () => setIntParams([ movementDirection, rotationDirection, userSource ]);
|
||||
|
||||
const rotationExtraOptions: DirectionExtraOption[] = [
|
||||
{ value: ROTATION_CLOCKWISE, icon: iconRotateClockwise, label: LocalizeText('wiredfurni.params.rotatefurni.1') },
|
||||
{ value: ROTATION_COUNTER_CLOCKWISE, icon: iconRotateCounterClockwise, label: LocalizeText('wiredfurni.params.rotatefurni.2') }
|
||||
];
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setMovementDirection((trigger.intData.length > 0) ? trigger.intData[0] : -1);
|
||||
setRotationDirection((trigger.intData.length > 1) ? trigger.intData[1] : -1);
|
||||
setUserSource((trigger.intData.length > 2) ? trigger.intData[2] : 0);
|
||||
}, [ trigger ]);
|
||||
|
||||
return (
|
||||
<WiredActionBaseView
|
||||
hasSpecialInput={ true }
|
||||
requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE }
|
||||
save={ save }
|
||||
footer={ <WiredSourcesSelector showUsers={ true } userSource={ userSource } onChangeUsers={ setUserSource } /> }>
|
||||
<DirectionPicker
|
||||
name="wired-move-user-direction"
|
||||
title={ LocalizeText('wiredfurni.params.moveuser') }
|
||||
noneLabel={ LocalizeText('wiredfurni.params.movefurni.0') }
|
||||
value={ movementDirection }
|
||||
onChange={ setMovementDirection } />
|
||||
<DirectionPicker
|
||||
name="wired-rotate-user-direction"
|
||||
title={ LocalizeText('wiredfurni.params.rotateuser') }
|
||||
noneLabel={ LocalizeText('wiredfurni.params.rotatefurni.0') }
|
||||
extraOptions={ rotationExtraOptions }
|
||||
value={ rotationDirection }
|
||||
onChange={ setRotationDirection } />
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { LocalizeText, WiredFurniType, WiredSelectionVisualizer } from '../../../../api';
|
||||
import { Button, Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
@@ -48,6 +48,7 @@ export const WiredActionSendSignalView: FC<{}> = () =>
|
||||
const [ antennaIds, setAntennaIds ] = useState<number[]>([]);
|
||||
const [ forwardFurniIds, setForwardFurniIds ] = useState<number[]>([]);
|
||||
const [ selectionMode, setSelectionMode ] = useState<SelectionMode>('antenna');
|
||||
const highlightedIds = useRef<number[]>([]);
|
||||
|
||||
const { trigger = null, furniIds = [], setFurniIds = null, setIntParams = null, setStringParam = null, setAllowedInteractionTypes = null } = useWired();
|
||||
|
||||
@@ -84,28 +85,39 @@ export const WiredActionSendSignalView: FC<{}> = () =>
|
||||
else setForwardFurniIds(furniIds);
|
||||
}, [ furniIds, selectionMode ]);
|
||||
|
||||
const applySelection = useCallback((nextIds: number[]) =>
|
||||
const syncHighlights = useCallback((nextAntennaIds: number[], nextForwardFurniIds: number[], nextSelectionMode: SelectionMode, nextFurniSource: number) =>
|
||||
{
|
||||
if(!setFurniIds) return;
|
||||
|
||||
setFurniIds(prev =>
|
||||
if(highlightedIds.current.length)
|
||||
{
|
||||
if(prev && prev.length) WiredSelectionVisualizer.clearSelectionShaderFromFurni(prev);
|
||||
if(nextIds && nextIds.length) WiredSelectionVisualizer.applySelectionShaderToFurni(nextIds);
|
||||
WiredSelectionVisualizer.clearSelectionShaderFromFurni(highlightedIds.current);
|
||||
WiredSelectionVisualizer.clearSecondarySelectionShaderFromFurni(highlightedIds.current);
|
||||
}
|
||||
|
||||
return [ ...nextIds ];
|
||||
});
|
||||
}, [ setFurniIds ]);
|
||||
const visibleForwardIds = (nextFurniSource === SOURCE_SELECTED) ? nextForwardFurniIds : [];
|
||||
const activeIds = (nextSelectionMode === 'antenna') ? nextAntennaIds : visibleForwardIds;
|
||||
const passiveIds = (nextSelectionMode === 'antenna') ? visibleForwardIds : nextAntennaIds;
|
||||
const activeSet = new Set(activeIds);
|
||||
const passiveOnlyIds = passiveIds.filter(id => !activeSet.has(id));
|
||||
|
||||
if(activeIds.length) WiredSelectionVisualizer.applySelectionShaderToFurni(activeIds);
|
||||
if(passiveOnlyIds.length) WiredSelectionVisualizer.applySecondarySelectionShaderToFurni(passiveOnlyIds);
|
||||
|
||||
highlightedIds.current = Array.from(new Set([ ...activeIds, ...passiveOnlyIds ]));
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
syncHighlights(antennaIds, forwardFurniIds, selectionMode, furniSource);
|
||||
}, [ antennaIds, forwardFurniIds, selectionMode, furniSource, syncHighlights ]);
|
||||
|
||||
const switchSelection = useCallback((mode: SelectionMode) =>
|
||||
{
|
||||
if(mode === selectionMode) return;
|
||||
if(mode === 'furni' && furniSource !== SOURCE_SELECTED) return;
|
||||
|
||||
const nextIds = (mode === 'antenna') ? antennaIds : forwardFurniIds;
|
||||
applySelection(nextIds);
|
||||
setSelectionMode(mode);
|
||||
}, [ selectionMode, furniSource, antennaIds, forwardFurniIds, applySelection ]);
|
||||
if(setFurniIds) setFurniIds([ ...((mode === 'antenna') ? antennaIds : forwardFurniIds) ]);
|
||||
}, [ selectionMode, furniSource, antennaIds, forwardFurniIds, setFurniIds ]);
|
||||
|
||||
const onChangeFurniSource = (next: number) =>
|
||||
{
|
||||
@@ -113,7 +125,7 @@ export const WiredActionSendSignalView: FC<{}> = () =>
|
||||
|
||||
if(selectionMode === 'furni')
|
||||
{
|
||||
applySelection(antennaIds);
|
||||
if(setFurniIds) setFurniIds([ ...antennaIds ]);
|
||||
setSelectionMode('antenna');
|
||||
}
|
||||
|
||||
@@ -122,12 +134,6 @@ export const WiredActionSendSignalView: FC<{}> = () =>
|
||||
|
||||
const save = useCallback(() =>
|
||||
{
|
||||
if(selectionMode === 'furni')
|
||||
{
|
||||
setSelectionMode('antenna');
|
||||
applySelection(antennaIds);
|
||||
}
|
||||
|
||||
const antennaSource = (antennaIds && antennaIds.length) ? antennaIds[0] : 0;
|
||||
|
||||
setIntParams([
|
||||
@@ -140,7 +146,19 @@ export const WiredActionSendSignalView: FC<{}> = () =>
|
||||
]);
|
||||
|
||||
setStringParam(serializeForwardIds(forwardFurniIds));
|
||||
}, [ selectionMode, antennaIds, furniSource, userSource, signalPerFurni, signalPerUser, forwardFurniIds, setIntParams, setStringParam, applySelection, setSelectionMode ]);
|
||||
}, [ antennaIds, furniSource, userSource, signalPerFurni, signalPerUser, forwardFurniIds, setIntParams, setStringParam ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
if(!highlightedIds.current.length) return;
|
||||
|
||||
WiredSelectionVisualizer.clearSelectionShaderFromFurni(highlightedIds.current);
|
||||
WiredSelectionVisualizer.clearSecondarySelectionShaderFromFurni(highlightedIds.current);
|
||||
highlightedIds.current = [];
|
||||
};
|
||||
}, []);
|
||||
|
||||
const selectionLimit = trigger?.maximumItemSelectionCount ?? 0;
|
||||
const forwardSelectionEnabled = (furniSource === SOURCE_SELECTED);
|
||||
|
||||
@@ -10,22 +10,26 @@ export const WiredActionSetFurniStateToView: FC<{}> = props =>
|
||||
const [ stateFlag, setStateFlag ] = useState(0);
|
||||
const [ directionFlag, setDirectionFlag ] = useState(0);
|
||||
const [ positionFlag, setPositionFlag ] = useState(0);
|
||||
const [ altitudeFlag, setAltitudeFlag ] = useState(0);
|
||||
const { trigger = null, setIntParams = null } = useWired();
|
||||
const [ furniSource, setFurniSource ] = useState<number>(() =>
|
||||
{
|
||||
if(trigger?.intData?.length > 4) return trigger.intData[4];
|
||||
if(trigger?.intData?.length > 3) return trigger.intData[3];
|
||||
return (trigger?.selectedItems?.length ?? 0) > 0 ? 100 : 0;
|
||||
});
|
||||
|
||||
const save = () => setIntParams([ stateFlag, directionFlag, positionFlag, furniSource ]);
|
||||
const save = () => setIntParams([ stateFlag, directionFlag, positionFlag, altitudeFlag, furniSource ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setStateFlag(trigger.getBoolean(0) ? 1 : 0);
|
||||
setDirectionFlag(trigger.getBoolean(1) ? 1 : 0);
|
||||
setPositionFlag(trigger.getBoolean(2) ? 1 : 0);
|
||||
setAltitudeFlag((trigger.intData.length > 4 && trigger.getBoolean(3)) ? 1 : 0);
|
||||
|
||||
if(trigger.intData.length > 3) setFurniSource(trigger.intData[3]);
|
||||
if(trigger.intData.length > 4) setFurniSource(trigger.intData[4]);
|
||||
else if(trigger.intData.length > 3) setFurniSource(trigger.intData[3]);
|
||||
else setFurniSource((trigger.selectedItems?.length ?? 0) > 0 ? 100 : 0);
|
||||
}, [ trigger ]);
|
||||
|
||||
@@ -53,6 +57,10 @@ export const WiredActionSetFurniStateToView: FC<{}> = props =>
|
||||
<input checked={ !!positionFlag } className="form-check-input" id="positionFlag" type="checkbox" onChange={ event => setPositionFlag(event.target.checked ? 1 : 0) } />
|
||||
<Text>{ LocalizeText('wiredfurni.params.condition.position') }</Text>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<input checked={ !!altitudeFlag } className="form-check-input" id="altitudeFlag" type="checkbox" onChange={ event => setAltitudeFlag(event.target.checked ? 1 : 0) } />
|
||||
<Text>{ LocalizeText('wiredfurni.params.condition.altitude') }</Text>
|
||||
</div>
|
||||
</div>
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
|
||||
@@ -1,21 +1,39 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { WiredFurniType } from '../../../../api';
|
||||
import { LocalizeText, WiredFurniType } from '../../../../api';
|
||||
import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredActionLayoutCode } from '../../../../api/wired/WiredActionLayoutCode';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
|
||||
export const WiredActionTeleportView: FC<{}> = props =>
|
||||
{
|
||||
const { trigger = null, setIntParams = null } = useWired();
|
||||
const isTeleportEffect = (trigger?.code === WiredActionLayoutCode.TELEPORT);
|
||||
const isUserToFurniEffect = (trigger?.code === WiredActionLayoutCode.USER_TO_FURNI);
|
||||
const [ fastTeleport, setFastTeleport ] = useState<boolean>(() =>
|
||||
{
|
||||
if(isTeleportEffect && trigger?.intData?.length >= 3) return (trigger.intData[0] === 1);
|
||||
return false;
|
||||
});
|
||||
const [ walkMode, setWalkMode ] = useState<number>(() =>
|
||||
{
|
||||
if(isUserToFurniEffect && trigger?.intData?.length >= 3) return trigger.intData[2];
|
||||
return 1;
|
||||
});
|
||||
|
||||
const [ furniSource, setFurniSource ] = useState<number>(() =>
|
||||
{
|
||||
if(isTeleportEffect && trigger?.intData?.length >= 3) return trigger.intData[1];
|
||||
if(isUserToFurniEffect && trigger?.intData?.length >= 3) return trigger.intData[0];
|
||||
if(trigger?.intData?.length >= 1) return trigger.intData[0];
|
||||
return (trigger?.selectedItems?.length ?? 0) > 0 ? 100 : 0;
|
||||
});
|
||||
|
||||
const [ userSource, setUserSource ] = useState<number>(() =>
|
||||
{
|
||||
if(isTeleportEffect && trigger?.intData?.length >= 3) return trigger.intData[2];
|
||||
if(isUserToFurniEffect && trigger?.intData?.length >= 3) return trigger.intData[1];
|
||||
if(trigger?.intData?.length >= 2) return trigger.intData[1];
|
||||
return 0;
|
||||
});
|
||||
@@ -24,16 +42,37 @@ export const WiredActionTeleportView: FC<{}> = props =>
|
||||
{
|
||||
if(!trigger) return;
|
||||
|
||||
if(isTeleportEffect && trigger.intData.length >= 3)
|
||||
{
|
||||
setFastTeleport(trigger.intData[0] === 1);
|
||||
setFurniSource(trigger.intData[1]);
|
||||
setUserSource(trigger.intData[2]);
|
||||
setWalkMode(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if(isUserToFurniEffect && trigger.intData.length >= 3)
|
||||
{
|
||||
setFastTeleport(false);
|
||||
setFurniSource(trigger.intData[0]);
|
||||
setUserSource(trigger.intData[1]);
|
||||
setWalkMode(trigger.intData[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
setFastTeleport(false);
|
||||
setWalkMode(1);
|
||||
|
||||
if(trigger.intData.length >= 1) setFurniSource(trigger.intData[0]);
|
||||
else setFurniSource((trigger.selectedItems?.length ?? 0) > 0 ? 100 : 0);
|
||||
|
||||
if(trigger.intData.length >= 2) setUserSource(trigger.intData[1]);
|
||||
else setUserSource(0);
|
||||
}, [ trigger ]);
|
||||
}, [ isTeleportEffect, isUserToFurniEffect, trigger ]);
|
||||
|
||||
const onChangeFurniSource = (next: number) => setFurniSource(next);
|
||||
|
||||
const save = () => setIntParams([ furniSource, userSource ]);
|
||||
const save = () => setIntParams(isTeleportEffect ? [ fastTeleport ? 1 : 0, furniSource, userSource ] : (isUserToFurniEffect ? [ furniSource, userSource, walkMode ] : [ furniSource, userSource ]));
|
||||
|
||||
const requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT;
|
||||
|
||||
@@ -50,6 +89,21 @@ export const WiredActionTeleportView: FC<{}> = props =>
|
||||
userSource={ userSource }
|
||||
onChangeFurni={ onChangeFurniSource }
|
||||
onChangeUsers={ setUserSource } />
|
||||
} />
|
||||
}>
|
||||
{ isTeleportEffect &&
|
||||
<div className="flex items-center gap-1">
|
||||
<input checked={ fastTeleport } className="form-check-input" type="checkbox" onChange={ event => setFastTeleport(event.target.checked) } />
|
||||
<Text>{ LocalizeText('wiredfurni.params.teleport.options.0') }</Text>
|
||||
</div> }
|
||||
{ isUserToFurniEffect &&
|
||||
<div className="flex flex-col gap-1">
|
||||
{ [ 0, 1, 2 ].map(option => (
|
||||
<label key={ option } className="flex items-center gap-1 cursor-pointer">
|
||||
<input checked={ walkMode === option } className="form-check-input" name="userWalkMode" type="radio" onChange={ () => setWalkMode(option) } />
|
||||
<Text>{ LocalizeText(`wiredfurni.params.user_move.walkmode.${ option }`) }</Text>
|
||||
</label>
|
||||
)) }
|
||||
</div> }
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { WiredFurniType } from '../../../../api';
|
||||
import { LocalizeText, WiredFurniType } from '../../../../api';
|
||||
import { Text } from '../../../../common';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
import { WiredSourcesSelector } from '../WiredSourcesSelector';
|
||||
import { useWired } from '../../../../hooks';
|
||||
@@ -7,8 +8,14 @@ import { useWired } from '../../../../hooks';
|
||||
export const WiredActionToggleFurniStateView: FC<{}> = props =>
|
||||
{
|
||||
const { trigger = null, setIntParams = null } = useWired();
|
||||
const [ toggleType, setToggleType ] = useState<number>(() =>
|
||||
{
|
||||
if(trigger?.intData?.length > 1) return trigger.intData[0];
|
||||
return 0;
|
||||
});
|
||||
const [ furniSource, setFurniSource ] = useState<number>(() =>
|
||||
{
|
||||
if(trigger?.intData?.length > 1) return trigger.intData[1];
|
||||
if(trigger?.intData?.length >= 1) return trigger.intData[0];
|
||||
return (trigger?.selectedItems?.length ?? 0) > 0 ? 100 : 0;
|
||||
});
|
||||
@@ -17,13 +24,26 @@ export const WiredActionToggleFurniStateView: FC<{}> = props =>
|
||||
{
|
||||
if(!trigger) return;
|
||||
|
||||
if(trigger.intData.length >= 1) setFurniSource(trigger.intData[0]);
|
||||
else setFurniSource((trigger.selectedItems?.length ?? 0) > 0 ? 100 : 0);
|
||||
if(trigger.intData.length > 1)
|
||||
{
|
||||
setToggleType(trigger.intData[0]);
|
||||
setFurniSource(trigger.intData[1]);
|
||||
}
|
||||
else if(trigger.intData.length >= 1)
|
||||
{
|
||||
setToggleType(0);
|
||||
setFurniSource(trigger.intData[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
setToggleType(0);
|
||||
setFurniSource((trigger.selectedItems?.length ?? 0) > 0 ? 100 : 0);
|
||||
}
|
||||
}, [ trigger ]);
|
||||
|
||||
const onChangeFurniSource = (next: number) => setFurniSource(next);
|
||||
|
||||
const save = () => setIntParams([ furniSource ]);
|
||||
const save = () => setIntParams([ toggleType, furniSource ]);
|
||||
|
||||
const requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT;
|
||||
|
||||
@@ -32,6 +52,16 @@ export const WiredActionToggleFurniStateView: FC<{}> = props =>
|
||||
hasSpecialInput={ true }
|
||||
requiresFurni={ requiresFurni }
|
||||
save={ save }
|
||||
footer={ <WiredSourcesSelector showFurni={ true } furniSource={ furniSource } onChangeFurni={ onChangeFurniSource } /> } />
|
||||
footer={ <WiredSourcesSelector showFurni={ true } furniSource={ furniSource } onChangeFurni={ onChangeFurniSource } /> }>
|
||||
<div className="flex flex-col gap-1">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.operator.2') }</Text>
|
||||
{ [ 0, 1 ].map(option => (
|
||||
<label key={ option } className="flex items-center gap-1">
|
||||
<input checked={ (toggleType === option) } className="form-check-input" name="toggleType" type="radio" onChange={ () => setToggleType(option) } />
|
||||
<Text>{ LocalizeText(`wiredfurni.params.toggletype.${ option }`) }</Text>
|
||||
</label>
|
||||
)) }
|
||||
</div>
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user