🆙 Init V3

This commit is contained in:
DuckieTM
2026-01-31 09:10:52 +01:00
commit 7feb10ab15
1733 changed files with 53405 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
import { ConditionDefinition, TriggerDefinition, WiredActionDefinition } from '@nitrots/nitro-renderer';
import { FC } from 'react';
import { useWired } from '../../hooks';
import { WiredActionLayoutView } from './views/actions/WiredActionLayoutView';
import { WiredConditionLayoutView } from './views/conditions/WiredConditionLayoutView';
import { WiredTriggerLayoutView } from './views/triggers/WiredTriggerLayoutView';
export const WiredView: FC<{}> = props =>
{
const { trigger = null } = useWired();
if(!trigger) return null;
if(trigger instanceof WiredActionDefinition) return WiredActionLayoutView(trigger.code);
if(trigger instanceof TriggerDefinition) return WiredTriggerLayoutView(trigger.code);
if(trigger instanceof ConditionDefinition) return WiredConditionLayoutView(trigger.code);
return null;
};
@@ -0,0 +1,114 @@
import { GetSessionDataManager } from '@nitrots/nitro-renderer';
import { FC, PropsWithChildren, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType, WiredSelectionVisualizer } from '../../../api';
import { Button, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../common';
import { useWired } from '../../../hooks';
import { WiredFurniSelectorView } from './WiredFurniSelectorView';
export interface WiredBaseViewProps
{
wiredType: string;
requiresFurni: number;
hasSpecialInput: boolean;
save: () => void;
validate?: () => boolean;
}
export const WiredBaseView: FC<PropsWithChildren<WiredBaseViewProps>> = props =>
{
const { wiredType = '', requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, validate = null, children = null, hasSpecialInput = false } = props;
const [ wiredName, setWiredName ] = useState<string>(null);
const [ wiredDescription, setWiredDescription ] = useState<string>(null);
const [ needsSave, setNeedsSave ] = useState<boolean>(false);
const { trigger = null, setTrigger = null, setIntParams = null, setStringParam = null, setFurniIds = null, setAllowsFurni = null, saveWired = null } = useWired();
const onClose = () => setTrigger(null);
const onSave = () =>
{
if(validate && !validate()) return;
if(save) save();
setNeedsSave(true);
};
useEffect(() =>
{
if(!needsSave) return;
saveWired();
setNeedsSave(false);
}, [ needsSave, saveWired ]);
useEffect(() =>
{
if(!trigger) return;
const spriteId = (trigger.spriteId || -1);
const furniData = GetSessionDataManager().getFloorItemData(spriteId);
if(!furniData)
{
setWiredName(('NAME: ' + spriteId));
setWiredDescription(('NAME: ' + spriteId));
}
else
{
setWiredName(furniData.name);
setWiredDescription(furniData.description);
}
if(hasSpecialInput)
{
setIntParams(trigger.intData);
setStringParam(trigger.stringData);
}
if(requiresFurni > WiredFurniType.STUFF_SELECTION_OPTION_NONE)
{
setFurniIds(prevValue =>
{
if(prevValue && prevValue.length) WiredSelectionVisualizer.clearSelectionShaderFromFurni(prevValue);
if(trigger.selectedItems && trigger.selectedItems.length)
{
WiredSelectionVisualizer.applySelectionShaderToFurni(trigger.selectedItems);
return trigger.selectedItems;
}
return [];
});
}
setAllowsFurni(requiresFurni);
}, [ trigger, hasSpecialInput, requiresFurni, setIntParams, setStringParam, setFurniIds, setAllowsFurni ]);
return (
<NitroCardView className="nitro-wired" theme="primary-slim" uniqueKey="nitro-wired">
<NitroCardHeaderView headerText={ LocalizeText('wiredfurni.title') } onCloseClick={ onClose } />
<NitroCardContentView>
<div className="flex flex-col gap-1">
<div className="flex items-center gap-1">
<i className={ `icon icon-wired-${ wiredType }` } />
<Text bold>{ wiredName }</Text>
</div>
<Text small>{ wiredDescription }</Text>
</div>
{ !!children && <hr className="m-0 bg-dark" /> }
{ children }
{ (requiresFurni > WiredFurniType.STUFF_SELECTION_OPTION_NONE) &&
<>
<hr className="m-0 bg-dark" />
<WiredFurniSelectorView />
</> }
<div className="flex items-center gap-1">
<Button fullWidth variant="success" onClick={ onSave }>{ LocalizeText('wiredfurni.ready') }</Button>
<Button fullWidth variant="secondary" onClick={ onClose }>{ LocalizeText('cancel') }</Button>
</div>
</NitroCardContentView>
</NitroCardView>
);
};
@@ -0,0 +1,16 @@
import { FC } from 'react';
import { LocalizeText } from '../../../api';
import { Text } from '../../../common';
import { useWired } from '../../../hooks';
export const WiredFurniSelectorView: FC<{}> = props =>
{
const { trigger = null, furniIds = [] } = useWired();
return (
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.pickfurnis.caption', [ 'count', 'limit' ], [ furniIds.length.toString(), trigger.maximumItemSelectionCount.toString() ]) }</Text>
<Text small>{ LocalizeText('wiredfurni.pickfurnis.desc') }</Text>
</div>
);
};
@@ -0,0 +1,41 @@
import { WiredActionDefinition } from '@nitrots/nitro-renderer';
import { FC, PropsWithChildren, useEffect } from 'react';
import ReactSlider from 'react-slider';
import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredBaseView } from '../WiredBaseView';
export interface WiredActionBaseViewProps
{
hasSpecialInput: boolean;
requiresFurni: number;
save: () => void;
}
export const WiredActionBaseView: FC<PropsWithChildren<WiredActionBaseViewProps>> = props =>
{
const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, hasSpecialInput = false, children = null } = props;
const { trigger = null, actionDelay = 0, setActionDelay = null } = useWired();
useEffect(() =>
{
setActionDelay((trigger as WiredActionDefinition).delayInPulses);
}, [ trigger, setActionDelay ]);
return (
<WiredBaseView hasSpecialInput={ hasSpecialInput } requiresFurni={ requiresFurni } save={ save } wiredType="action">
{ children }
{ !!children && <hr className="m-0 bg-dark" /> }
<div className="flex flex-col">
<Text bold>{ LocalizeText('wiredfurni.params.delay', [ 'seconds' ], [ GetWiredTimeLocale(actionDelay) ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 20 }
min={ 0 }
value={ actionDelay }
onChange={ event => setActionDelay(event) } />
</div>
</WiredBaseView>
);
};
@@ -0,0 +1,39 @@
import { GetSessionDataManager } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WIRED_STRING_DELIMETER, WiredFurniType } from '../../../../api';
import { Button, LayoutAvatarImageView, Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
const DEFAULT_FIGURE: string = 'hd-180-1.ch-210-66.lg-270-82.sh-290-81';
export const WiredActionBotChangeFigureView: FC<{}> = props =>
{
const [ botName, setBotName ] = useState('');
const [ figure, setFigure ] = useState('');
const { trigger = null, setStringParam = null } = useWired();
const save = () => setStringParam((botName + WIRED_STRING_DELIMETER + figure));
useEffect(() =>
{
const data = trigger.stringData.split(WIRED_STRING_DELIMETER);
if(data.length > 0) setBotName(data[0]);
if(data.length > 1) setFigure(data[1].length > 0 ? data[1] : DEFAULT_FIGURE);
}, [ 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>
<div className="flex items-center justify-center">
<LayoutAvatarImageView direction={ 4 } figure={ figure } />
<Button onClick={ event => setFigure(GetSessionDataManager().figure) }>{ LocalizeText('wiredfurni.params.capture.figure') }</Button>
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,44 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionBotFollowAvatarView: FC<{}> = props =>
{
const [ botName, setBotName ] = useState('');
const [ followMode, setFollowMode ] = useState(-1);
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
const save = () =>
{
setStringParam(botName);
setIntParams([ followMode ]);
};
useEffect(() =>
{
setBotName(trigger.stringData);
setFollowMode((trigger.intData.length > 0) ? trigger.intData[0] : 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>
<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) } />
<Text>{ LocalizeText('wiredfurni.params.start.following') }</Text>
</div>
<div className="flex items-center gap-1">
<input checked={ (followMode === 0) } className="form-check-input" id="followMode2" name="followMode" type="radio" onChange={ event => setFollowMode(0) } />
<Text>{ LocalizeText('wiredfurni.params.stop.following') }</Text>
</div>
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,43 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
const ALLOWED_HAND_ITEM_IDS: number[] = [ 2, 5, 7, 8, 9, 10, 27 ];
export const WiredActionBotGiveHandItemView: FC<{}> = props =>
{
const [ botName, setBotName ] = useState('');
const [ handItemId, setHandItemId ] = useState(-1);
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
const save = () =>
{
setStringParam(botName);
setIntParams([ handItemId ]);
};
useEffect(() =>
{
setBotName(trigger.stringData);
setHandItemId((trigger.intData.length > 0) ? trigger.intData[0] : 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>
<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>
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,28 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionBotMoveView: FC<{}> = props =>
{
const [ botName, setBotName ] = useState('');
const { trigger = null, setStringParam = null } = useWired();
const save = () => setStringParam(botName);
useEffect(() =>
{
setBotName(trigger.stringData);
}, [ trigger ]);
return (
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID } 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>
);
};
@@ -0,0 +1,53 @@
import { FC, useEffect, useState } from 'react';
import { GetConfigurationValue, LocalizeText, WIRED_STRING_DELIMETER, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionBotTalkToAvatarView: FC<{}> = props =>
{
const [ botName, setBotName ] = useState('');
const [ message, setMessage ] = useState('');
const [ talkMode, setTalkMode ] = useState(-1);
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
const save = () =>
{
setStringParam(botName + WIRED_STRING_DELIMETER + message);
setIntParams([ talkMode ]);
};
useEffect(() =>
{
const data = trigger.stringData.split(WIRED_STRING_DELIMETER);
if(data.length > 0) setBotName(data[0]);
if(data.length > 1) setMessage(data[1].length > 0 ? data[1] : '');
setTalkMode((trigger.intData.length > 0) ? trigger.intData[0] : 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>
<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) } />
</div>
<div className="flex flex-col gap-1">
<div className="flex items-center gap-1">
<input checked={ (talkMode === 0) } className="form-check-input" id="talkMode1" name="talkMode" type="radio" onChange={ event => setTalkMode(0) } />
<Text>{ LocalizeText('wiredfurni.params.talk') }</Text>
</div>
<div className="flex items-center gap-1">
<input checked={ (talkMode === 1) } className="form-check-input" id="talkMode2" name="talkMode" type="radio" onChange={ event => setTalkMode(1) } />
<Text>{ LocalizeText('wiredfurni.params.whisper') }</Text>
</div>
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,53 @@
import { FC, useEffect, useState } from 'react';
import { GetConfigurationValue, LocalizeText, WIRED_STRING_DELIMETER, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionBotTalkView: FC<{}> = props =>
{
const [ botName, setBotName ] = useState('');
const [ message, setMessage ] = useState('');
const [ talkMode, setTalkMode ] = useState(-1);
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
const save = () =>
{
setStringParam(botName + WIRED_STRING_DELIMETER + message);
setIntParams([ talkMode ]);
};
useEffect(() =>
{
const data = trigger.stringData.split(WIRED_STRING_DELIMETER);
if(data.length > 0) setBotName(data[0]);
if(data.length > 1) setMessage(data[1].length > 0 ? data[1] : '');
setTalkMode((trigger.intData.length > 0) ? trigger.intData[0] : 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>
<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) } />
</div>
<div className="flex flex-col gap-1">
<div className="flex items-center gap-1">
<input checked={ (talkMode === 0) } className="form-check-input" id="talkMode1" name="talkMode" type="radio" onChange={ event => setTalkMode(0) } />
<Text>{ LocalizeText('wiredfurni.params.talk') }</Text>
</div>
<div className="flex items-center gap-1">
<input checked={ (talkMode === 1) } className="form-check-input" id="talkMode2" name="talkMode" type="radio" onChange={ event => setTalkMode(1) } />
<Text>{ LocalizeText('wiredfurni.params.shout') }</Text>
</div>
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,28 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionBotTeleportView: FC<{}> = props =>
{
const [ botName, setBotName ] = useState('');
const { trigger = null, setStringParam = null } = useWired();
const save = () => setStringParam(botName);
useEffect(() =>
{
setBotName(trigger.stringData);
}, [ trigger ]);
return (
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID } 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>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionCallAnotherStackView: FC<{}> = props =>
{
return <WiredActionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT } save={ null } />;
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionChaseView: FC<{}> = props =>
{
return <WiredActionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT } save={ null } />;
};
@@ -0,0 +1,28 @@
import { FC, useEffect, useState } from 'react';
import { GetConfigurationValue, LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionChatView: FC<{}> = props =>
{
const [ message, setMessage ] = useState('');
const { trigger = null, setStringParam = null } = useWired();
const save = () => setStringParam(message);
useEffect(() =>
{
setMessage(trigger.stringData);
}, [ 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.message') }</Text>
<NitroInput maxLength={ GetConfigurationValue<number>('wired.action.chat.max.length', 100) } type="text" value={ message } onChange={ event => setMessage(event.target.value) } />
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionFleeView: FC<{}> = props =>
{
return <WiredActionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT } save={ null } />;
};
@@ -0,0 +1,161 @@
import { FC, useEffect, useState } from 'react';
import { FaPlus, FaTrash } from 'react-icons/fa';
import ReactSlider from 'react-slider';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Button, Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionGiveRewardView: FC<{}> = props =>
{
const [ limitEnabled, setLimitEnabled ] = useState(false);
const [ rewardTime, setRewardTime ] = useState(1);
const [ uniqueRewards, setUniqueRewards ] = useState(false);
const [ rewardsLimit, setRewardsLimit ] = useState(1);
const [ limitationInterval, setLimitationInterval ] = useState(1);
const [ rewards, setRewards ] = useState<{ isBadge: boolean, itemCode: string, probability: number }[]>([]);
const { trigger = null, setIntParams = null, setStringParam = null } = useWired();
const addReward = () => setRewards(rewards => [ ...rewards, { isBadge: false, itemCode: '', probability: null } ]);
const removeReward = (index: number) =>
{
setRewards(prevValue =>
{
const newValues = Array.from(prevValue);
newValues.splice(index, 1);
return newValues;
});
};
const updateReward = (index: number, isBadge: boolean, itemCode: string, probability: number) =>
{
const rewardsClone = Array.from(rewards);
const reward = rewardsClone[index];
if(!reward) return;
reward.isBadge = isBadge;
reward.itemCode = itemCode;
reward.probability = probability;
setRewards(rewardsClone);
};
const save = () =>
{
let stringRewards = [];
for(const reward of rewards)
{
if(!reward.itemCode) continue;
const rewardsString = [ reward.isBadge ? '0' : '1', reward.itemCode, reward.probability.toString() ];
stringRewards.push(rewardsString.join(','));
}
if(stringRewards.length > 0)
{
setStringParam(stringRewards.join(';'));
setIntParams([ rewardTime, uniqueRewards ? 1 : 0, rewardsLimit, limitationInterval ]);
}
};
useEffect(() =>
{
const readRewards: { isBadge: boolean, itemCode: string, probability: number }[] = [];
if(trigger.stringData.length > 0 && trigger.stringData.includes(';'))
{
const splittedRewards = trigger.stringData.split(';');
for(const rawReward of splittedRewards)
{
const reward = rawReward.split(',');
if(reward.length !== 3) continue;
readRewards.push({ isBadge: reward[0] === '0', itemCode: reward[1], probability: Number(reward[2]) });
}
}
if(readRewards.length === 0) readRewards.push({ isBadge: false, itemCode: '', probability: null });
setRewardTime((trigger.intData.length > 0) ? trigger.intData[0] : 0);
setUniqueRewards((trigger.intData.length > 1) ? (trigger.intData[1] === 1) : false);
setRewardsLimit((trigger.intData.length > 2) ? trigger.intData[2] : 0);
setLimitationInterval((trigger.intData.length > 3) ? trigger.intData[3] : 0);
setLimitEnabled((trigger.intData.length > 3) ? trigger.intData[3] > 0 : false);
setRewards(readRewards);
}, [ trigger ]);
return (
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex items-center gap-1">
<input className="form-check-input" id="limitEnabled" type="checkbox" onChange={ event => setLimitEnabled(event.target.checked) } />
<Text>{ LocalizeText('wiredfurni.params.prizelimit', [ 'amount' ], [ limitEnabled ? rewardsLimit.toString() : '' ]) }</Text>
</div>
{ !limitEnabled &&
<Text center small className="p-1 rounded bg-muted">
Reward limit not set. Make sure rewards are badges or non-tradeable items.
</Text> }
{ limitEnabled &&
<ReactSlider
className={ 'nitro-slider' }
max={ 1000 }
min={ 1 }
value={ rewardsLimit }
onChange={ event => setRewardsLimit(event) } /> }
<hr className="m-0 bg-dark" />
<div className="flex flex-col gap-1">
<Text bold>How often can a user be rewarded?</Text>
<div className="flex gap-1">
<select className="w-full form-select form-select-sm" value={ rewardTime } onChange={ (e) => setRewardTime(Number(e.target.value)) }>
<option value="0">Once</option>
<option value="3">Once every { limitationInterval } minutes</option>
<option value="2">Once every { limitationInterval } hours</option>
<option value="1">Once every { limitationInterval } days</option>
</select>
{ (rewardTime > 0) && <NitroInput type="number" value={ limitationInterval } onChange={ event => setLimitationInterval(Number(event.target.value)) } /> }
</div>
</div>
<hr className="m-0 bg-dark" />
<div className="flex items-center gap-1">
<input checked={ uniqueRewards } className="form-check-input" id="uniqueRewards" type="checkbox" onChange={ (e) => setUniqueRewards(e.target.checked) } />
<Text>Unique rewards</Text>
</div>
<Text center small className="p-1 rounded bg-muted">
If checked each reward will be given once to each user. This will disable the probabilities option.
</Text>
<hr className="m-0 bg-dark" />
<div className="flex items-center justify-between">
<Text bold>Rewards</Text>
<Button variant="success" onClick={ addReward }>
<FaPlus className="fa-icon" />
</Button>
</div>
<div className="flex flex-col gap-1">
{ rewards && rewards.map((reward, index) =>
{
return (
<div key={ index } className="flex gap-1">
<div className="flex items-center gap-1">
<input checked={ reward.isBadge } className="form-check-input" type="checkbox" onChange={ (e) => updateReward(index, e.target.checked, reward.itemCode, reward.probability) } />
<Text small>Badge?</Text>
</div>
<NitroInput placeholder="Item Code" type="text" value={ reward.itemCode } onChange={ e => updateReward(index, reward.isBadge, e.target.value, reward.probability) } />
<NitroInput placeholder="Probability" type="number" value={ reward.probability } onChange={ e => updateReward(index, reward.isBadge, reward.itemCode, Number(e.target.value)) } />
{ (index > 0) &&
<Button variant="danger" onClick={ event => removeReward(index) }>
<FaTrash className="fa-icon" />
</Button> }
</div>
);
}) }
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,67 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionGiveScoreToPredefinedTeamView: FC<{}> = props =>
{
const [ points, setPoints ] = useState(1);
const [ time, setTime ] = useState(1);
const [ selectedTeam, setSelectedTeam ] = useState(1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ points, time, selectedTeam ]);
useEffect(() =>
{
if(trigger.intData.length >= 2)
{
setPoints(trigger.intData[0]);
setTime(trigger.intData[1]);
setSelectedTeam(trigger.intData[2]);
}
else
{
setPoints(1);
setTime(1);
setSelectedTeam(1);
}
}, [ 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.setpoints', [ 'points' ], [ points.toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 100 }
min={ 1 }
value={ points }
onChange={ event => setPoints(event) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.settimesingame', [ 'times' ], [ time.toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 10 }
min={ 1 }
value={ time }
onChange={ event => setTime(event) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.team') }</Text>
{ [ 1, 2, 3, 4 ].map(value =>
{
return (
<div key={ value } className="flex gap-1">
<input checked={ (selectedTeam === value) } className="form-check-input" id={ `selectedTeam${ value }` } name="selectedTeam" type="radio" onChange={ event => setSelectedTeam(value) } />
<Text>{ LocalizeText('wiredfurni.params.team.' + value) }</Text>
</div>
);
}) }
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,52 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionGiveScoreView: FC<{}> = props =>
{
const [ points, setPoints ] = useState(1);
const [ time, setTime ] = useState(1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ points, time ]);
useEffect(() =>
{
if(trigger.intData.length >= 2)
{
setPoints(trigger.intData[0]);
setTime(trigger.intData[1]);
}
else
{
setPoints(1);
setTime(1);
}
}, [ 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.setpoints', [ 'points' ], [ points.toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 100 }
min={ 1 }
value={ points }
onChange={ event => setPoints(event) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.settimesingame', [ 'times' ], [ time.toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 10 }
min={ 1 }
value={ time }
onChange={ event => setTime(event) } />
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,35 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionJoinTeamView: FC<{}> = props =>
{
const [ selectedTeam, setSelectedTeam ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ selectedTeam ]);
useEffect(() =>
{
setSelectedTeam((trigger.intData.length > 0) ? trigger.intData[0] : 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.team') }</Text>
{ [ 1, 2, 3, 4 ].map(team =>
{
return (
<div key={ team } className="flex gap-1">
<input checked={ (selectedTeam === team) } className="form-check-input" id={ `selectedTeam${ team }` } name="selectedTeam" type="radio" onChange={ event => setSelectedTeam(team) } />
<Text>{ LocalizeText(`wiredfurni.params.team.${ team }`) }</Text>
</div>
);
}) }
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,28 @@
import { FC, useEffect, useState } from 'react';
import { GetConfigurationValue, LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionKickFromRoomView: FC<{}> = props =>
{
const [ message, setMessage ] = useState('');
const { trigger = null, setStringParam = null } = useWired();
const save = () => setStringParam(message);
useEffect(() =>
{
setMessage(trigger.stringData);
}, [ 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.message') }</Text>
<NitroInput maxLength={ GetConfigurationValue<number>('wired.action.kick.from.room.max.length', 100) } type="text" value={ message } onChange={ event => setMessage(event.target.value) } />
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,85 @@
import { WiredActionLayoutCode } from '../../../../api';
import { WiredActionBotChangeFigureView } from './WiredActionBotChangeFigureView';
import { WiredActionBotFollowAvatarView } from './WiredActionBotFollowAvatarView';
import { WiredActionBotGiveHandItemView } from './WiredActionBotGiveHandItemView';
import { WiredActionBotMoveView } from './WiredActionBotMoveView';
import { WiredActionBotTalkToAvatarView } from './WiredActionBotTalkToAvatarView';
import { WiredActionBotTalkView } from './WiredActionBotTalkView';
import { WiredActionBotTeleportView } from './WiredActionBotTeleportView';
import { WiredActionCallAnotherStackView } from './WiredActionCallAnotherStackView';
import { WiredActionChaseView } from './WiredActionChaseView';
import { WiredActionChatView } from './WiredActionChatView';
import { WiredActionFleeView } from './WiredActionFleeView';
import { WiredActionGiveRewardView } from './WiredActionGiveRewardView';
import { WiredActionGiveScoreToPredefinedTeamView } from './WiredActionGiveScoreToPredefinedTeamView';
import { WiredActionGiveScoreView } from './WiredActionGiveScoreView';
import { WiredActionJoinTeamView } from './WiredActionJoinTeamView';
import { WiredActionKickFromRoomView } from './WiredActionKickFromRoomView';
import { WiredActionLeaveTeamView } from './WiredActionLeaveTeamView';
import { WiredActionMoveAndRotateFurniView } from './WiredActionMoveAndRotateFurniView';
import { WiredActionMoveFurniToView } from './WiredActionMoveFurniToView';
import { WiredActionMoveFurniView } from './WiredActionMoveFurniView';
import { WiredActionMuteUserView } from './WiredActionMuteUserView';
import { WiredActionResetView } from './WiredActionResetView';
import { WiredActionSetFurniStateToView } from './WiredActionSetFurniStateToView';
import { WiredActionTeleportView } from './WiredActionTeleportView';
import { WiredActionToggleFurniStateView } from './WiredActionToggleFurniStateView';
export const WiredActionLayoutView = (code: number) =>
{
switch(code)
{
case WiredActionLayoutCode.BOT_CHANGE_FIGURE:
return <WiredActionBotChangeFigureView />;
case WiredActionLayoutCode.BOT_FOLLOW_AVATAR:
return <WiredActionBotFollowAvatarView />;
case WiredActionLayoutCode.BOT_GIVE_HAND_ITEM:
return <WiredActionBotGiveHandItemView />;
case WiredActionLayoutCode.BOT_MOVE:
return <WiredActionBotMoveView />;
case WiredActionLayoutCode.BOT_TALK:
return <WiredActionBotTalkView />;
case WiredActionLayoutCode.BOT_TALK_DIRECT_TO_AVTR:
return <WiredActionBotTalkToAvatarView />;
case WiredActionLayoutCode.BOT_TELEPORT:
return <WiredActionBotTeleportView />;
case WiredActionLayoutCode.CALL_ANOTHER_STACK:
return <WiredActionCallAnotherStackView />;
case WiredActionLayoutCode.CHASE:
return <WiredActionChaseView />;
case WiredActionLayoutCode.CHAT:
return <WiredActionChatView />;
case WiredActionLayoutCode.FLEE:
return <WiredActionFleeView />;
case WiredActionLayoutCode.GIVE_REWARD:
return <WiredActionGiveRewardView />;
case WiredActionLayoutCode.GIVE_SCORE:
return <WiredActionGiveScoreView />;
case WiredActionLayoutCode.GIVE_SCORE_TO_PREDEFINED_TEAM:
return <WiredActionGiveScoreToPredefinedTeamView />;
case WiredActionLayoutCode.JOIN_TEAM:
return <WiredActionJoinTeamView />;
case WiredActionLayoutCode.KICK_FROM_ROOM:
return <WiredActionKickFromRoomView />;
case WiredActionLayoutCode.LEAVE_TEAM:
return <WiredActionLeaveTeamView />;
case WiredActionLayoutCode.MOVE_FURNI:
return <WiredActionMoveFurniView />;
case WiredActionLayoutCode.MOVE_AND_ROTATE_FURNI:
return <WiredActionMoveAndRotateFurniView />;
case WiredActionLayoutCode.MOVE_FURNI_TO:
return <WiredActionMoveFurniToView />;
case WiredActionLayoutCode.MUTE_USER:
return <WiredActionMuteUserView />;
case WiredActionLayoutCode.RESET:
return <WiredActionResetView />;
case WiredActionLayoutCode.SET_FURNI_STATE:
return <WiredActionSetFurniStateToView />;
case WiredActionLayoutCode.TELEPORT:
return <WiredActionTeleportView />;
case WiredActionLayoutCode.TOGGLE_FURNI_STATE:
return <WiredActionToggleFurniStateView />;
}
return null;
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionLeaveTeamView: FC<{}> = props =>
{
return <WiredActionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ null } />;
};
@@ -0,0 +1,82 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredActionBaseView } from './WiredActionBaseView';
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 { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ movement, rotation ]);
useEffect(() =>
{
if(trigger.intData.length >= 2)
{
setMovement(trigger.intData[0]);
setRotation(trigger.intData[1]);
}
else
{
setMovement(-1);
setRotation(-1);
}
}, [ trigger ]);
return (
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.startdir') }</Text>
<div className="flex gap-1">
{ directionOptions.map(option =>
{
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>
);
}) }
</div>
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.turn') }</Text>
{ rotationOptions.map(option =>
{
return (
<div key={ option } className="flex items-center gap-1">
<input checked={ (rotation === option) } className="form-check-input" id={ `rotation${ option }` } name="rotation" type="radio" onChange={ event => setRotation(option) } />
<Text>{ LocalizeText(`wiredfurni.params.turn.${ option }`) }</Text>
</div>
);
}) }
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,76 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredActionBaseView } from './WiredActionBaseView';
const directionOptions: { value: number, icon: string }[] = [
{
value: 0,
icon: 'ne'
},
{
value: 2,
icon: 'se'
},
{
value: 4,
icon: 'sw'
},
{
value: 6,
icon: 'nw'
}
];
export const WiredActionMoveFurniToView: FC<{}> = props =>
{
const [ spacing, setSpacing ] = useState(-1);
const [ movement, setMovement ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ movement, spacing ]);
useEffect(() =>
{
if(trigger.intData.length >= 2)
{
setSpacing(trigger.intData[1]);
setMovement(trigger.intData[0]);
}
else
{
setSpacing(-1);
setMovement(-1);
}
}, [ trigger ]);
return (
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_OR_BY_TYPE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.emptytiles', [ 'tiles' ], [ spacing.toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 5 }
min={ 1 }
value={ spacing }
onChange={ event => setSpacing(event) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.startdir') }</Text>
<div className="flex gap-1">
{ directionOptions.map(value =>
{
return (
<div key={ value.value } className="flex items-center gap-1">
<input checked={ (movement === value.value) } className="form-check-input" id={ `movement${ value.value }` } name="movement" type="radio" onChange={ event => setMovement(value.value) } />
<Text><i className={ `icon icon-${ value.icon }` } /></Text>
</div>
);
}) }
</div>
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,100 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredActionBaseView } from './WiredActionBaseView';
const directionOptions: { value: number, icon: string }[] = [
{
value: 4,
icon: 'ne'
},
{
value: 5,
icon: 'se'
},
{
value: 6,
icon: 'sw'
},
{
value: 7,
icon: 'nw'
},
{
value: 2,
icon: 'mv-2'
},
{
value: 3,
icon: 'mv-3'
},
{
value: 1,
icon: 'mv-1'
}
];
const rotationOptions: number[] = [ 0, 1, 2, 3 ];
export const WiredActionMoveFurniView: FC<{}> = props =>
{
const [ movement, setMovement ] = useState(-1);
const [ rotation, setRotation ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ movement, rotation ]);
useEffect(() =>
{
if(trigger.intData.length >= 2)
{
setMovement(trigger.intData[0]);
setRotation(trigger.intData[1]);
}
else
{
setMovement(-1);
setRotation(-1);
}
}, [ trigger ]);
return (
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.movefurni') }</Text>
<div className="flex items-center gap-1">
<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 =>
{
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) } />
<i className={ `nitro.icon icon-${ option.icon }` } />
</div>
);
}) }
<div className="col" />
</div>
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.rotatefurni') }</Text>
{ rotationOptions.map(option =>
{
return (
<div key={ option } className="flex items-center gap-1">
<input checked={ (rotation === option) } className="form-check-input" id={ `rotation${ option }` } name="rotation" type="radio" onChange={ event => setRotation(option) } />
<Text>
{ [ 1, 2 ].includes(option) && <i className={ `nitro-icon icon-rot-${ option }` } /> }
{ LocalizeText(`wiredfurni.params.rotatefurni.${ option }`) }
</Text>
</div>
);
}) }
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,44 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { GetConfigurationValue, LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionMuteUserView: FC<{}> = props =>
{
const [ time, setTime ] = useState(-1);
const [ message, setMessage ] = useState('');
const { trigger = null, setIntParams = null, setStringParam = null } = useWired();
const save = () =>
{
setIntParams([ time ]);
setStringParam(message);
};
useEffect(() =>
{
setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0);
setMessage(trigger.stringData);
}, [ 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.length.minutes', [ 'minutes' ], [ time.toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 10 }
min={ 1 }
value={ time }
onChange={ event => setTime(event) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.message') }</Text>
<NitroInput maxLength={ GetConfigurationValue<number>('wired.action.mute.user.max.length', 100) } type="text" value={ message } onChange={ event => setMessage(event.target.value) } />
</div>
</WiredActionBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionResetView: FC<{}> = props =>
{
return <WiredActionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ null } />;
};
@@ -0,0 +1,42 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionSetFurniStateToView: FC<{}> = props =>
{
const [ stateFlag, setStateFlag ] = useState(0);
const [ directionFlag, setDirectionFlag ] = useState(0);
const [ positionFlag, setPositionFlag ] = useState(0);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ stateFlag, directionFlag, positionFlag ]);
useEffect(() =>
{
setStateFlag(trigger.getBoolean(0) ? 1 : 0);
setDirectionFlag(trigger.getBoolean(1) ? 1 : 0);
setPositionFlag(trigger.getBoolean(2) ? 1 : 0);
}, [ trigger ]);
return (
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.conditions') }</Text>
<div className="flex items-center gap-1">
<input checked={ !!stateFlag } className="form-check-input" id="stateFlag" type="checkbox" onChange={ event => setStateFlag(event.target.checked ? 1 : 0) } />
<Text>{ LocalizeText('wiredfurni.params.condition.state') }</Text>
</div>
<div className="flex items-center gap-1">
<input checked={ !!directionFlag } className="form-check-input" id="directionFlag" type="checkbox" onChange={ event => setDirectionFlag(event.target.checked ? 1 : 0) } />
<Text>{ LocalizeText('wiredfurni.params.condition.direction') }</Text>
</div>
<div className="flex items-center gap-1">
<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>
</WiredActionBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionTeleportView: FC<{}> = props =>
{
return <WiredActionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT } save={ null } />;
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredActionBaseView } from './WiredActionBaseView';
export const WiredActionToggleFurniStateView: FC<{}> = props =>
{
return <WiredActionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT } save={ null } />;
};
@@ -0,0 +1,34 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredConditionBaseView } from './WiredConditionBaseView';
const ALLOWED_HAND_ITEM_IDS: number[] = [ 2, 5, 7, 8, 9, 10, 27 ];
export const WiredConditionActorHasHandItemView: FC<{}> = props =>
{
const [ handItemId, setHandItemId ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ handItemId ]);
useEffect(() =>
{
setHandItemId((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<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)) }>
{ ALLOWED_HAND_ITEM_IDS.map(value =>
{
return <option key={ value } value={ value }>{ LocalizeText(`handitem${ value }`) }</option>;
}) }
</select>
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionActorIsGroupMemberView: FC<{}> = props =>
{
return <WiredConditionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ null } />;
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionActorIsOnFurniView: FC<{}> = props =>
{
return <WiredConditionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID } save={ null } />;
};
@@ -0,0 +1,37 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredConditionBaseView } from './WiredConditionBaseView';
const teamIds: number[] = [ 1, 2, 3, 4 ];
export const WiredConditionActorIsTeamMemberView: FC<{}> = props =>
{
const [ selectedTeam, setSelectedTeam ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ selectedTeam ]);
useEffect(() =>
{
setSelectedTeam((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.team') }</Text>
{ teamIds.map(value =>
{
return (
<div key={ value } className="items-center gap-1">
<input checked={ (selectedTeam === value) } className="form-check-input" id={ `selectedTeam${ value }` } name="selectedTeam" type="radio" onChange={ event => setSelectedTeam(value) } />
<Text>{ LocalizeText(`wiredfurni.params.team.${ value }`) }</Text>
</div>
);
}) }
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,28 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionActorIsWearingBadgeView: FC<{}> = props =>
{
const [ badge, setBadge ] = useState('');
const { trigger = null, setStringParam = null } = useWired();
const save = () => setStringParam(badge);
useEffect(() =>
{
setBadge(trigger.stringData);
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.badgecode') }</Text>
<NitroInput type="text" value={ badge } onChange={ event => setBadge(event.target.value) } />
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,28 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionActorIsWearingEffectView: FC<{}> = props =>
{
const [ effect, setEffect ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ effect ]);
useEffect(() =>
{
setEffect(trigger?.intData[0] ?? 0);
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.tooltip.effectid') }</Text>
<NitroInput type="number" value={ effect } onChange={ event => setEffect(parseInt(event.target.value)) } />
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,23 @@
import { FC, PropsWithChildren } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredBaseView } from '../WiredBaseView';
export interface WiredConditionBaseViewProps
{
hasSpecialInput: boolean;
requiresFurni: number;
save: () => void;
}
export const WiredConditionBaseView: FC<PropsWithChildren<WiredConditionBaseViewProps>> = props =>
{
const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, hasSpecialInput = false, children = null } = props;
const onSave = () => (save && save());
return (
<WiredBaseView hasSpecialInput={ hasSpecialInput } requiresFurni={ requiresFurni } save={ onSave } wiredType="condition">
{ children }
</WiredBaseView>
);
};
@@ -0,0 +1,59 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredDateToString, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionDateRangeView: FC<{}> = props =>
{
const [ startDate, setStartDate ] = useState('');
const [ endDate, setEndDate ] = useState('');
const { trigger = null, setIntParams = null } = useWired();
const save = () =>
{
let startDateMili = 0;
let endDateMili = 0;
const startDateInstance = new Date(startDate);
const endDateInstance = new Date(endDate);
if(startDateInstance && endDateInstance)
{
startDateMili = startDateInstance.getTime() / 1000;
endDateMili = endDateInstance.getTime() / 1000;
}
setIntParams([ startDateMili, endDateMili ]);
};
useEffect(() =>
{
if(trigger.intData.length >= 2)
{
let startDate = new Date();
let endDate = new Date();
if(trigger.intData[0] > 0) startDate = new Date((trigger.intData[0] * 1000));
if(trigger.intData[1] > 0) endDate = new Date((trigger.intData[1] * 1000));
setStartDate(WiredDateToString(startDate));
setEndDate(WiredDateToString(endDate));
}
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.startdate') }</Text>
<NitroInput type="text" value={ startDate } onChange={ (e) => setStartDate(e.target.value) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.enddate') }</Text>
<NitroInput type="text" value={ endDate } onChange={ (e) => setEndDate(e.target.value) } />
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionFurniHasAvatarOnView: FC<{}> = props =>
{
return <WiredConditionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID } save={ null } />;
};
@@ -0,0 +1,35 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionFurniHasFurniOnView: FC<{}> = props =>
{
const [ requireAll, setRequireAll ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ requireAll ]);
useEffect(() =>
{
setRequireAll((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.requireall') }</Text>
{ [ 0, 1 ].map(value =>
{
return (
<div key={ value } className="flex items-center gap-1">
<input checked={ (requireAll === value) } className="form-check-input" id={ `requireAll${ value }` } name="requireAll" type="radio" onChange={ event => setRequireAll(value) } />
<Text>{ LocalizeText('wiredfurni.params.requireall.' + value) }</Text>
</div>
);
}) }
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,35 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionFurniHasNotFurniOnView: FC<{}> = props =>
{
const [ requireAll, setRequireAll ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ requireAll ]);
useEffect(() =>
{
setRequireAll((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.not_requireall') }</Text>
{ [ 0, 1 ].map(value =>
{
return (
<div key={ value } className="flex items-center gap-1">
<input checked={ (requireAll === value) } className="form-check-input" id={ `requireAll${ value }` } name="requireAll" type="radio" onChange={ event => setRequireAll(value) } />
<Text>{ LocalizeText(`wiredfurni.params.not_requireall.${ value }`) }</Text>
</div>
);
}) }
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionFurniIsOfTypeView: FC<{}> = props =>
{
return <WiredConditionBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_OR_BY_TYPE } save={ null } />;
};
@@ -0,0 +1,42 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionFurniMatchesSnapshotView: FC<{}> = props =>
{
const [ stateFlag, setStateFlag ] = useState(0);
const [ directionFlag, setDirectionFlag ] = useState(0);
const [ positionFlag, setPositionFlag ] = useState(0);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ stateFlag, directionFlag, positionFlag ]);
useEffect(() =>
{
setStateFlag(trigger.getBoolean(0) ? 1 : 0);
setDirectionFlag(trigger.getBoolean(1) ? 1 : 0);
setPositionFlag(trigger.getBoolean(2) ? 1 : 0);
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.conditions') }</Text>
<div className="flex items-center gap-1">
<input checked={ !!stateFlag } className="form-check-input" id="stateFlag" type="checkbox" onChange={ event => setStateFlag(event.target.checked ? 1 : 0) } />
<Text>{ LocalizeText('wiredfurni.params.condition.state') }</Text>
</div>
<div className="flex items-center gap-1">
<input checked={ !!directionFlag } className="form-check-input" id="directionFlag" type="checkbox" onChange={ event => setDirectionFlag(event.target.checked ? 1 : 0) } />
<Text>{ LocalizeText('wiredfurni.params.condition.direction') }</Text>
</div>
<div className="flex items-center gap-1">
<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>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,64 @@
import { WiredConditionlayout } from '../../../../api';
import { WiredConditionActorHasHandItemView } from './WiredConditionActorHasHandItem';
import { WiredConditionActorIsGroupMemberView } from './WiredConditionActorIsGroupMemberView';
import { WiredConditionActorIsOnFurniView } from './WiredConditionActorIsOnFurniView';
import { WiredConditionActorIsTeamMemberView } from './WiredConditionActorIsTeamMemberView';
import { WiredConditionActorIsWearingBadgeView } from './WiredConditionActorIsWearingBadgeView';
import { WiredConditionActorIsWearingEffectView } from './WiredConditionActorIsWearingEffectView';
import { WiredConditionDateRangeView } from './WiredConditionDateRangeView';
import { WiredConditionFurniHasAvatarOnView } from './WiredConditionFurniHasAvatarOnView';
import { WiredConditionFurniHasFurniOnView } from './WiredConditionFurniHasFurniOnView';
import { WiredConditionFurniHasNotFurniOnView } from './WiredConditionFurniHasNotFurniOnView';
import { WiredConditionFurniIsOfTypeView } from './WiredConditionFurniIsOfTypeView';
import { WiredConditionFurniMatchesSnapshotView } from './WiredConditionFurniMatchesSnapshotView';
import { WiredConditionTimeElapsedLessView } from './WiredConditionTimeElapsedLessView';
import { WiredConditionTimeElapsedMoreView } from './WiredConditionTimeElapsedMoreView';
import { WiredConditionUserCountInRoomView } from './WiredConditionUserCountInRoomView';
export const WiredConditionLayoutView = (code: number) =>
{
switch(code)
{
case WiredConditionlayout.ACTOR_HAS_HANDITEM:
return <WiredConditionActorHasHandItemView />;
case WiredConditionlayout.ACTOR_IS_GROUP_MEMBER:
case WiredConditionlayout.NOT_ACTOR_IN_GROUP:
return <WiredConditionActorIsGroupMemberView />;
case WiredConditionlayout.ACTOR_IS_ON_FURNI:
case WiredConditionlayout.NOT_ACTOR_ON_FURNI:
return <WiredConditionActorIsOnFurniView />;
case WiredConditionlayout.ACTOR_IS_IN_TEAM:
case WiredConditionlayout.NOT_ACTOR_IN_TEAM:
return <WiredConditionActorIsTeamMemberView />;
case WiredConditionlayout.ACTOR_IS_WEARING_BADGE:
case WiredConditionlayout.NOT_ACTOR_WEARS_BADGE:
return <WiredConditionActorIsWearingBadgeView />;
case WiredConditionlayout.ACTOR_IS_WEARING_EFFECT:
case WiredConditionlayout.NOT_ACTOR_WEARING_EFFECT:
return <WiredConditionActorIsWearingEffectView />;
case WiredConditionlayout.DATE_RANGE_ACTIVE:
return <WiredConditionDateRangeView />;
case WiredConditionlayout.FURNIS_HAVE_AVATARS:
case WiredConditionlayout.FURNI_NOT_HAVE_HABBO:
return <WiredConditionFurniHasAvatarOnView />;
case WiredConditionlayout.HAS_STACKED_FURNIS:
return <WiredConditionFurniHasFurniOnView />;
case WiredConditionlayout.NOT_HAS_STACKED_FURNIS:
return <WiredConditionFurniHasNotFurniOnView />;
case WiredConditionlayout.STUFF_TYPE_MATCHES:
case WiredConditionlayout.NOT_FURNI_IS_OF_TYPE:
return <WiredConditionFurniIsOfTypeView />;
case WiredConditionlayout.STATES_MATCH:
case WiredConditionlayout.NOT_STATES_MATCH:
return <WiredConditionFurniMatchesSnapshotView />;
case WiredConditionlayout.TIME_ELAPSED_LESS:
return <WiredConditionTimeElapsedLessView />;
case WiredConditionlayout.TIME_ELAPSED_MORE:
return <WiredConditionTimeElapsedMoreView />;
case WiredConditionlayout.USER_COUNT_IN:
case WiredConditionlayout.NOT_USER_COUNT_IN:
return <WiredConditionUserCountInRoomView />;
}
return null;
};
@@ -0,0 +1,33 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionTimeElapsedLessView: FC<{}> = props =>
{
const [ time, setTime ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ time ]);
useEffect(() =>
{
setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.allowbefore', [ 'seconds' ], [ GetWiredTimeLocale(time) ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 1200 }
min={ 1 }
value={ time }
onChange={ event => setTime(event) } />
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,33 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionTimeElapsedMoreView: FC<{}> = props =>
{
const [ time, setTime ] = useState(-1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ time ]);
useEffect(() =>
{
setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.allowafter', [ 'seconds' ], [ GetWiredTimeLocale(time) ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 1200 }
min={ 1 }
value={ time }
onChange={ event => setTime(event) } />
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,52 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredConditionBaseView } from './WiredConditionBaseView';
export const WiredConditionUserCountInRoomView: FC<{}> = props =>
{
const [ min, setMin ] = useState(1);
const [ max, setMax ] = useState(0);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ min, max ]);
useEffect(() =>
{
if(trigger.intData.length >= 2)
{
setMin(trigger.intData[0]);
setMax(trigger.intData[1]);
}
else
{
setMin(1);
setMax(0);
}
}, [ trigger ]);
return (
<WiredConditionBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.usercountmin', [ 'value' ], [ min.toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 50 }
min={ 1 }
value={ min }
onChange={ event => setMin(event) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.usercountmax', [ 'value' ], [ max.toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 125 }
min={ 0 }
value={ max }
onChange={ event => setMax(event) } />
</div>
</WiredConditionBaseView>
);
};
@@ -0,0 +1,39 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerAvatarEnterRoomView: FC<{}> = props =>
{
const [ username, setUsername ] = useState('');
const [ avatarMode, setAvatarMode ] = useState(0);
const { trigger = null, setStringParam = null } = useWired();
const save = () => setStringParam((avatarMode === 1) ? username : '');
useEffect(() =>
{
setUsername(trigger.stringData);
setAvatarMode(trigger.stringData ? 1 : 0);
}, [ trigger ]);
return (
<WiredTriggerBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.picktriggerer') }</Text>
<div className="flex items-center gap-1">
<input checked={ (avatarMode === 0) } className="form-check-input" id="avatarMode0" name="avatarMode" type="radio" onChange={ event => setAvatarMode(0) } />
<Text>{ LocalizeText('wiredfurni.params.anyavatar') }</Text>
</div>
<div className="flex items-center gap-1">
<input checked={ (avatarMode === 1) } className="form-check-input" id="avatarMode1" name="avatarMode" type="radio" onChange={ event => setAvatarMode(1) } />
<Text>{ LocalizeText('wiredfurni.params.certainavatar') }</Text>
</div>
{ (avatarMode === 1) &&
<NitroInput type="text" value={ username } onChange={ event => setUsername(event.target.value) } /> }
</div>
</WiredTriggerBaseView>
);
};
@@ -0,0 +1,46 @@
import { GetSessionDataManager } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerAvatarSaysSomethingView: FC<{}> = props =>
{
const [ message, setMessage ] = useState('');
const [ triggererAvatar, setTriggererAvatar ] = useState(-1);
const { trigger = null, setStringParam = null, setIntParams = null } = useWired();
const save = () =>
{
setStringParam(message);
setIntParams([ triggererAvatar ]);
};
useEffect(() =>
{
setMessage(trigger.stringData);
setTriggererAvatar((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredTriggerBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.whatissaid') }</Text>
<NitroInput type="text" value={ message } onChange={ event => setMessage(event.target.value) } />
</div>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.picktriggerer') }</Text>
<div className="flex items-center gap-1">
<input checked={ (triggererAvatar === 0) } className="form-check-input" id="triggererAvatar0" name="triggererAvatar" type="radio" onChange={ event => setTriggererAvatar(0) } />
<Text>{ LocalizeText('wiredfurni.params.anyavatar') }</Text>
</div>
<div className="flex items-center gap-1">
<input checked={ (triggererAvatar === 1) } className="form-check-input" id="triggererAvatar1" name="triggererAvatar" type="radio" onChange={ event => setTriggererAvatar(1) } />
<Text>{ GetSessionDataManager().userName }</Text>
</div>
</div>
</WiredTriggerBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerAvatarWalksOffFurniView: FC<{}> = props =>
{
return <WiredTriggerBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_OR_BY_TYPE } save={ null } />;
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerAvatarWalksOnFurniView: FC<{}> = props =>
{
return <WiredTriggerBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_OR_BY_TYPE } save={ null } />;
};
@@ -0,0 +1,23 @@
import { FC, PropsWithChildren } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredBaseView } from '../WiredBaseView';
export interface WiredTriggerBaseViewProps
{
hasSpecialInput: boolean;
requiresFurni: number;
save: () => void;
}
export const WiredTriggerBaseView: FC<PropsWithChildren<WiredTriggerBaseViewProps>> = props =>
{
const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, hasSpecialInput = false, children = null } = props;
const onSave = () => (save && save());
return (
<WiredBaseView hasSpecialInput={ hasSpecialInput } requiresFurni={ requiresFurni } save={ onSave } wiredType="trigger">
{ children }
</WiredBaseView>
);
};
@@ -0,0 +1,28 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerBotReachedAvatarView: FC<{}> = props =>
{
const [ botName, setBotName ] = useState('');
const { trigger = null, setStringParam = null } = useWired();
const save = () => setStringParam(botName);
useEffect(() =>
{
setBotName(trigger.stringData);
}, [ trigger ]);
return (
<WiredTriggerBaseView 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>
</WiredTriggerBaseView>
);
};
@@ -0,0 +1,28 @@
import { FC, useEffect, useState } from 'react';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { NitroInput } from '../../../../layout';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerBotReachedStuffView: FC<{}> = props =>
{
const [ botName, setBotName ] = useState('');
const { trigger = null, setStringParam = null } = useWired();
const save = () => setStringParam(botName);
useEffect(() =>
{
setBotName(trigger.stringData);
}, [ trigger ]);
return (
<WiredTriggerBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_OR_BY_TYPE } 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>
</WiredTriggerBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerCollisionView: FC<{}> = props =>
{
return <WiredTriggerBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ null } />;
};
@@ -0,0 +1,33 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggeExecuteOnceView: FC<{}> = props =>
{
const [ time, setTime ] = useState(1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ time ]);
useEffect(() =>
{
setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredTriggerBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.settime', [ 'seconds' ], [ GetWiredTimeLocale(time) ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 1200 }
min={ 1 }
value={ time }
onChange={ event => setTime(event) } />
</div>
</WiredTriggerBaseView>
);
};
@@ -0,0 +1,33 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { FriendlyTime, LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggeExecutePeriodicallyLongView: FC<{}> = props =>
{
const [ time, setTime ] = useState(1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ time ]);
useEffect(() =>
{
setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredTriggerBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.setlongtime', [ 'time' ], [ FriendlyTime.format(time * 5).toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 120 }
min={ 1 }
value={ time }
onChange={ event => setTime(event) } />
</div>
</WiredTriggerBaseView>
);
};
@@ -0,0 +1,33 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { GetWiredTimeLocale, LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggeExecutePeriodicallyView: FC<{}> = props =>
{
const [ time, setTime ] = useState(1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ time ]);
useEffect(() =>
{
setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredTriggerBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.settime', [ 'seconds' ], [ GetWiredTimeLocale(time) ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 60 }
min={ 1 }
value={ time }
onChange={ event => setTime(event) } />
</div>
</WiredTriggerBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerGameEndsView: FC<{}> = props =>
{
return <WiredTriggerBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ null } />;
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerGameStartsView: FC<{}> = props =>
{
return <WiredTriggerBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ null } />;
};
@@ -0,0 +1,52 @@
import { WiredTriggerLayout } from '../../../../api';
import { WiredTriggerAvatarEnterRoomView } from './WiredTriggerAvatarEnterRoomView';
import { WiredTriggerAvatarSaysSomethingView } from './WiredTriggerAvatarSaysSomethingView';
import { WiredTriggerAvatarWalksOffFurniView } from './WiredTriggerAvatarWalksOffFurniView';
import { WiredTriggerAvatarWalksOnFurniView } from './WiredTriggerAvatarWalksOnFurni';
import { WiredTriggerBotReachedAvatarView } from './WiredTriggerBotReachedAvatarView';
import { WiredTriggerBotReachedStuffView } from './WiredTriggerBotReachedStuffView';
import { WiredTriggerCollisionView } from './WiredTriggerCollisionView';
import { WiredTriggeExecuteOnceView } from './WiredTriggerExecuteOnceView';
import { WiredTriggeExecutePeriodicallyLongView } from './WiredTriggerExecutePeriodicallyLongView';
import { WiredTriggeExecutePeriodicallyView } from './WiredTriggerExecutePeriodicallyView';
import { WiredTriggerGameEndsView } from './WiredTriggerGameEndsView';
import { WiredTriggerGameStartsView } from './WiredTriggerGameStartsView';
import { WiredTriggeScoreAchievedView } from './WiredTriggerScoreAchievedView';
import { WiredTriggerToggleFurniView } from './WiredTriggerToggleFurniView';
export const WiredTriggerLayoutView = (code: number) =>
{
switch(code)
{
case WiredTriggerLayout.AVATAR_ENTERS_ROOM:
return <WiredTriggerAvatarEnterRoomView />;
case WiredTriggerLayout.AVATAR_SAYS_SOMETHING:
return <WiredTriggerAvatarSaysSomethingView />;
case WiredTriggerLayout.AVATAR_WALKS_OFF_FURNI:
return <WiredTriggerAvatarWalksOffFurniView />;
case WiredTriggerLayout.AVATAR_WALKS_ON_FURNI:
return <WiredTriggerAvatarWalksOnFurniView />;
case WiredTriggerLayout.BOT_REACHED_AVATAR:
return <WiredTriggerBotReachedAvatarView />;
case WiredTriggerLayout.BOT_REACHED_STUFF:
return <WiredTriggerBotReachedStuffView />;
case WiredTriggerLayout.COLLISION:
return <WiredTriggerCollisionView />;
case WiredTriggerLayout.EXECUTE_ONCE:
return <WiredTriggeExecuteOnceView />;
case WiredTriggerLayout.EXECUTE_PERIODICALLY:
return <WiredTriggeExecutePeriodicallyView />;
case WiredTriggerLayout.EXECUTE_PERIODICALLY_LONG:
return <WiredTriggeExecutePeriodicallyLongView />;
case WiredTriggerLayout.GAME_ENDS:
return <WiredTriggerGameEndsView />;
case WiredTriggerLayout.GAME_STARTS:
return <WiredTriggerGameStartsView />;
case WiredTriggerLayout.SCORE_ACHIEVED:
return <WiredTriggeScoreAchievedView />;
case WiredTriggerLayout.TOGGLE_FURNI:
return <WiredTriggerToggleFurniView />;
}
return null;
};
@@ -0,0 +1,33 @@
import { FC, useEffect, useState } from 'react';
import ReactSlider from 'react-slider';
import { LocalizeText, WiredFurniType } from '../../../../api';
import { Text } from '../../../../common';
import { useWired } from '../../../../hooks';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggeScoreAchievedView: FC<{}> = props =>
{
const [ points, setPoints ] = useState(1);
const { trigger = null, setIntParams = null } = useWired();
const save = () => setIntParams([ points ]);
useEffect(() =>
{
setPoints((trigger.intData.length > 0) ? trigger.intData[0] : 0);
}, [ trigger ]);
return (
<WiredTriggerBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
<div className="flex flex-col gap-1">
<Text bold>{ LocalizeText('wiredfurni.params.setscore', [ 'points' ], [ points.toString() ]) }</Text>
<ReactSlider
className={ 'nitro-slider' }
max={ 1000 }
min={ 1 }
value={ points }
onChange={ event => setPoints(event) } />
</div>
</WiredTriggerBaseView>
);
};
@@ -0,0 +1,8 @@
import { FC } from 'react';
import { WiredFurniType } from '../../../../api';
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
export const WiredTriggerToggleFurniView: FC<{}> = props =>
{
return <WiredTriggerBaseView hasSpecialInput={ false } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_OR_BY_TYPE } save={ null } />;
};