mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
🆕 wf_act_send_signal & wf_trg_recv_signal
the signal sender can only be a max of 25 in a room
the signal receiver can only be a max of 5 in a room
one signal receiver can only accept a max of 5 senders (you can select the receivers with the senders)
Why : otherwise you can flood the rooms and let you CPU go 🍌
This commit is contained in:
@@ -31,4 +31,5 @@ export class WiredActionLayoutCode
|
||||
public static FURNI_BYTYPE_SELECTOR: number = 30;
|
||||
public static USERS_AREA_SELECTOR: number = 31;
|
||||
public static USERS_NEIGHBORHOOD_SELECTOR: number = 32;
|
||||
public static SEND_SIGNAL: number = 33;
|
||||
}
|
||||
|
||||
@@ -14,4 +14,5 @@ export class WiredTriggerLayout
|
||||
public static EXECUTE_PERIODICALLY_LONG: number = 12;
|
||||
public static BOT_REACHED_STUFF: number = 13;
|
||||
public static BOT_REACHED_AVATAR: number = 14;
|
||||
public static RECEIVE_SIGNAL: number = 15;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,14 @@ export interface WiredActionBaseViewProps
|
||||
hasSpecialInput: boolean;
|
||||
requiresFurni: number;
|
||||
save: () => void;
|
||||
validate?: () => boolean;
|
||||
cardStyle?: CSSProperties;
|
||||
hideDelay?: boolean;
|
||||
}
|
||||
|
||||
export const WiredActionBaseView: FC<PropsWithChildren<WiredActionBaseViewProps>> = props =>
|
||||
{
|
||||
const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, hasSpecialInput = false, children = null, cardStyle = undefined, hideDelay = false } = props;
|
||||
const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, validate = null, hasSpecialInput = false, children = null, cardStyle = undefined, hideDelay = false } = props;
|
||||
const { trigger = null, actionDelay = 0, setActionDelay = null } = useWired();
|
||||
|
||||
useEffect(() =>
|
||||
@@ -25,7 +26,7 @@ export const WiredActionBaseView: FC<PropsWithChildren<WiredActionBaseViewProps>
|
||||
}, [ trigger, setActionDelay ]);
|
||||
|
||||
return (
|
||||
<WiredBaseView hasSpecialInput={ hasSpecialInput } requiresFurni={ requiresFurni } save={ save } wiredType="action" cardStyle={ cardStyle }>
|
||||
<WiredBaseView hasSpecialInput={ hasSpecialInput } requiresFurni={ requiresFurni } save={ save } validate={ validate } wiredType="action" cardStyle={ cardStyle }>
|
||||
{ children }
|
||||
{ !hideDelay && !!children && <hr className="m-0 bg-dark" /> }
|
||||
{ !hideDelay && <div className="flex flex-col">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { WiredActionLayoutCode } from '../../../../api';
|
||||
import { WiredActionBotChangeFigureView } from './WiredActionBotChangeFigureView';
|
||||
import { WiredActionSendSignalView } from './WiredActionSendSignalView';
|
||||
import { WiredActionFurniAreaView } from '../selectors/WiredActionFurniAreaView';
|
||||
import { WiredSelectorFurniNeighborhoodView } from '../selectors/WiredSelectorFurniNeighborhoodView';
|
||||
import { WiredSelectorFurniByTypeView } from '../selectors/WiredSelectorFurniByTypeView';
|
||||
@@ -94,6 +95,8 @@ export const WiredActionLayoutView = (code: number) =>
|
||||
return <WiredSelectorUsersAreaView />;
|
||||
case WiredActionLayoutCode.USERS_NEIGHBORHOOD_SELECTOR:
|
||||
return <WiredSelectorUsersNeighborhoodView />;
|
||||
case WiredActionLayoutCode.SEND_SIGNAL:
|
||||
return <WiredActionSendSignalView />;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { LocalizeText, WiredFurniType } from '../../../../api';
|
||||
import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { WiredActionBaseView } from './WiredActionBaseView';
|
||||
|
||||
const ANTENNA_PICKED = 0;
|
||||
const ANTENNA_TRIGGER = 1;
|
||||
|
||||
const FORWARD_NONE = 0;
|
||||
const FORWARD_TRIGGER = 1;
|
||||
const FORWARD_SELECTOR = 200;
|
||||
const FORWARD_SIGNAL = 201;
|
||||
|
||||
const FURNI_FORWARD_OPTIONS = [
|
||||
{ value: FORWARD_TRIGGER, label: 'wiredfurni.params.sources.furni.0' },
|
||||
{ value: FORWARD_SELECTOR, label: 'wiredfurni.params.sources.furni.200' },
|
||||
{ value: FORWARD_SIGNAL, label: 'wiredfurni.params.sources.furni.201' },
|
||||
];
|
||||
|
||||
const USER_FORWARD_OPTIONS = [
|
||||
{ value: FORWARD_TRIGGER, label: 'wiredfurni.params.sources.users.0' },
|
||||
{ value: FORWARD_SELECTOR, label: 'wiredfurni.params.sources.users.200' },
|
||||
{ value: FORWARD_SIGNAL, label: 'wiredfurni.params.sources.users.201' },
|
||||
];
|
||||
|
||||
export const WiredActionSendSignalView: FC<{}> = () =>
|
||||
{
|
||||
const [ antennaSource, setAntennaSource ] = useState(ANTENNA_PICKED);
|
||||
const [ furniForward, setFurniForward ] = useState(FORWARD_NONE);
|
||||
const [ userForward, setUserForward ] = useState(FORWARD_NONE);
|
||||
const [ signalPerFurni, setSignalPerFurni ] = useState(false);
|
||||
const [ signalPerUser, setSignalPerUser ] = useState(false);
|
||||
const [ showAdvanced, setShowAdvanced ] = useState(false);
|
||||
|
||||
const { trigger = null, setIntParams } = useWired();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!trigger) return;
|
||||
|
||||
const p = trigger.intData;
|
||||
if(p.length >= 1) setAntennaSource(p[0]);
|
||||
if(p.length >= 2) setFurniForward(p[1]);
|
||||
if(p.length >= 3) setUserForward(p[2]);
|
||||
if(p.length >= 4) setSignalPerFurni(p[3] === 1);
|
||||
if(p.length >= 5) setSignalPerUser(p[4] === 1);
|
||||
|
||||
if(p.length >= 1 && (p[0] !== ANTENNA_PICKED || p[1] !== FORWARD_NONE ||
|
||||
p[2] !== FORWARD_NONE || (p.length >= 4 && p[3] === 1) || (p.length >= 5 && p[4] === 1)))
|
||||
{
|
||||
setShowAdvanced(true);
|
||||
}
|
||||
}, [ trigger ]);
|
||||
|
||||
const save = useCallback(() =>
|
||||
{
|
||||
setIntParams([
|
||||
antennaSource,
|
||||
furniForward,
|
||||
userForward,
|
||||
signalPerFurni ? 1 : 0,
|
||||
signalPerUser ? 1 : 0,
|
||||
]);
|
||||
}, [ antennaSource, furniForward, userForward, signalPerFurni, signalPerUser, setIntParams ]);
|
||||
|
||||
return (
|
||||
<WiredActionBaseView
|
||||
hasSpecialInput={ true }
|
||||
requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID }
|
||||
cardStyle={ { width: '400px' } }
|
||||
save={ save }>
|
||||
<div className="flex flex-col gap-2">
|
||||
|
||||
<div
|
||||
className="cursor-pointer text-center"
|
||||
onClick={ () => setShowAdvanced(!showAdvanced) }>
|
||||
<Text small underline>
|
||||
{ showAdvanced
|
||||
? LocalizeText('wiredfurni.params.hide_advanced')
|
||||
: LocalizeText('wiredfurni.params.show_advanced') }
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
{ showAdvanced && <>
|
||||
|
||||
{ /* --- Antennas --- */ }
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.sources.furni.title.signal_antenna') }</Text>
|
||||
<div className="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
id="signal-antenna-toggle"
|
||||
role="switch"
|
||||
checked={ antennaSource === ANTENNA_PICKED }
|
||||
onChange={ () => setAntennaSource(antennaSource === ANTENNA_PICKED ? ANTENNA_TRIGGER : ANTENNA_PICKED) } />
|
||||
<label className="form-check-label" htmlFor="signal-antenna-toggle">
|
||||
<Text small>{ LocalizeText('wiredfurni.params.sources.furni.100') }</Text>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{ /* --- Furni to forward --- */ }
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.sources.furni.title.signal_forward') }</Text>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="form-check form-switch flex-1 mb-0">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
id="signal-furni-toggle"
|
||||
role="switch"
|
||||
checked={ furniForward !== FORWARD_NONE }
|
||||
onChange={ e => setFurniForward(e.target.checked ? FORWARD_TRIGGER : FORWARD_NONE) } />
|
||||
<label className="form-check-label" htmlFor="signal-furni-toggle">
|
||||
<Text small>{ LocalizeText('wiredfurni.params.sources.furni.200') }</Text>
|
||||
</label>
|
||||
</div>
|
||||
{ furniForward !== FORWARD_NONE &&
|
||||
<select
|
||||
className="form-select form-select-sm"
|
||||
style={ { width: 'auto', minWidth: '160px' } }
|
||||
value={ furniForward }
|
||||
onChange={ e => setFurniForward(parseInt(e.target.value)) }>
|
||||
{ FURNI_FORWARD_OPTIONS.map(opt =>
|
||||
<option key={ opt.value } value={ opt.value }>{ LocalizeText(opt.label) }</option>
|
||||
) }
|
||||
</select>
|
||||
}
|
||||
</div>
|
||||
|
||||
{ /* --- Users to forward --- */ }
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.sources.users.title.signal_forward') }</Text>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="form-check form-switch flex-1 mb-0">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
id="signal-user-toggle"
|
||||
role="switch"
|
||||
checked={ userForward !== FORWARD_NONE }
|
||||
onChange={ e => setUserForward(e.target.checked ? FORWARD_TRIGGER : FORWARD_NONE) } />
|
||||
<label className="form-check-label" htmlFor="signal-user-toggle">
|
||||
<Text small>{ LocalizeText('wiredfurni.params.sources.users.0') }</Text>
|
||||
</label>
|
||||
</div>
|
||||
{ userForward !== FORWARD_NONE &&
|
||||
<select
|
||||
className="form-select form-select-sm"
|
||||
style={ { width: 'auto', minWidth: '160px' } }
|
||||
value={ userForward }
|
||||
onChange={ e => setUserForward(parseInt(e.target.value)) }>
|
||||
{ USER_FORWARD_OPTIONS.map(opt =>
|
||||
<option key={ opt.value } value={ opt.value }>{ LocalizeText(opt.label) }</option>
|
||||
) }
|
||||
</select>
|
||||
}
|
||||
</div>
|
||||
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.signal.options') }</Text>
|
||||
<div className="form-check">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
id="signal-per-furni"
|
||||
checked={ signalPerFurni }
|
||||
onChange={ e => setSignalPerFurni(e.target.checked) } />
|
||||
<label className="form-check-label" htmlFor="signal-per-furni">
|
||||
<Text small>{ LocalizeText('wiredfurni.params.signal.split_furni') }</Text>
|
||||
</label>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
id="signal-per-user"
|
||||
checked={ signalPerUser }
|
||||
onChange={ e => setSignalPerUser(e.target.checked) } />
|
||||
<label className="form-check-label" htmlFor="signal-per-user">
|
||||
<Text small>{ LocalizeText('wiredfurni.params.signal.split_users') }</Text>
|
||||
</label>
|
||||
</div>
|
||||
</> }
|
||||
|
||||
</div>
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
};
|
||||
@@ -12,6 +12,7 @@ import { WiredTriggeExecutePeriodicallyView } from './WiredTriggerExecutePeriodi
|
||||
import { WiredTriggerGameEndsView } from './WiredTriggerGameEndsView';
|
||||
import { WiredTriggerGameStartsView } from './WiredTriggerGameStartsView';
|
||||
import { WiredTriggeScoreAchievedView } from './WiredTriggerScoreAchievedView';
|
||||
import { WiredTriggerReceiveSignalView } from './WiredTriggerReceiveSignalView';
|
||||
import { WiredTriggerToggleFurniView } from './WiredTriggerToggleFurniView';
|
||||
|
||||
export const WiredTriggerLayoutView = (code: number) =>
|
||||
@@ -46,6 +47,8 @@ export const WiredTriggerLayoutView = (code: number) =>
|
||||
return <WiredTriggeScoreAchievedView />;
|
||||
case WiredTriggerLayout.TOGGLE_FURNI:
|
||||
return <WiredTriggerToggleFurniView />;
|
||||
case WiredTriggerLayout.RECEIVE_SIGNAL:
|
||||
return <WiredTriggerReceiveSignalView />;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeText, WiredFurniType } from '../../../../api';
|
||||
import { Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { WiredTriggerBaseView } from './WiredTriggerBaseView';
|
||||
|
||||
export const WiredTriggerReceiveSignalView: FC<{}> = () =>
|
||||
{
|
||||
const [ senderCount, setSenderCount ] = useState(0);
|
||||
const [ maxSenders, setMaxSenders ] = useState(5);
|
||||
|
||||
const { trigger = null } = useWired();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!trigger) return;
|
||||
|
||||
const p = trigger.intData;
|
||||
if(p.length >= 2) setSenderCount(p[1]);
|
||||
if(p.length >= 3) setMaxSenders(p[2]);
|
||||
}, [ trigger ]);
|
||||
|
||||
return (
|
||||
<WiredTriggerBaseView hasSpecialInput={ true } requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ null }>
|
||||
<div className="flex items-center justify-between">
|
||||
<Text small>{ LocalizeText('wiredfurni.params.signal.senders_connected') }</Text>
|
||||
<Text bold small>{ senderCount }/{ maxSenders }</Text>
|
||||
</div>
|
||||
</WiredTriggerBaseView>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ConditionDefinition, GetRoomEngine, GetSessionDataManager, OpenMessageComposer, RoomObjectCategory, RoomObjectVariable, Triggerable, TriggerDefinition, UpdateActionMessageComposer, UpdateConditionMessageComposer, UpdateTriggerMessageComposer, WiredActionDefinition, WiredFurniActionEvent, WiredFurniConditionEvent, WiredFurniTriggerEvent, WiredOpenEvent, WiredSaveSuccessEvent } from '@nitrots/nitro-renderer';
|
||||
import { ConditionDefinition, GetRoomEngine, GetSessionDataManager, OpenMessageComposer, RoomObjectCategory, RoomObjectVariable, Triggerable, TriggerDefinition, UpdateActionMessageComposer, UpdateConditionMessageComposer, UpdateTriggerMessageComposer, WiredActionDefinition, WiredFurniActionEvent, WiredFurniConditionEvent, WiredFurniTriggerEvent, WiredOpenEvent, WiredSaveSuccessEvent, WiredValidationErrorEvent } from '@nitrots/nitro-renderer';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useBetween } from 'use-between';
|
||||
import { GetRoomSession, IsOwnerOfFloorFurniture, LocalizeText, SendMessageComposer, WiredFurniType, WiredSelectionVisualizer } from '../../api';
|
||||
@@ -17,7 +17,7 @@ const useWiredState = () =>
|
||||
const [ invertSelection, setInvertSelection ] = useState<boolean>(false);
|
||||
const [ neighborhoodTiles, setNeighborhoodTiles ] = useState<{ x: number; y: number }[] | null>(null);
|
||||
const [ neighborhoodInvert, setNeighborhoodInvert ] = useState<boolean>(false);
|
||||
const { showConfirm = null } = useNotification();
|
||||
const { showConfirm = null, simpleAlert = null } = useNotification();
|
||||
|
||||
const saveWired = () =>
|
||||
{
|
||||
@@ -169,6 +169,16 @@ const useWiredState = () =>
|
||||
setTrigger(null);
|
||||
});
|
||||
|
||||
useMessageEvent<WiredValidationErrorEvent>(WiredValidationErrorEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
if(parser.info && parser.info.length)
|
||||
{
|
||||
simpleAlert(parser.info, null, null, null, LocalizeText('wiredfurni.title'));
|
||||
}
|
||||
});
|
||||
|
||||
useMessageEvent<WiredFurniActionEvent>(WiredFurniActionEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
Reference in New Issue
Block a user