diff --git a/.vscode/settings.json b/.vscode/settings.json index 7b328b85..b0a56f10 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,5 +12,6 @@ "git.ignoreLimitWarning": true, "files.eol": "\n", "files.insertFinalNewline": true, - "files.trimFinalNewlines": true + "files.trimFinalNewlines": true, + "editor.wordWrap": "on" } diff --git a/package-lock.json b/package-lock.json index 66944ba0..4bd0f3e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2376,6 +2376,15 @@ "redux": "^4.0.0" } }, + "@types/react-slider": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/react-slider/-/react-slider-1.3.0.tgz", + "integrity": "sha512-Hr+P8wiqYAjeFTlf+NWPVGWW79npC8V7KkZdbPlMqo+iblcopPzE/z0m8503j2YmfxoKJKaPnrJe0a6spXacYQ==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -5268,6 +5277,11 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz", "integrity": "sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==" }, + "dom-align": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.2.tgz", + "integrity": "sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==" + }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -14739,6 +14753,71 @@ } } }, + "rc-align": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.9.tgz", + "integrity": "sha512-myAM2R4qoB6LqBul0leaqY8gFaiECDJ3MtQDmzDo9xM9NRT/04TvWOYd2YHU9zvGzqk9QXF6S9/MifzSKDZeMw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "dom-align": "^1.7.0", + "rc-util": "^5.3.0", + "resize-observer-polyfill": "^1.5.1" + } + }, + "rc-motion": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.4.tgz", + "integrity": "sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.2.1" + } + }, + "rc-slider": { + "version": "9.7.2", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.2.tgz", + "integrity": "sha512-mVaLRpDo6otasBs6yVnG02ykI3K6hIrLTNfT5eyaqduFv95UODI9PDS6fWuVVehVpdS4ENgOSwsTjrPVun+k9g==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-tooltip": "^5.0.1", + "rc-util": "^5.0.0", + "shallowequal": "^1.1.0" + } + }, + "rc-tooltip": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz", + "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==", + "requires": { + "@babel/runtime": "^7.11.2", + "rc-trigger": "^5.0.0" + } + }, + "rc-trigger": { + "version": "5.2.9", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.9.tgz", + "integrity": "sha512-0Bxsh2Xe+etejMn73am+jZBcOpsueAZiEKLiGoDfA0fvm/JHLNOiiww3zJ0qgyPOTmbYxhsxFcGOZu+VcbaZhQ==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.5.0" + } + }, + "rc-util": { + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.13.1.tgz", + "integrity": "sha512-Dws2tjXBBihfjVQFlG5JzZ/5O3Wutctm0W94Wb1+M7GD2roWJPrQdSa4AkWm2pn0Ms32zoVPPkWodFeAYZPLfA==", + "requires": { + "@babel/runtime": "^7.12.5", + "react-is": "^16.12.0", + "shallowequal": "^1.1.0" + } + }, "react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -15430,6 +15509,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", @@ -16220,6 +16304,11 @@ "safe-buffer": "^5.0.1" } }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", diff --git a/package.json b/package.json index 82a862a6..f1be2c6c 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "immutable": "^4.0.0-rc.12", "nitro-renderer": "file:../nitro-renderer", "node-sass": "^5.0.0", + "rc-slider": "^9.7.2", "react": "^17.0.2", "react-bootstrap": "^2.0.0-alpha.2", "react-dom": "^17.0.2", @@ -58,6 +59,7 @@ ] }, "devDependencies": { + "@types/react-slider": "^1.3.0", "@types/react-transition-group": "^4.4.1" } } diff --git a/src/assets/images/wired/card-action-corners.png b/src/assets/images/wired/card-action-corners.png new file mode 100644 index 00000000..faec2349 Binary files /dev/null and b/src/assets/images/wired/card-action-corners.png differ diff --git a/src/assets/images/wired/icon_wired_around.png b/src/assets/images/wired/icon_wired_around.png index 363913a9..0b4b5a12 100644 Binary files a/src/assets/images/wired/icon_wired_around.png and b/src/assets/images/wired/icon_wired_around.png differ diff --git a/src/assets/images/wired/icon_wired_left_right.png b/src/assets/images/wired/icon_wired_left_right.png index 9e1b4500..862d6d81 100644 Binary files a/src/assets/images/wired/icon_wired_left_right.png and b/src/assets/images/wired/icon_wired_left_right.png differ diff --git a/src/assets/images/wired/icon_wired_north_east.png b/src/assets/images/wired/icon_wired_north_east.png index 4ae642f4..3710854f 100644 Binary files a/src/assets/images/wired/icon_wired_north_east.png and b/src/assets/images/wired/icon_wired_north_east.png differ diff --git a/src/assets/images/wired/icon_wired_north_west.png b/src/assets/images/wired/icon_wired_north_west.png index b5933ee7..09eeefc1 100644 Binary files a/src/assets/images/wired/icon_wired_north_west.png and b/src/assets/images/wired/icon_wired_north_west.png differ diff --git a/src/assets/images/wired/icon_wired_rotate_clockwise.png b/src/assets/images/wired/icon_wired_rotate_clockwise.png index 73c29eb3..2827e3d2 100644 Binary files a/src/assets/images/wired/icon_wired_rotate_clockwise.png and b/src/assets/images/wired/icon_wired_rotate_clockwise.png differ diff --git a/src/assets/images/wired/icon_wired_rotate_counter_clockwise.png b/src/assets/images/wired/icon_wired_rotate_counter_clockwise.png index 5bde5f7a..7e281bac 100644 Binary files a/src/assets/images/wired/icon_wired_rotate_counter_clockwise.png and b/src/assets/images/wired/icon_wired_rotate_counter_clockwise.png differ diff --git a/src/assets/images/wired/icon_wired_south_east.png b/src/assets/images/wired/icon_wired_south_east.png index f575dd61..4217c4b8 100644 Binary files a/src/assets/images/wired/icon_wired_south_east.png and b/src/assets/images/wired/icon_wired_south_east.png differ diff --git a/src/assets/images/wired/icon_wired_south_west.png b/src/assets/images/wired/icon_wired_south_west.png index 10ebcac3..07ab1f95 100644 Binary files a/src/assets/images/wired/icon_wired_south_west.png and b/src/assets/images/wired/icon_wired_south_west.png differ diff --git a/src/assets/images/wired/icon_wired_up_down.png b/src/assets/images/wired/icon_wired_up_down.png index 3824dce1..c2d243ba 100644 Binary files a/src/assets/images/wired/icon_wired_up_down.png and b/src/assets/images/wired/icon_wired_up_down.png differ diff --git a/src/events/index.ts b/src/events/index.ts index 9ec510a0..684c0bfa 100644 --- a/src/events/index.ts +++ b/src/events/index.ts @@ -5,3 +5,4 @@ export * from './inventory'; export * from './navigator'; export * from './notification-center'; export * from './room-widgets'; +export * from './wired'; diff --git a/src/events/wired/WiredEvent.ts b/src/events/wired/WiredEvent.ts new file mode 100644 index 00000000..d5959215 --- /dev/null +++ b/src/events/wired/WiredEvent.ts @@ -0,0 +1,6 @@ +import { NitroEvent } from 'nitro-renderer'; + +export class WiredEvent extends NitroEvent +{ + public static SAVE_WIRED: string = 'WE_SAVE_WIRED'; +} diff --git a/src/events/wired/WiredSelectObjectEvent.ts b/src/events/wired/WiredSelectObjectEvent.ts new file mode 100644 index 00000000..e82fc9d1 --- /dev/null +++ b/src/events/wired/WiredSelectObjectEvent.ts @@ -0,0 +1,27 @@ +import { WiredEvent } from './WiredEvent'; + +export class WiredSelectObjectEvent extends WiredEvent +{ + public static SELECT_OBJECT: string = 'WE_SELECT_OBJECT'; + + private _objectId: number; + private _category: number; + + constructor(objectId = -1, category = -1) + { + super(WiredSelectObjectEvent.SELECT_OBJECT); + + this._objectId = objectId; + this._category = category; + } + + public get objectId(): number + { + return this._objectId; + } + + public get category(): number + { + return this._category; + } +} diff --git a/src/events/wired/index.ts b/src/events/wired/index.ts new file mode 100644 index 00000000..63ab5775 --- /dev/null +++ b/src/events/wired/index.ts @@ -0,0 +1,2 @@ +export * from './WiredEvent'; +export * from './WiredSelectObjectEvent'; diff --git a/src/index.scss b/src/index.scss index d1c389d9..08696a5c 100644 --- a/src/index.scss +++ b/src/index.scss @@ -1,5 +1,6 @@ @import url('https://fonts.googleapis.com/css2?family=Ubuntu+Condensed:wght@300;400;500&display=swap'); @import '../node_modules/animate.css/animate.css'; +@import '../node_modules/rc-slider/assets/index.css'; @import './assets/styles'; html, diff --git a/src/views/Styles.scss b/src/views/Styles.scss index c6117f4c..c4964b7e 100644 --- a/src/views/Styles.scss +++ b/src/views/Styles.scss @@ -14,3 +14,4 @@ @import './room/RoomView'; @import './room-host/RoomHostView'; @import './toolbar/ToolbarView'; +@import './wired/WiredView'; diff --git a/src/views/main/MainView.tsx b/src/views/main/MainView.tsx index 3d06d83d..540ff32f 100644 --- a/src/views/main/MainView.tsx +++ b/src/views/main/MainView.tsx @@ -11,6 +11,7 @@ import { NotificationCenterView } from '../notification-center/NotificationCente import { RightSideView } from '../right-side/RightSideView'; import { RoomHostView } from '../room-host/RoomHostView'; import { ToolbarView } from '../toolbar/ToolbarView'; +import { WiredView } from '../wired/WiredView'; import { MainViewProps } from './MainView.types'; export const MainView: FC = props => @@ -46,6 +47,7 @@ export const MainView: FC = props => { landingViewVisible && } + diff --git a/src/views/room/handlers/RoomWidgetInfostandHandler.ts b/src/views/room/handlers/RoomWidgetInfostandHandler.ts index eda7705d..fc68071a 100644 --- a/src/views/room/handlers/RoomWidgetInfostandHandler.ts +++ b/src/views/room/handlers/RoomWidgetInfostandHandler.ts @@ -1,5 +1,7 @@ import { IFurnitureData, Nitro, NitroEvent, ObjectDataFactory, PetFigureData, PetType, RoomAdsUpdateComposer, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomObjectVariable, RoomSessionPetInfoUpdateEvent, RoomSessionUserBadgesEvent, RoomTradingLevelEnum, RoomUnitDropHandItemComposer, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUserData, RoomWidgetEnumItemExtradataParameter, SecurityLevel, Vector3d } from 'nitro-renderer'; import { GetConnection, GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture } from '../../../api'; +import { WiredSelectObjectEvent } from '../../../events'; +import { dispatchUiEvent } from '../../../hooks/events'; import { LocalizeText } from '../../../utils/LocalizeText'; import { RoomWidgetObjectNameEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../events'; import { RoomWidgetChangeMottoMessage, RoomWidgetFurniActionMessage, RoomWidgetMessage, RoomWidgetRoomObjectMessage, RoomWidgetUserActionMessage } from '../messages'; @@ -386,10 +388,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler event.rentCouldBeUsedForBuyout = furnitureData.rentCouldBeUsedForBuyout; event.availableForBuildersClub = furnitureData.availableForBuildersClub; - // if(this._container.wiredService && (k.category === RoomObjectCategory.FLOOR)) - // { - // this._container.wiredService.selectFurniture(roomObject.id, furnitureData.name); - // } + dispatchUiEvent(new WiredSelectObjectEvent(event.id, event.category)); } } diff --git a/src/views/shared/avatar-image/AvatarImageView.tsx b/src/views/shared/avatar-image/AvatarImageView.tsx index 9d3f6ea2..40377a63 100644 --- a/src/views/shared/avatar-image/AvatarImageView.tsx +++ b/src/views/shared/avatar-image/AvatarImageView.tsx @@ -1,5 +1,5 @@ import { AvatarScaleType, AvatarSetType } from 'nitro-renderer'; -import { FC, useCallback, useEffect, useState } from 'react'; +import { FC, useEffect, useState } from 'react'; import { GetAvatarRenderManager } from '../../../api'; import { AvatarImageViewProps } from './AvatarImageView.types'; @@ -8,39 +8,32 @@ export const AvatarImageView: FC = props => const { figure = '', gender = 'M', headOnly = false, direction = 0, scale = 1 } = props; const [ avatarUrl, setAvatarUrl ] = useState(null); + const [ randomValue, setRandomValue ] = useState(-1); - const getUserImageUrl = useCallback(() => + useEffect(() => { - let url = null; + if(randomValue) {} const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, gender, { - resetFigure: (figure) => setAvatarUrl(getUserImageUrl()), + resetFigure: figure => setRandomValue(Math.random()), dispose: () => {}, disposed: false }, null); - if(avatarImage) - { - let setType = AvatarSetType.FULL; + if(!avatarImage) return; + + let setType = AvatarSetType.FULL; - if(headOnly) setType = AvatarSetType.HEAD; + if(headOnly) setType = AvatarSetType.HEAD; - avatarImage.setDirection(setType, direction); + avatarImage.setDirection(setType, direction); - const image = avatarImage.getCroppedImage(setType); + const image = avatarImage.getCroppedImage(setType); - if(image) url = image.src; + if(image) setAvatarUrl(image.src); - avatarImage.dispose(); - } - - return url; - }, [ figure, gender, direction, headOnly ]); - - useEffect(() => - { - setAvatarUrl(getUserImageUrl()); - }, [ getUserImageUrl ]); + avatarImage.dispose(); + }, [ figure, gender, direction, headOnly, randomValue ]); const url = `url('${ avatarUrl }')`; diff --git a/src/views/wired/WiredMessageHandler.tsx b/src/views/wired/WiredMessageHandler.tsx new file mode 100644 index 00000000..cae3aed7 --- /dev/null +++ b/src/views/wired/WiredMessageHandler.tsx @@ -0,0 +1,62 @@ +import { WiredFurniActionEvent, WiredFurniConditionEvent, WiredFurniTriggerEvent, WiredOpenEvent, WiredRewardResultMessageEvent, WiredSaveSuccessEvent, WiredValidationErrorEvent } from 'nitro-renderer'; +import { FC, useCallback } from 'react'; +import { CreateMessageHook } from '../../hooks/messages'; +import { useWiredContext } from './context/WiredContext'; + +export const WiredMessageHandler: FC<{}> = props => +{ + const { setTrigger = null } = useWiredContext(); + + const onWiredFurniActionEvent = useCallback((event: WiredFurniActionEvent) => + { + const parser = event.getParser(); + + setTrigger(parser.definition); + }, [ setTrigger ]); + + const onWiredFurniConditionEvent = useCallback((event: WiredFurniConditionEvent) => + { + const parser = event.getParser(); + + setTrigger(parser.definition); + }, [ setTrigger ]); + + const onWiredFurniTriggerEvent = useCallback((event: WiredFurniTriggerEvent) => + { + const parser = event.getParser(); + + setTrigger(parser.definition); + }, [ setTrigger ]); + + const onWiredOpenEvent = useCallback((event: WiredOpenEvent) => + { + const parser = event.getParser(); + }, []); + + const onWiredRewardResultMessageEvent = useCallback((event: WiredRewardResultMessageEvent) => + { + const parser = event.getParser(); + }, []); + + const onWiredSaveSuccessEvent = useCallback((event: WiredSaveSuccessEvent) => + { + const parser = event.getParser(); + + setTrigger(null); + }, [ setTrigger ]); + + const onWiredValidationErrorEvent = useCallback((event: WiredValidationErrorEvent) => + { + const parser = event.getParser(); + }, []); + + CreateMessageHook(WiredFurniActionEvent, onWiredFurniActionEvent); + CreateMessageHook(WiredFurniConditionEvent, onWiredFurniConditionEvent); + CreateMessageHook(WiredFurniTriggerEvent, onWiredFurniTriggerEvent); + CreateMessageHook(WiredOpenEvent, onWiredOpenEvent); + CreateMessageHook(WiredRewardResultMessageEvent, onWiredRewardResultMessageEvent); + CreateMessageHook(WiredSaveSuccessEvent, onWiredSaveSuccessEvent); + CreateMessageHook(WiredValidationErrorEvent, onWiredValidationErrorEvent); + + return null; +}; diff --git a/src/views/wired/WiredView.scss b/src/views/wired/WiredView.scss new file mode 100644 index 00000000..ce1bc799 --- /dev/null +++ b/src/views/wired/WiredView.scss @@ -0,0 +1,160 @@ +.nitro-wired { + width: 300px; + padding:7px; + + .icon { + width: 16px; + height: 9px; + background-repeat: no-repeat; + background-position: center; + + &.icon-mv-1 { + background-image: url('../../assets/images/wired/icon_wired_around.png'); + } + &.icon-mv-2 { + background-image: url('../../assets/images/wired/icon_wired_up_down.png'); + } + &.icon-mv-3 { + background-image: url('../../assets/images/wired/icon_wired_left_right.png'); + } + &.icon-ne { + background-image: url('../../assets/images/wired/icon_wired_north_east.png'); + } + &.icon-se { + background-image: url('../../assets/images/wired/icon_wired_south_east.png'); + } + &.icon-sw { + background-image: url('../../assets/images/wired/icon_wired_south_west.png'); + } + &.icon-nw { + background-image: url('../../assets/images/wired/icon_wired_north_west.png'); + } + &.icon-rot-1 { + background-image: url('../../assets/images/wired/icon_wired_rotate_clockwise.png'); + } + &.icon-rot-2 { + background-image: url('../../assets/images/wired/icon_wired_rotate_counter_clockwise.png'); + } + } + + .nitro-wired-header { + color: #000; + margin-bottom:3px; + + .nitro-wired-title, .nitro-wired-close { + border:1px solid rgba($black,.8); + background-image: linear-gradient(45deg, #00d9cb 25%, #00bdb0 25%, #00bdb0 50%, #00d9cb 50%, #00d9cb 75%, #00bdb0 75%, #00bdb0 100%); + background-size: 197.99px 197.99px; + animation: wiredSlider 3s linear infinite; + text-align: center; + box-shadow:inset 0 0 0 2px rgba($white,.6), 0 2px rgba($black,.4); + } + + .nitro-wired-title { + margin-right:3px; + } + + .nitro-wired-close { + min-width: 23px; + } + } + + &.nitro-wired-trigger { + background-color: #3b2516 !important; + border: 1px solid #000 !important; + box-shadow: inset 0px -2px #50321f, + inset 0px -3px #86583b, + inset 0 0 0 1px #86583b, + inset 0 0 0 3px #644029, + inset 0 0 0 4px rgba($black,.4) !important; + + .bg-light,.bg-primary { + background-color: transparent !important; + } + + .bg-dark { + background-color: #000 !important; + } + } + + &.nitro-wired-action { + background-color: #686868 !important; + border: 1px solid #000 !important; + box-shadow: inset 0px -2px #9d9d9d, + inset 0px -3px #c5c5c5, + inset 0 0 0 1px #c5c5c5, + inset 0 0 0 3px #9d9d9d, + inset 0 0 0 4px rgba($black,.4) !important; + + .bg-light,.bg-primary { + background-color: transparent !important; + } + + .bg-dark { + background-color: #000 !important; + } + + &::before, + &::after, + .content-area::before, + .content-area::after { + content: ''; + height: 6px; + width: 6px; + position: absolute; + background-image: url('../../assets/images/wired/card-action-corners.png'); + } + + &::before { + background-position: 0 0; + top: 0; + left: 0; + } + + &::after { + background-position: 6px 0; + top: 0; + right: 0; + } + + .content-area { + &::before { + background-position: 0 6px; + bottom: 0; + left: 0; + } + + &::after { + background-position: 6px 6px; + bottom: 0; + right: 0; + } + } + } + + &.nitro-wired-condition { + background-color: #cfd2dd !important; + border: 1px solid #000 !important; + box-shadow: inset 0 0 0 3px #efefef, inset 4px 4px #abaeb9 !important; + color: #000; + + .bg-light,.bg-primary { + background-color: transparent !important; + } + + .bg-dark { + background-color: #000 !important; + } + } +} + + +@keyframes wiredSlider { + 0% { + background-position: 0 0; + } + + 100% { + background-position: 0 -197.99px; + } +} diff --git a/src/views/wired/WiredView.tsx b/src/views/wired/WiredView.tsx new file mode 100644 index 00000000..e438dd67 --- /dev/null +++ b/src/views/wired/WiredView.tsx @@ -0,0 +1,53 @@ +import { ConditionDefinition, Triggerable, TriggerDefinition, UpdateActionMessageComposer, UpdateConditionMessageComposer, UpdateTriggerMessageComposer, WiredActionDefinition } from 'nitro-renderer'; +import { FC, useCallback, useMemo, useState } from 'react'; +import { GetConnection } from '../../api'; +import { WiredEvent } from '../../events'; +import { useUiEvent } from '../../hooks/events'; +import { GetWiredLayout } from './common/GetWiredLayout'; +import { WiredContextProvider } from './context/WiredContext'; +import { WiredMessageHandler } from './WiredMessageHandler'; +import { WiredFurniSelectorViewProps } from './WiredView.types'; + +export const WiredView: FC = props => +{ + const [ trigger, setTrigger ] = useState(null); + const [ intParams, setIntParams ] = useState(null); + const [ stringParam, setStringParam ] = useState(null); + const [ furniIds, setFurniIds ] = useState([]); + const [ actionDelay, setActionDelay ] = useState(null); + + const wiredLayout = useMemo(() => + { + return GetWiredLayout(trigger); + }, [ trigger ]); + + const onWiredEvent = useCallback((event: WiredEvent) => + { + // check if owner & warn with confirm + + if(trigger instanceof WiredActionDefinition) + { + GetConnection().send(new UpdateActionMessageComposer(trigger.id, intParams, stringParam, furniIds, actionDelay, trigger.stuffTypeSelectionCode)); + } + + else if(trigger instanceof TriggerDefinition) + { + console.log(intParams, stringParam); + GetConnection().send(new UpdateTriggerMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode)); + } + + else if(trigger instanceof ConditionDefinition) + { + GetConnection().send(new UpdateConditionMessageComposer(trigger.id, intParams, stringParam, furniIds, trigger.stuffTypeSelectionCode)); + } + }, [ trigger, intParams, stringParam, furniIds, actionDelay ]); + + useUiEvent(WiredEvent.SAVE_WIRED, onWiredEvent); + + return ( + + + { wiredLayout } + + ); +}; diff --git a/src/views/wired/WiredView.types.ts b/src/views/wired/WiredView.types.ts new file mode 100644 index 00000000..823d8fb3 --- /dev/null +++ b/src/views/wired/WiredView.types.ts @@ -0,0 +1,12 @@ +export class WiredFurniSelectorViewProps +{} + +export class WiredFurniType +{ + public static STUFF_SELECTION_OPTION_NONE: number = 0; + public static STUFF_SELECTION_OPTION_BY_ID: number = 1; + public static STUFF_SELECTION_OPTION_BY_ID_OR_BY_TYPE: number = 2; + public static STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT: number = 3; +} + +export const WIRED_STRING_DELIMETER: string = '\t'; diff --git a/src/views/wired/common/GetWiredActionLayout.tsx b/src/views/wired/common/GetWiredActionLayout.tsx new file mode 100644 index 00000000..fab75242 --- /dev/null +++ b/src/views/wired/common/GetWiredActionLayout.tsx @@ -0,0 +1,85 @@ +import { WiredActionBotChangeFigureView } from '../views/actions/bot-change-figure/WiredActionBotChangeFigureView'; +import { WiredActionBotFollowAvatarView } from '../views/actions/bot-follow-avatar/WiredActionBotFollowAvatarView'; +import { WiredActionBotGiveHandItemView } from '../views/actions/bot-give-hand-item/WiredActionBotGiveHandItemView'; +import { WiredActionBotMoveView } from '../views/actions/bot-move/WiredActionBotMoveView'; +import { WiredActionBotTalkToAvatarView } from '../views/actions/bot-talk-to-avatar/WiredActionBotTalkToAvatarView'; +import { WiredActionBotTalkView } from '../views/actions/bot-talk/WiredActionBotTalkView'; +import { WiredActionBotTeleportView } from '../views/actions/bot-teleport/WiredActionBotTeleportView'; +import { WiredActionCallAnotherStackView } from '../views/actions/call-another-stack/WiredActionCallAnotherStackView'; +import { WiredActionChaseView } from '../views/actions/chase/WiredActionChaseView'; +import { WiredActionChatView } from '../views/actions/chat/WiredActionChatView'; +import { WiredActionFleeView } from '../views/actions/flee/WiredActionFleeView'; +import { WiredActionGiveRewardView } from '../views/actions/give-reward/WiredActionGiveRewardView'; +import { WiredActionGiveScoreToPredefinedTeamView } from '../views/actions/give-score-to-predefined-team/WiredActionGiveScoreToPredefinedTeamView'; +import { WiredActionGiveScoreView } from '../views/actions/give-score/WiredActionGiveScoreView'; +import { WiredActionJoinTeamView } from '../views/actions/join-team/WiredActionJoinTeamView'; +import { WiredActionKickFromRoomView } from '../views/actions/kick-from-room/WiredActionKickFromRoomView'; +import { WiredActionLeaveTeamView } from '../views/actions/leave-team/WiredActionLeaveTeamView'; +import { WiredActionMoveAndRotateFurniView } from '../views/actions/move-and-rotate-furni/WiredActionMoveAndRotateFurniView'; +import { WiredActionMoveFurniToView } from '../views/actions/move-furni-to/WiredActionMoveFurniToView'; +import { WiredActionMoveFurniView } from '../views/actions/move-furni/WiredActionMoveFurniView'; +import { WiredActionMuteUserView } from '../views/actions/mute-user/WiredActionMuteUserView'; +import { WiredActionResetView } from '../views/actions/reset/WiredActionResetView'; +import { WiredActionSetFurniStateToView } from '../views/actions/set-furni-state-to/WiredActionSetFurniStateToView'; +import { WiredActionTeleportView } from '../views/actions/teleport/WiredActionTeleportView'; +import { WiredActionToggleFurniStateView } from '../views/actions/toggle-furni-state/WiredActionToggleFurniStateView'; +import { WiredActionLayout } from './WiredActionLayoutCode'; + +export function GetWiredActionLayout(code: number): JSX.Element +{ + switch(code) + { + case WiredActionLayout.BOT_CHANGE_FIGURE: + return ; + case WiredActionLayout.BOT_FOLLOW_AVATAR: + return ; + case WiredActionLayout.BOT_GIVE_HAND_ITEM: + return ; + case WiredActionLayout.BOT_MOVE: + return ; + case WiredActionLayout.BOT_TALK: + return ; + case WiredActionLayout.BOT_TALK_DIRECT_TO_AVTR: + return ; + case WiredActionLayout.BOT_TELEPORT: + return ; + case WiredActionLayout.CALL_ANOTHER_STACK: + return ; + case WiredActionLayout.CHASE: + return ; + case WiredActionLayout.CHAT: + return ; + case WiredActionLayout.FLEE: + return ; + case WiredActionLayout.GIVE_REWARD: + return ; + case WiredActionLayout.GIVE_SCORE: + return ; + case WiredActionLayout.GIVE_SCORE_TO_PREDEFINED_TEAM: + return ; + case WiredActionLayout.JOIN_TEAM: + return ; + case WiredActionLayout.KICK_FROM_ROOM: + return ; + case WiredActionLayout.LEAVE_TEAM: + return ; + case WiredActionLayout.MOVE_FURNI: + return ; + case WiredActionLayout.MOVE_AND_ROTATE_FURNI: + return ; + case WiredActionLayout.MOVE_FURNI_TO: + return ; + case WiredActionLayout.MUTE_USER: + return ; + case WiredActionLayout.RESET: + return ; + case WiredActionLayout.SET_FURNI_STATE: + return ; + case WiredActionLayout.TELEPORT: + return ; + case WiredActionLayout.TOGGLE_FURNI_STATE: + return ; + } + + return null; +} diff --git a/src/views/wired/common/GetWiredConditionLayout.tsx b/src/views/wired/common/GetWiredConditionLayout.tsx new file mode 100644 index 00000000..e56caebe --- /dev/null +++ b/src/views/wired/common/GetWiredConditionLayout.tsx @@ -0,0 +1,64 @@ +import { WiredConditionActorHasHandItemView } from '../views/conditions/actor-has-hand-item/WiredConditionActorHasHandItem'; +import { WiredConditionActorIsGroupMemberView } from '../views/conditions/actor-is-group-member/WiredConditionActorIsGroupMemberView'; +import { WiredConditionActorIsOnFurniView } from '../views/conditions/actor-is-on-furni/WiredConditionActorIsOnFurniView'; +import { WiredConditionActorIsTeamMemberView } from '../views/conditions/actor-is-team-member/WiredConditionActorIsTeamMemberView'; +import { WiredConditionActorIsWearingBadgeView } from '../views/conditions/actor-is-wearing-badge/WiredConditionActorIsWearingBadgeView'; +import { WiredConditionActorIsWearingEffectView } from '../views/conditions/actor-is-wearing-effect/WiredConditionActorIsWearingEffectView'; +import { WiredConditionDateRangeView } from '../views/conditions/date-range/WiredConditionDateRangeView'; +import { WiredConditionFurniHasAvatarOnView } from '../views/conditions/furni-has-avatar-on/WiredConditionFurniHasAvatarOnView'; +import { WiredConditionFurniHasFurniOnView } from '../views/conditions/furni-has-furni-on/WiredConditionFurniHasFurniOnView'; +import { WiredConditionFurniHasNotFurniOnView } from '../views/conditions/furni-has-not-furni-on/WiredConditionFurniHasNotFurniOnView'; +import { WiredConditionFurniIsOfTypeView } from '../views/conditions/furni-is-of-type/WiredConditionFurniIsOfTypeView'; +import { WiredConditionFurniMatchesSnapshotView } from '../views/conditions/furni-matches-snapshot/WiredConditionFurniMatchesSnapshotView'; +import { WiredConditionTimeElapsedLessView } from '../views/conditions/time-elapsed-less/WiredConditionTimeElapsedLessView'; +import { WiredConditionTimeElapsedMoreView } from '../views/conditions/time-elapsed-more/WiredConditionTimeElapsedMoreView'; +import { WiredConditionUserCountInRoomView } from '../views/conditions/user-count-in-room/WiredConditionUserCountInRoomView'; +import { WiredConditionlayout } from './WiredConditionLayoutCode'; + +export function GetWiredConditionLayout(code: number): JSX.Element +{ + switch(code) + { + case WiredConditionlayout.ACTOR_HAS_HANDITEM: + return ; + case WiredConditionlayout.ACTOR_IS_GROUP_MEMBER: + case WiredConditionlayout.NOT_ACTOR_IN_GROUP: + return ; + case WiredConditionlayout.ACTOR_IS_ON_FURNI: + case WiredConditionlayout.NOT_ACTOR_ON_FURNI: + return ; + case WiredConditionlayout.ACTOR_IS_IN_TEAM: + case WiredConditionlayout.NOT_ACTOR_IN_TEAM: + return ; + case WiredConditionlayout.ACTOR_IS_WEARING_BADGE: + case WiredConditionlayout.NOT_ACTOR_WEARS_BADGE: + return ; + case WiredConditionlayout.ACTOR_IS_WEARING_EFFECT: + case WiredConditionlayout.NOT_ACTOR_WEARING_EFFECT: + return ; + case WiredConditionlayout.DATE_RANGE_ACTIVE: + return ; + case WiredConditionlayout.FURNIS_HAVE_AVATARS: + case WiredConditionlayout.FURNI_NOT_HAVE_HABBO: + return ; + case WiredConditionlayout.HAS_STACKED_FURNIS: + return ; + case WiredConditionlayout.NOT_HAS_STACKED_FURNIS: + return ; + case WiredConditionlayout.STUFF_TYPE_MATCHES: + case WiredConditionlayout.NOT_FURNI_IS_OF_TYPE: + return ; + case WiredConditionlayout.STATES_MATCH: + case WiredConditionlayout.NOT_STATES_MATCH: + return ; + case WiredConditionlayout.TIME_ELAPSED_LESS: + return ; + case WiredConditionlayout.TIME_ELAPSED_MORE: + return ; + case WiredConditionlayout.USER_COUNT_IN: + case WiredConditionlayout.NOT_USER_COUNT_IN: + return ; + } + + return null; +} diff --git a/src/views/wired/common/GetWiredLayout.tsx b/src/views/wired/common/GetWiredLayout.tsx new file mode 100644 index 00000000..25d7fc34 --- /dev/null +++ b/src/views/wired/common/GetWiredLayout.tsx @@ -0,0 +1,15 @@ +import { ConditionDefinition, Triggerable, TriggerDefinition, WiredActionDefinition } from 'nitro-renderer'; +import { GetWiredActionLayout } from './GetWiredActionLayout'; +import { GetWiredConditionLayout } from './GetWiredConditionLayout'; +import { GetWiredTriggerLayout } from './GetWiredTriggerLayout'; + +export function GetWiredLayout(trigger: Triggerable): JSX.Element +{ + if(trigger instanceof WiredActionDefinition) return GetWiredActionLayout(trigger.code); + + if(trigger instanceof TriggerDefinition) return GetWiredTriggerLayout(trigger.code); + + if(trigger instanceof ConditionDefinition) return GetWiredConditionLayout(trigger.code); + + return null; +} diff --git a/src/views/wired/common/GetWiredTimeLocale.ts b/src/views/wired/common/GetWiredTimeLocale.ts new file mode 100644 index 00000000..02aa3b4e --- /dev/null +++ b/src/views/wired/common/GetWiredTimeLocale.ts @@ -0,0 +1,8 @@ +export function GetWiredTimeLocale(value: number): string +{ + const time = Math.floor((value / 2)); + + if(!(value % 2)) return time.toString(); + + return (time + 0.5).toString(); +} diff --git a/src/views/wired/common/GetWiredTriggerLayout.tsx b/src/views/wired/common/GetWiredTriggerLayout.tsx new file mode 100644 index 00000000..41ddd9c7 --- /dev/null +++ b/src/views/wired/common/GetWiredTriggerLayout.tsx @@ -0,0 +1,52 @@ +import { WiredTriggerAvatarEnterRoomView } from '../views/triggers/avatar-enter-room/WiredTriggerAvatarEnterRoomView'; +import { WiredTriggerAvatarSaysSomethingView } from '../views/triggers/avatar-says-something/WiredTriggerAvatarSaysSomethingView'; +import { WiredTriggerAvatarWalksOffFurniView } from '../views/triggers/avatar-walks-off-furni/WiredTriggerAvatarWalksOffFurniView'; +import { WiredTriggerAvatarWalksOnFurniView } from '../views/triggers/avatar-walks-on-furni/WiredTriggerAvatarWalksOnFurni'; +import { WiredTriggerBotReachedAvatarView } from '../views/triggers/bot-reached-avatar/WiredTriggerBotReachedAvatarView'; +import { WiredTriggerBotReachedStuffView } from '../views/triggers/bot-reached-stuff/WiredTriggerBotReachedStuffView'; +import { WiredTriggerCollisionView } from '../views/triggers/collision/WiredTriggerCollisionView'; +import { WiredTriggeExecuteOnceView } from '../views/triggers/execute-once/WiredTriggerExecuteOnceView'; +import { WiredTriggeExecutePeriodicallyLongView } from '../views/triggers/execute-periodically-long/WiredTriggerExecutePeriodicallyLongView'; +import { WiredTriggeExecutePeriodicallyView } from '../views/triggers/execute-periodically/WiredTriggerExecutePeriodicallyView'; +import { WiredTriggerGameEndsView } from '../views/triggers/game-ends/WiredTriggerGameEndsView'; +import { WiredTriggerGameStartsView } from '../views/triggers/game-starts/WiredTriggerGameStartsView'; +import { WiredTriggeScoreAchievedView } from '../views/triggers/score-achieved/WiredTriggerScoreAchievedView'; +import { WiredTriggerToggleFurniView } from '../views/triggers/toggle-furni/WiredTriggerToggleFurniView'; +import { WiredTriggerLayout } from './WiredTriggerLayoutCode'; + +export function GetWiredTriggerLayout(code: number): JSX.Element +{ + switch(code) + { + case WiredTriggerLayout.AVATAR_ENTERS_ROOM: + return ; + case WiredTriggerLayout.AVATAR_SAYS_SOMETHING: + return ; + case WiredTriggerLayout.AVATAR_WALKS_OFF_FURNI: + return ; + case WiredTriggerLayout.AVATAR_WALKS_ON_FURNI: + return ; + case WiredTriggerLayout.BOT_REACHED_AVATAR: + return ; + case WiredTriggerLayout.BOT_REACHED_STUFF: + return ; + case WiredTriggerLayout.COLLISION: + return ; + case WiredTriggerLayout.EXECUTE_ONCE: + return ; + case WiredTriggerLayout.EXECUTE_PERIODICALLY: + return ; + case WiredTriggerLayout.EXECUTE_PERIODICALLY_LONG: + return ; + case WiredTriggerLayout.GAME_ENDS: + return ; + case WiredTriggerLayout.GAME_STARTS: + return ; + case WiredTriggerLayout.SCORE_ACHIEVED: + return ; + case WiredTriggerLayout.TOGGLE_FURNI: + return ; + } + + return null; +} diff --git a/src/views/wired/common/WiredActionLayoutCode.ts b/src/views/wired/common/WiredActionLayoutCode.ts new file mode 100644 index 00000000..f15a527f --- /dev/null +++ b/src/views/wired/common/WiredActionLayoutCode.ts @@ -0,0 +1,29 @@ +export class WiredActionLayout +{ + public static TOGGLE_FURNI_STATE: number = 0; + public static RESET: number = 1; + public static SET_FURNI_STATE: number = 3; + public static MOVE_FURNI: number = 4; + public static GIVE_SCORE: number = 6; + public static CHAT: number = 7; + public static TELEPORT: number = 8; + public static JOIN_TEAM: number = 9; + public static LEAVE_TEAM: number = 10; + public static CHASE: number = 11; + public static FLEE: number = 12; + public static MOVE_AND_ROTATE_FURNI: number = 13; + public static GIVE_SCORE_TO_PREDEFINED_TEAM: number = 14; + public static TOGGLE_TO_RANDOM_STATE: number = 15; + public static MOVE_FURNI_TO: number = 16; + public static GIVE_REWARD: number = 17; + public static CALL_ANOTHER_STACK: number = 18; + public static KICK_FROM_ROOM: number = 19; + public static MUTE_USER: number = 20; + public static BOT_TELEPORT: number = 21; + public static BOT_MOVE: number = 22; + public static BOT_TALK: number = 23; + public static BOT_GIVE_HAND_ITEM: number = 24; + public static BOT_FOLLOW_AVATAR: number = 25; + public static BOT_CHANGE_FIGURE: number = 26; + public static BOT_TALK_DIRECT_TO_AVTR: number = 27; +} diff --git a/src/views/wired/common/WiredConditionLayoutCode.ts b/src/views/wired/common/WiredConditionLayoutCode.ts new file mode 100644 index 00000000..58cae5db --- /dev/null +++ b/src/views/wired/common/WiredConditionLayoutCode.ts @@ -0,0 +1,29 @@ +export class WiredConditionlayout +{ + public static STATES_MATCH: number = 0; + public static FURNIS_HAVE_AVATARS: number = 1; + public static ACTOR_IS_ON_FURNI: number = 2; + public static TIME_ELAPSED_MORE: number = 3; + public static TIME_ELAPSED_LESS: number = 4; + public static USER_COUNT_IN: number = 5; + public static ACTOR_IS_IN_TEAM: number = 6; + public static HAS_STACKED_FURNIS: number = 7; + public static STUFF_TYPE_MATCHES: number = 8; + public static STUFFS_IN_FORMATION: number = 9; + public static ACTOR_IS_GROUP_MEMBER: number = 10; + public static ACTOR_IS_WEARING_BADGE: number = 11; + public static ACTOR_IS_WEARING_EFFECT: number = 12; + public static NOT_STATES_MATCH: number = 13; + public static FURNI_NOT_HAVE_HABBO: number = 14; + public static NOT_ACTOR_ON_FURNI: number = 15; + public static NOT_USER_COUNT_IN: number = 16; + public static NOT_ACTOR_IN_TEAM: number = 17; + public static NOT_HAS_STACKED_FURNIS: number = 18; + public static NOT_FURNI_IS_OF_TYPE: number = 19; + public static NOT_STUFFS_IN_FORMATION: number = 20; + public static NOT_ACTOR_IN_GROUP: number = 21; + public static NOT_ACTOR_WEARS_BADGE: number = 22; + public static NOT_ACTOR_WEARING_EFFECT: number = 23; + public static DATE_RANGE_ACTIVE: number = 24; + public static ACTOR_HAS_HANDITEM: number = 25; +} diff --git a/src/views/wired/common/WiredSelectionFilter.ts b/src/views/wired/common/WiredSelectionFilter.ts new file mode 100644 index 00000000..0ae889df --- /dev/null +++ b/src/views/wired/common/WiredSelectionFilter.ts @@ -0,0 +1,95 @@ +import { ColorConverter, NitroFilter } from 'nitro-renderer'; + +const vertex = ` +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +uniform mat3 projectionMatrix; +varying vec2 vTextureCoord; +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; +}`; + +const fragment = ` +varying vec2 vTextureCoord; +uniform sampler2D uSampler; +uniform vec3 lineColor; +uniform vec3 color; +void main(void) { + vec4 currentColor = texture2D(uSampler, vTextureCoord); + vec3 colorLine = lineColor * currentColor.a; + vec3 colorOverlay = color * currentColor.a; + + if(currentColor.r == 0.0 && currentColor.g == 0.0 && currentColor.b == 0.0 && currentColor.a > 0.0) { + gl_FragColor = vec4(colorLine.r, colorLine.g, colorLine.b, currentColor.a); + } else if(currentColor.a > 0.0) { + gl_FragColor = vec4(colorOverlay.r, colorOverlay.g, colorOverlay.b, currentColor.a); + } +}`; + +export class WiredSelectionFilter extends NitroFilter +{ + private _lineColor: number; + private _color: number; + + constructor(lineColor: number | number[], color: number | number[]) + { + super(vertex, fragment); + + this.uniforms.lineColor = new Float32Array(3); + this.uniforms.color = new Float32Array(3); + this.lineColor = lineColor; + this.color = color; + } + + public get lineColor(): number | number[] + { + return this._lineColor; + } + + public set lineColor(value: number | number[]) + { + const arr = this.uniforms.lineColor; + + if(typeof value === 'number') + { + ColorConverter.hex2rgb(value, arr); + + this._lineColor = value; + } + else + { + arr[0] = value[0]; + arr[1] = value[1]; + arr[2] = value[2]; + + this._lineColor = ColorConverter.rgb2hex(arr); + } + } + + public get color(): number | number[] + { + return this._color; + } + + public set color(value: number | number[]) + { + const arr = this.uniforms.color; + + if(typeof value === 'number') + { + ColorConverter.hex2rgb(value, arr); + + this._color = value; + } + else + { + arr[0] = value[0]; + arr[1] = value[1]; + arr[2] = value[2]; + + this._color = ColorConverter.rgb2hex(arr); + } + } +} diff --git a/src/views/wired/common/WiredSelectionVisualizer.ts b/src/views/wired/common/WiredSelectionVisualizer.ts new file mode 100644 index 00000000..283c089a --- /dev/null +++ b/src/views/wired/common/WiredSelectionVisualizer.ts @@ -0,0 +1,68 @@ +import { IRoomObject, IRoomObjectSpriteVisualization, NitroFilter, RoomObjectCategory } from 'nitro-renderer'; +import { GetRoomEngine } from '../../../api'; +import { WiredSelectionFilter } from './WiredSelectionFilter'; + +export class WiredSelectionVisualizer +{ + private static _selectionShader: NitroFilter = new WiredSelectionFilter([ 1, 1, 1 ], [ 0.6, 0.6, 0.6 ]); + + public static show(furniId: number): void + { + WiredSelectionVisualizer.applySelectionShader(WiredSelectionVisualizer.getRoomObject(furniId)); + } + + public static hide(furniId: number): void + { + WiredSelectionVisualizer.clearSelectionShader(WiredSelectionVisualizer.getRoomObject(furniId)); + } + + public static clearSelectionShaderFromFurni(furniIds: number[]): void + { + for(const furniId of furniIds) + { + WiredSelectionVisualizer.clearSelectionShader(WiredSelectionVisualizer.getRoomObject(furniId)); + } + } + + public static applySelectionShaderToFurni(furniIds: number[]): void + { + for(const furniId of furniIds) + { + WiredSelectionVisualizer.applySelectionShader(WiredSelectionVisualizer.getRoomObject(furniId)); + } + } + + private static getRoomObject(objectId: number): IRoomObject + { + const roomEngine = GetRoomEngine(); + + return roomEngine.getRoomObject(roomEngine.activeRoomId, objectId, RoomObjectCategory.FLOOR); + } + + private static applySelectionShader(roomObject: IRoomObject): void + { + if(!roomObject) return; + + const visualization = (roomObject.visualization as IRoomObjectSpriteVisualization); + + if(!visualization) return; + + for(const sprite of visualization.sprites) + { + if(sprite.blendMode === 1) continue; // BLEND_MODE: ADD + + sprite.filters = [ WiredSelectionVisualizer._selectionShader ]; + } + } + + private static clearSelectionShader(roomObject: IRoomObject): void + { + if(!roomObject) return; + + const visualization = (roomObject.visualization as IRoomObjectSpriteVisualization); + + if(!visualization) return; + + for(const sprite of visualization.sprites) sprite.filters = []; + } +} diff --git a/src/views/wired/common/WiredTriggerLayoutCode.ts b/src/views/wired/common/WiredTriggerLayoutCode.ts new file mode 100644 index 00000000..fd758dff --- /dev/null +++ b/src/views/wired/common/WiredTriggerLayoutCode.ts @@ -0,0 +1,17 @@ +export class WiredTriggerLayout +{ + public static AVATAR_SAYS_SOMETHING: number = 0; + public static AVATAR_WALKS_ON_FURNI: number = 1; + public static AVATAR_WALKS_OFF_FURNI: number = 2; + public static EXECUTE_ONCE: number = 3; + public static TOGGLE_FURNI: number = 4; + public static EXECUTE_PERIODICALLY: number = 6; + public static AVATAR_ENTERS_ROOM: number = 7; + public static GAME_STARTS: number = 8; + public static GAME_ENDS: number = 9; + public static SCORE_ACHIEVED: number = 10; + public static COLLISION: number = 11; + public static EXECUTE_PERIODICALLY_LONG: number = 12; + public static BOT_REACHED_STUFF: number = 13; + public static BOT_REACHED_AVATAR: number = 14; +} diff --git a/src/views/wired/context/WiredContext.tsx b/src/views/wired/context/WiredContext.tsx new file mode 100644 index 00000000..26c42a7a --- /dev/null +++ b/src/views/wired/context/WiredContext.tsx @@ -0,0 +1,22 @@ +import { createContext, FC, useContext } from 'react'; +import { IWiredContext, WiredContextProps } from './WiredContext.types'; + +const WiredContext = createContext({ + trigger: null, + setTrigger: null, + intParams: null, + setIntParams: null, + stringParam: null, + setStringParam: null, + furniIds: null, + setFurniIds: null, + actionDelay: null, + setActionDelay: null +}); + +export const WiredContextProvider: FC = props => +{ + return { props.children } +} + +export const useWiredContext = () => useContext(WiredContext); diff --git a/src/views/wired/context/WiredContext.types.ts b/src/views/wired/context/WiredContext.types.ts new file mode 100644 index 00000000..18e9c5ae --- /dev/null +++ b/src/views/wired/context/WiredContext.types.ts @@ -0,0 +1,21 @@ +import { Triggerable } from 'nitro-renderer'; +import { Dispatch, ProviderProps, SetStateAction } from 'react'; + +export interface IWiredContext +{ + trigger: Triggerable; + setTrigger: Dispatch>; + intParams: number[], + setIntParams: Dispatch>; + stringParam: string; + setStringParam: Dispatch>; + furniIds: number[]; + setFurniIds: Dispatch>; + actionDelay: number; + setActionDelay: Dispatch>; +} + +export interface WiredContextProps extends ProviderProps +{ + +} diff --git a/src/views/wired/views/actions/base/WiredActionBaseView.tsx b/src/views/wired/views/actions/base/WiredActionBaseView.tsx new file mode 100644 index 00000000..c88c3b00 --- /dev/null +++ b/src/views/wired/views/actions/base/WiredActionBaseView.tsx @@ -0,0 +1,45 @@ +import { WiredActionDefinition } from 'nitro-renderer'; +import Slider from 'rc-slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { GetWiredTimeLocale } from '../../../common/GetWiredTimeLocale'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredBaseView } from '../../base/WiredBaseView'; +import { WiredActionBaseViewProps } from './WiredActionBaseView.types'; + +export const WiredActionBaseView: FC = props => +{ + const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, children = null } = props; + const [ delay, setDelay ] = useState(-1); + const { trigger = null, setActionDelay = null } = useWiredContext(); + + useEffect(() => + { + setDelay((trigger as WiredActionDefinition).delayInPulses); + }, [ trigger ]); + + const onSave = useCallback(() => + { + if(save) save(); + + setActionDelay(delay); + }, [ delay, save, setActionDelay ]); + + return ( + + { !children ? null : <> + { children } +
+ } +
+ + setDelay(event) } /> +
+
+ ); +} diff --git a/src/views/wired/views/actions/base/WiredActionBaseView.types.ts b/src/views/wired/views/actions/base/WiredActionBaseView.types.ts new file mode 100644 index 00000000..ef514b76 --- /dev/null +++ b/src/views/wired/views/actions/base/WiredActionBaseView.types.ts @@ -0,0 +1,5 @@ +export interface WiredActionBaseViewProps +{ + requiresFurni: number; + save: () => void; +} diff --git a/src/views/wired/views/actions/bot-change-figure/WiredActionBotChangeFigureView.tsx b/src/views/wired/views/actions/bot-change-figure/WiredActionBotChangeFigureView.tsx new file mode 100644 index 00000000..8515d532 --- /dev/null +++ b/src/views/wired/views/actions/bot-change-figure/WiredActionBotChangeFigureView.tsx @@ -0,0 +1,47 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { GetSessionDataManager } from '../../../../../api'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { AvatarImageView } from '../../../../shared/avatar-image/AvatarImageView'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType, WIRED_STRING_DELIMETER } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/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 } = useWiredContext(); + + 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 ]); + + const copyLooks = useCallback(() => + { + setFigure(GetSessionDataManager().figure); + }, []); + + const save = useCallback(() => + { + setStringParam((botName + WIRED_STRING_DELIMETER + figure)); + }, [ botName, figure, setStringParam ]); + + return ( + +
+ + setBotName(event.target.value) } /> +
+
+ + +
+
+ ); +} diff --git a/src/views/wired/views/actions/bot-follow-avatar/WiredActionBotFollowAvatarView.tsx b/src/views/wired/views/actions/bot-follow-avatar/WiredActionBotFollowAvatarView.tsx new file mode 100644 index 00000000..ae38d8a6 --- /dev/null +++ b/src/views/wired/views/actions/bot-follow-avatar/WiredActionBotFollowAvatarView.tsx @@ -0,0 +1,47 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionBotFollowAvatarView: FC<{}> = props => +{ + const [ botName, setBotName ] = useState(''); + const [ followMode, setFollowMode ] = useState(-1); + const { trigger = null, setStringParam = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setBotName(trigger.stringData); + setFollowMode((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(botName); + setIntParams([followMode]); + }, [ followMode, botName, setStringParam, setIntParams ]); + + return ( + +
+ + setBotName(event.target.value) } /> +
+
+
+ setFollowMode(1) } /> + +
+
+ setFollowMode(0) } /> + +
+
+
+ ); +} diff --git a/src/views/wired/views/actions/bot-give-hand-item/WiredActionBotGiveHandItemView.tsx b/src/views/wired/views/actions/bot-give-hand-item/WiredActionBotGiveHandItemView.tsx new file mode 100644 index 00000000..bb787036 --- /dev/null +++ b/src/views/wired/views/actions/bot-give-hand-item/WiredActionBotGiveHandItemView.tsx @@ -0,0 +1,45 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +const allowedHanditemIds: 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 } = useWiredContext(); + + useEffect(() => + { + setBotName(trigger.stringData); + setHandItemId((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(botName); + setIntParams([ handItemId ]); + }, [ handItemId, botName, setStringParam, setIntParams ]); + + return ( + +
+ + setBotName(event.target.value) } /> +
+
+ + +
+
+ ); +} diff --git a/src/views/wired/views/actions/bot-move/WiredActionBotMoveView.tsx b/src/views/wired/views/actions/bot-move/WiredActionBotMoveView.tsx new file mode 100644 index 00000000..45dd3ba9 --- /dev/null +++ b/src/views/wired/views/actions/bot-move/WiredActionBotMoveView.tsx @@ -0,0 +1,30 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionBotMoveView: FC<{}> = props => +{ + const [ botName, setBotName ] = useState(''); + const { trigger = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setBotName(trigger.stringData); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(botName); + }, [ botName, setStringParam ]); + + return ( + +
+ + setBotName(event.target.value) } /> +
+
+ ); +} diff --git a/src/views/wired/views/actions/bot-talk-to-avatar/WiredActionBotTalkToAvatarView.tsx b/src/views/wired/views/actions/bot-talk-to-avatar/WiredActionBotTalkToAvatarView.tsx new file mode 100644 index 00000000..bbe30016 --- /dev/null +++ b/src/views/wired/views/actions/bot-talk-to-avatar/WiredActionBotTalkToAvatarView.tsx @@ -0,0 +1,52 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType, WIRED_STRING_DELIMETER } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/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 } = useWiredContext(); + + 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 ]); + + const save = useCallback(() => + { + setStringParam(botName + WIRED_STRING_DELIMETER + message); + setIntParams([ talkMode ]); + }, [ botName, message, talkMode, setStringParam, setIntParams ]); + + return ( + +
+ + setBotName(event.target.value) } /> +
+
+ + setMessage(event.target.value) } /> +
+
+
+ setTalkMode(0) } /> + +
+
+ setTalkMode(1) } /> + +
+
+
+ ); +} diff --git a/src/views/wired/views/actions/bot-talk/WiredActionBotTalkView.tsx b/src/views/wired/views/actions/bot-talk/WiredActionBotTalkView.tsx new file mode 100644 index 00000000..a8b848b4 --- /dev/null +++ b/src/views/wired/views/actions/bot-talk/WiredActionBotTalkView.tsx @@ -0,0 +1,52 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType, WIRED_STRING_DELIMETER } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/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 } = useWiredContext(); + + 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 ]); + + const save = useCallback(() => + { + setStringParam(botName + WIRED_STRING_DELIMETER + message); + setIntParams([ talkMode ]); + }, [ botName, message, talkMode, setStringParam, setIntParams ]); + + return ( + +
+ + setBotName(event.target.value) } /> +
+
+ + setMessage(event.target.value) } /> +
+
+
+ setTalkMode(0) } /> + +
+
+ setTalkMode(1) } /> + +
+
+
+ ); +} diff --git a/src/views/wired/views/actions/bot-teleport/WiredActionBotTeleportView.tsx b/src/views/wired/views/actions/bot-teleport/WiredActionBotTeleportView.tsx new file mode 100644 index 00000000..ad6aa17d --- /dev/null +++ b/src/views/wired/views/actions/bot-teleport/WiredActionBotTeleportView.tsx @@ -0,0 +1,30 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionBotTeleportView: FC<{}> = props => +{ + const [ botName, setBotName ] = useState(''); + const { trigger = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setBotName(trigger.stringData); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(botName); + }, [ botName, setStringParam ]); + + return ( + +
+ + setBotName(event.target.value) } /> +
+
+ ); +} diff --git a/src/views/wired/views/actions/call-another-stack/WiredActionCallAnotherStackView.tsx b/src/views/wired/views/actions/call-another-stack/WiredActionCallAnotherStackView.tsx new file mode 100644 index 00000000..62342124 --- /dev/null +++ b/src/views/wired/views/actions/call-another-stack/WiredActionCallAnotherStackView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionCallAnotherStackView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/actions/chase/WiredActionChaseView.tsx b/src/views/wired/views/actions/chase/WiredActionChaseView.tsx new file mode 100644 index 00000000..76bcfae0 --- /dev/null +++ b/src/views/wired/views/actions/chase/WiredActionChaseView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionChaseView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/actions/chat/WiredActionChatView.tsx b/src/views/wired/views/actions/chat/WiredActionChatView.tsx new file mode 100644 index 00000000..39635d26 --- /dev/null +++ b/src/views/wired/views/actions/chat/WiredActionChatView.tsx @@ -0,0 +1,30 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionChatView: FC<{}> = props => +{ + const [ message, setMessage ] = useState(''); + const { trigger = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setMessage(trigger.stringData); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(message); + }, [ message, setStringParam ]); + + return ( + +
+ + setMessage(event.target.value) } /> +
+
+ ); +} diff --git a/src/views/wired/views/actions/flee/WiredActionFleeView.tsx b/src/views/wired/views/actions/flee/WiredActionFleeView.tsx new file mode 100644 index 00000000..d8e37d0b --- /dev/null +++ b/src/views/wired/views/actions/flee/WiredActionFleeView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionFleeView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/actions/give-reward/WiredActionGiveRewardView.tsx b/src/views/wired/views/actions/give-reward/WiredActionGiveRewardView.tsx new file mode 100644 index 00000000..0d857a67 --- /dev/null +++ b/src/views/wired/views/actions/give-reward/WiredActionGiveRewardView.tsx @@ -0,0 +1,173 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/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 } = useWiredContext(); + + useEffect(() => + { + 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); + + 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 }); + } + + setRewards(readRewards); + }, [ trigger ]); + + const addReward = useCallback(() => + { + setRewards(rewards => [...rewards, { isBadge: false, itemCode: '', probability: null }]); + }, [ setRewards ]); + + const removeReward = useCallback((index: number) => + { + const rewardsClone = Array.from(rewards); + rewardsClone.splice(index, 1); + + setRewards(rewardsClone); + }, [ rewards, setRewards ]); + + const updateReward = useCallback((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); + }, [ rewards, setRewards ]); + + const save = useCallback(() => + { + 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]); + } + }, [ rewardTime, uniqueRewards, rewardsLimit, limitationInterval, rewards, setIntParams, setStringParam ]); + + return ( + +
+ setLimitEnabled(e.target.checked)} /> + +
+ { !limitEnabled &&
+ Reward limit not set. Make sure rewards are badges or non-tradeable items. +
} + { limitEnabled && setRewardsLimit(event) } + /> } +
+
How ofter can a user be rewarded?
+
+ + { rewardTime > 0 && setLimitationInterval(Number(event.target.value)) } /> } +
+
+
+ setUniqueRewards(e.target.checked)} /> + +
+
If checked each reward will be given once to each user. This will disable the probabilities option.
+
+
+
Rewards
+
+
+ + + + + + + + + + + { rewards && rewards.map((reward, index) => + { + return ( + + + + + + + ) + }) } + +
Badge?Item CodeProbability
+ updateReward(index, e.target.checked, reward.itemCode, reward.probability)} /> + + updateReward(index, reward.isBadge, e.target.value, reward.probability) } /> + + updateReward(index, reward.isBadge, reward.itemCode, Number(e.target.value)) } /> + + { index > 0 && } +
+
+ ); +} diff --git a/src/views/wired/views/actions/give-score-to-predefined-team/WiredActionGiveScoreToPredefinedTeamView.tsx b/src/views/wired/views/actions/give-score-to-predefined-team/WiredActionGiveScoreToPredefinedTeamView.tsx new file mode 100644 index 00000000..3c5d444a --- /dev/null +++ b/src/views/wired/views/actions/give-score-to-predefined-team/WiredActionGiveScoreToPredefinedTeamView.tsx @@ -0,0 +1,70 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/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 } = useWiredContext(); + + 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 ]); + + const save = useCallback(() => + { + setIntParams([ points, time, selectedTeam ]); + }, [ points, time, selectedTeam, setIntParams ]); + + return ( + +
+ + setPoints(event) } /> +
+
+ + setTime(event) } /> +
+
+ + { [1, 2, 3, 4].map(value => + { + return ( +
+ setSelectedTeam(value) } /> + +
+ ); + }) } +
+
+ ); +} diff --git a/src/views/wired/views/actions/give-score/WiredActionGiveScoreView.tsx b/src/views/wired/views/actions/give-score/WiredActionGiveScoreView.tsx new file mode 100644 index 00000000..1360e889 --- /dev/null +++ b/src/views/wired/views/actions/give-score/WiredActionGiveScoreView.tsx @@ -0,0 +1,53 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionGiveScoreView: FC<{}> = props => +{ + const [ points, setPoints ] = useState(1); + const [ time, setTime ] = useState(1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + if(trigger.intData.length >= 2) + { + setPoints(trigger.intData[0]); + setTime(trigger.intData[1]); + } + else + { + setPoints(1); + setTime(1); + } + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ points, time ]); + }, [ points, time, setIntParams ]); + + return ( + +
+ + setPoints(event) } /> +
+
+ + setTime(event) } /> +
+
+ ); +} diff --git a/src/views/wired/views/actions/join-team/WiredActionJoinTeamView.tsx b/src/views/wired/views/actions/join-team/WiredActionJoinTeamView.tsx new file mode 100644 index 00000000..cf3fb1cb --- /dev/null +++ b/src/views/wired/views/actions/join-team/WiredActionJoinTeamView.tsx @@ -0,0 +1,40 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionJoinTeamView: FC<{}> = props => +{ + const [ selectedTeam, setSelectedTeam ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setSelectedTeam((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ selectedTeam ]); + }, [ selectedTeam, setIntParams ]); + + return ( + +
+ + { [1, 2, 3, 4].map(team => + { + return ( +
+ setSelectedTeam(team) } /> + +
+ ) + }) } +
+
+ ); +} diff --git a/src/views/wired/views/actions/kick-from-room/WiredActionKickFromRoomView.tsx b/src/views/wired/views/actions/kick-from-room/WiredActionKickFromRoomView.tsx new file mode 100644 index 00000000..5d28ff52 --- /dev/null +++ b/src/views/wired/views/actions/kick-from-room/WiredActionKickFromRoomView.tsx @@ -0,0 +1,30 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionKickFromRoomView: FC<{}> = props => +{ + const [ message, setMessage ] = useState(''); + const { trigger = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setMessage(trigger.stringData); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(message); + }, [ message, setStringParam ]); + + return ( + +
+ + setMessage(event.target.value) } /> +
+
+ ); +} diff --git a/src/views/wired/views/actions/leave-team/WiredActionLeaveTeamView.tsx b/src/views/wired/views/actions/leave-team/WiredActionLeaveTeamView.tsx new file mode 100644 index 00000000..67d13522 --- /dev/null +++ b/src/views/wired/views/actions/leave-team/WiredActionLeaveTeamView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionLeaveTeamView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/actions/move-and-rotate-furni/WiredActionMoveAndRotateFurniView.tsx b/src/views/wired/views/actions/move-and-rotate-furni/WiredActionMoveAndRotateFurniView.tsx new file mode 100644 index 00000000..5995dd4d --- /dev/null +++ b/src/views/wired/views/actions/move-and-rotate-furni/WiredActionMoveAndRotateFurniView.tsx @@ -0,0 +1,89 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/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 } = useWiredContext(); + + useEffect(() => + { + if(trigger.intData.length >= 2) + { + setMovement(trigger.intData[0]); + setRotation(trigger.intData[1]); + } + else + { + setMovement(-1); + setRotation(-1); + } + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ movement, rotation ]); + }, [ movement, rotation, setIntParams ]); + + return ( + +
+ +
+ { directionOptions.map(option => + { + return ( +
+
+ setMovement(option.value) } /> + +
+
+ ) + }) } +
+
+
+ + { rotationOptions.map(option => + { + return ( +
+ setRotation(option) } /> + +
+ ) + }) } +
+
+ ); +} diff --git a/src/views/wired/views/actions/move-furni-to/WiredActionMoveFurniToView.tsx b/src/views/wired/views/actions/move-furni-to/WiredActionMoveFurniToView.tsx new file mode 100644 index 00000000..96bf209a --- /dev/null +++ b/src/views/wired/views/actions/move-furni-to/WiredActionMoveFurniToView.tsx @@ -0,0 +1,82 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/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 } = useWiredContext(); + + useEffect(() => + { + if(trigger.intData.length >= 2) + { + setSpacing(trigger.intData[1]); + setMovement(trigger.intData[0]); + } + else + { + setSpacing(-1); + setMovement(-1); + } + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ movement, spacing ]); + }, [ movement, spacing, setIntParams ]); + + return ( + +
+ + setSpacing(event) } /> +
+
+ +
+ { directionOptions.map(value => + { + return ( +
+
+ setMovement(value.value) } /> + +
+
+ ) + }) } +
+
+
+ ); +} diff --git a/src/views/wired/views/actions/move-furni/WiredActionMoveFurniView.tsx b/src/views/wired/views/actions/move-furni/WiredActionMoveFurniView.tsx new file mode 100644 index 00000000..f9107c42 --- /dev/null +++ b/src/views/wired/views/actions/move-furni/WiredActionMoveFurniView.tsx @@ -0,0 +1,109 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/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 } = useWiredContext(); + + useEffect(() => + { + if(trigger.intData.length >= 2) + { + setMovement(trigger.intData[0]); + setRotation(trigger.intData[1]); + } + else + { + setMovement(-1); + setRotation(-1); + } + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ movement, rotation ]); + }, [ movement, rotation, setIntParams ]); + + return ( + +
+ +
+ setMovement(0) } /> + +
+
+ { directionOptions.map(option => + { + return ( +
+
+ setMovement(option.value) } /> + +
+
+ ) + }) } +
+
+
+
+ + { rotationOptions.map(option => + { + return ( +
+ setRotation(option) } /> + +
+ ) + }) } +
+ + ); +} diff --git a/src/views/wired/views/actions/mute-user/WiredActionMuteUserView.tsx b/src/views/wired/views/actions/mute-user/WiredActionMuteUserView.tsx new file mode 100644 index 00000000..1c6f912f --- /dev/null +++ b/src/views/wired/views/actions/mute-user/WiredActionMuteUserView.tsx @@ -0,0 +1,42 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionMuteUserView: FC<{}> = props => +{ + const [ time, setTime ] = useState(-1); + const [ message, setMessage ] = useState(''); + const { trigger = null, setIntParams = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); + setMessage(trigger.stringData); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ time ]); + setStringParam(message); + }, [ time, message, setIntParams, setStringParam ]); + + return ( + +
+ + setTime(event) } /> +
+
+ + setMessage(event.target.value) } /> +
+
+ ); +} diff --git a/src/views/wired/views/actions/reset/WiredActionResetView.tsx b/src/views/wired/views/actions/reset/WiredActionResetView.tsx new file mode 100644 index 00000000..23d4cbf5 --- /dev/null +++ b/src/views/wired/views/actions/reset/WiredActionResetView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionResetView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/actions/set-furni-state-to/WiredActionSetFurniStateToView.tsx b/src/views/wired/views/actions/set-furni-state-to/WiredActionSetFurniStateToView.tsx new file mode 100644 index 00000000..d3d5d82e --- /dev/null +++ b/src/views/wired/views/actions/set-furni-state-to/WiredActionSetFurniStateToView.tsx @@ -0,0 +1,51 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionSetFurniStateToView: FC<{}> = props => +{ + const [ stateFlag, setStateFlag ] = useState(-1); + const [ directionFlag, setDirectionFlag ] = useState(-1); + const [ positionFlag, setPositionFlag ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setStateFlag(trigger.getBoolean(0) ? 1 : 0); + setDirectionFlag(trigger.getBoolean(1) ? 1 : 0); + setPositionFlag(trigger.getBoolean(2) ? 1 : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ stateFlag, directionFlag, positionFlag ]); + }, [ directionFlag, positionFlag, stateFlag, setIntParams ]); + + return ( + +
+ +
+ setStateFlag(event.target.checked ? 1 : 0) } /> + +
+
+ setDirectionFlag(event.target.checked ? 1 : 0) } /> + +
+
+ setPositionFlag(event.target.checked ? 1 : 0) } /> + +
+
+
+ ); +} diff --git a/src/views/wired/views/actions/teleport/WiredActionTeleportView.tsx b/src/views/wired/views/actions/teleport/WiredActionTeleportView.tsx new file mode 100644 index 00000000..f4390f4e --- /dev/null +++ b/src/views/wired/views/actions/teleport/WiredActionTeleportView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionTeleportView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/actions/toggle-furni-state/WiredActionToggleFurniStateView.tsx b/src/views/wired/views/actions/toggle-furni-state/WiredActionToggleFurniStateView.tsx new file mode 100644 index 00000000..fc7aed91 --- /dev/null +++ b/src/views/wired/views/actions/toggle-furni-state/WiredActionToggleFurniStateView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredActionBaseView } from '../base/WiredActionBaseView'; + +export const WiredActionToggleFurniStateView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/base/WiredBaseView.tsx b/src/views/wired/views/base/WiredBaseView.tsx new file mode 100644 index 00000000..679eb070 --- /dev/null +++ b/src/views/wired/views/base/WiredBaseView.tsx @@ -0,0 +1,100 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { GetSessionDataManager } from '../../../../api'; +import { WiredEvent } from '../../../../events'; +import { dispatchUiEvent } from '../../../../hooks/events'; +import { NitroCardContentView, NitroCardView } from '../../../../layout'; +import { LocalizeText } from '../../../../utils/LocalizeText'; +import { WiredSelectionVisualizer } from '../../common/WiredSelectionVisualizer'; +import { useWiredContext } from '../../context/WiredContext'; +import { WiredFurniType } from '../../WiredView.types'; +import { WiredFurniSelectorView } from '../furni-selector/WiredFurniSelectorView'; +import { WiredBaseViewProps } from './WiredBaseView.types'; + +export const WiredBaseView: FC = props => +{ + const { wiredType = '', requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, children = null } = props; + const [ wiredName, setWiredName ] = useState(null); + const [ wiredDescription, setWiredDescription ] = useState(null); + const { trigger = null, setTrigger = null, setIntParams = null, setStringParam = null, setFurniIds = null } = useWiredContext(); + + 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); + } + + setIntParams(trigger.intData); + setStringParam(trigger.stringData); + setFurniIds(prevValue => + { + if(prevValue && prevValue.length) WiredSelectionVisualizer.clearSelectionShaderFromFurni(prevValue); + + if(trigger.selectedItems && trigger.selectedItems.length) + { + WiredSelectionVisualizer.applySelectionShaderToFurni(trigger.selectedItems); + + return trigger.selectedItems; + } + + return []; + }); + }, [ trigger, setIntParams, setStringParam, setFurniIds ]); + + const onSave = useCallback(() => + { + if(save) save(); + + setTimeout(() => dispatchUiEvent(new WiredEvent(WiredEvent.SAVE_WIRED)), 1); + }, [ save ]); + + const close = useCallback(() => + { + setTrigger(null); + }, [ setTrigger ]); + + return ( + +
+
{ LocalizeText('wiredfurni.title') }
+
+ +
+
+ +
+ +
{ wiredName }
+
+
{ wiredDescription }
+
+ { !children ? null : <> +
+ { children } + } +
+ { (requiresFurni > WiredFurniType.STUFF_SELECTION_OPTION_NONE) && + <> +
+ + } +
+ + +
+
+
+ ); +} diff --git a/src/views/wired/views/base/WiredBaseView.types.ts b/src/views/wired/views/base/WiredBaseView.types.ts new file mode 100644 index 00000000..b38c08da --- /dev/null +++ b/src/views/wired/views/base/WiredBaseView.types.ts @@ -0,0 +1,6 @@ +export interface WiredBaseViewProps +{ + wiredType: string; + requiresFurni: number; + save: () => void; +} diff --git a/src/views/wired/views/conditions/actor-has-hand-item/WiredConditionActorHasHandItem.tsx b/src/views/wired/views/conditions/actor-has-hand-item/WiredConditionActorHasHandItem.tsx new file mode 100644 index 00000000..fe4aefe3 --- /dev/null +++ b/src/views/wired/views/conditions/actor-has-hand-item/WiredConditionActorHasHandItem.tsx @@ -0,0 +1,37 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +const allowedHanditemIds: number[] = [ 2, 5, 7, 8, 9, 10, 27 ]; + +export const WiredConditionActorHasHandItemView: FC<{}> = props => +{ + const [ handItemId, setHandItemId ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setHandItemId((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ handItemId ]); + }, [ handItemId, setIntParams ]); + + return ( + +
+ + +
+
+ ); +} diff --git a/src/views/wired/views/conditions/actor-is-group-member/WiredConditionActorIsGroupMemberView.tsx b/src/views/wired/views/conditions/actor-is-group-member/WiredConditionActorIsGroupMemberView.tsx new file mode 100644 index 00000000..8221f74b --- /dev/null +++ b/src/views/wired/views/conditions/actor-is-group-member/WiredConditionActorIsGroupMemberView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionActorIsGroupMemberView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/conditions/actor-is-on-furni/WiredConditionActorIsOnFurniView.tsx b/src/views/wired/views/conditions/actor-is-on-furni/WiredConditionActorIsOnFurniView.tsx new file mode 100644 index 00000000..fbafd294 --- /dev/null +++ b/src/views/wired/views/conditions/actor-is-on-furni/WiredConditionActorIsOnFurniView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionActorIsOnFurniView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/conditions/actor-is-team-member/WiredConditionActorIsTeamMemberView.tsx b/src/views/wired/views/conditions/actor-is-team-member/WiredConditionActorIsTeamMemberView.tsx new file mode 100644 index 00000000..851088a3 --- /dev/null +++ b/src/views/wired/views/conditions/actor-is-team-member/WiredConditionActorIsTeamMemberView.tsx @@ -0,0 +1,42 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +const teamIds: number[] = [ 1, 2, 3, 4 ]; + +export const WiredConditionActorIsTeamMemberView: FC<{}> = props => +{ + const [ selectedTeam, setSelectedTeam ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setSelectedTeam((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ selectedTeam ]); + }, [ selectedTeam, setIntParams ]); + + return ( + +
+ + { teamIds.map((value, index) => + { + return ( +
+ setSelectedTeam(value) } /> + +
+ ) + }) } +
+
+ ); +} diff --git a/src/views/wired/views/conditions/actor-is-wearing-badge/WiredConditionActorIsWearingBadgeView.tsx b/src/views/wired/views/conditions/actor-is-wearing-badge/WiredConditionActorIsWearingBadgeView.tsx new file mode 100644 index 00000000..cfeef2ce --- /dev/null +++ b/src/views/wired/views/conditions/actor-is-wearing-badge/WiredConditionActorIsWearingBadgeView.tsx @@ -0,0 +1,30 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionActorIsWearingBadgeView: FC<{}> = props => +{ + const [ badge, setBadge ] = useState(''); + const { trigger = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setBadge(trigger.stringData); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(badge); + }, [ badge, setStringParam ]); + + return ( + +
+ + setBadge(event.target.value) } /> +
+
+ ); +} diff --git a/src/views/wired/views/conditions/actor-is-wearing-effect/WiredConditionActorIsWearingEffectView.tsx b/src/views/wired/views/conditions/actor-is-wearing-effect/WiredConditionActorIsWearingEffectView.tsx new file mode 100644 index 00000000..4242720a --- /dev/null +++ b/src/views/wired/views/conditions/actor-is-wearing-effect/WiredConditionActorIsWearingEffectView.tsx @@ -0,0 +1,30 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionActorIsWearingEffectView: FC<{}> = props => +{ + const [ effect, setEffect ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setEffect((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ effect ]); + }, [ effect, setIntParams ]); + + return ( + +
+ + setEffect(parseInt(event.target.value)) } /> +
+
+ ); +} diff --git a/src/views/wired/views/conditions/base/WiredConditionBaseView.tsx b/src/views/wired/views/conditions/base/WiredConditionBaseView.tsx new file mode 100644 index 00000000..4504765d --- /dev/null +++ b/src/views/wired/views/conditions/base/WiredConditionBaseView.tsx @@ -0,0 +1,20 @@ +import { FC, useCallback } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredBaseView } from '../../base/WiredBaseView'; +import { WiredConditionBaseViewProps } from './WiredConditionBaseView.types'; + +export const WiredConditionBaseView: FC = props => +{ + const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, children = null } = props; + + const onSave = useCallback(() => + { + if(save) save(); + }, [ save ]); + + return ( + + { children } + + ); +} diff --git a/src/views/wired/views/conditions/base/WiredConditionBaseView.types.ts b/src/views/wired/views/conditions/base/WiredConditionBaseView.types.ts new file mode 100644 index 00000000..61d99f91 --- /dev/null +++ b/src/views/wired/views/conditions/base/WiredConditionBaseView.types.ts @@ -0,0 +1,5 @@ +export interface WiredConditionBaseViewProps +{ + requiresFurni: number; + save: () => void; +} diff --git a/src/views/wired/views/conditions/date-range/WiredConditionDateRangeView.tsx b/src/views/wired/views/conditions/date-range/WiredConditionDateRangeView.tsx new file mode 100644 index 00000000..a0d3c0dd --- /dev/null +++ b/src/views/wired/views/conditions/date-range/WiredConditionDateRangeView.tsx @@ -0,0 +1,62 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionDateRangeView: FC<{}> = props => +{ + const [ startDate, setStartDate ] = useState(''); + const [ endDate, setEndDate ] = useState(''); + const { trigger = null, setIntParams = null } = useWiredContext(); + + const dateToString = useCallback((date: Date) => + { + return `${date.getFullYear()}/${('0' + (date.getMonth() + 1)).slice(-2)}/${('0' + date.getDate()).slice(-2)} ` + `${('0' + date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}`; + }, []); + + 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(dateToString(startDate)); + setEndDate(dateToString(endDate)); + } + }, [ trigger ]); + + const save = useCallback(() => + { + 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]); + }, [ startDate, endDate, setIntParams ]); + + return ( + +
{ LocalizeText('wiredfurni.params.startdate') }
+ setStartDate(e.target.value) } /> +
+
{ LocalizeText('wiredfurni.params.enddate') }
+ setEndDate(e.target.value) } /> +
+ ); +} diff --git a/src/views/wired/views/conditions/furni-has-avatar-on/WiredConditionFurniHasAvatarOnView.tsx b/src/views/wired/views/conditions/furni-has-avatar-on/WiredConditionFurniHasAvatarOnView.tsx new file mode 100644 index 00000000..286273ae --- /dev/null +++ b/src/views/wired/views/conditions/furni-has-avatar-on/WiredConditionFurniHasAvatarOnView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionFurniHasAvatarOnView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/conditions/furni-has-furni-on/WiredConditionFurniHasFurniOnView.tsx b/src/views/wired/views/conditions/furni-has-furni-on/WiredConditionFurniHasFurniOnView.tsx new file mode 100644 index 00000000..1a41594f --- /dev/null +++ b/src/views/wired/views/conditions/furni-has-furni-on/WiredConditionFurniHasFurniOnView.tsx @@ -0,0 +1,40 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionFurniHasFurniOnView: FC<{}> = props => +{ + const [ requireAll, setRequireAll ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setRequireAll((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ requireAll ]); + }, [ requireAll, setIntParams ]); + + return ( + +
+ + { [0, 1].map(value => + { + return ( +
+ setRequireAll(value) } /> + +
+ ) + }) } +
+
+ ); +} diff --git a/src/views/wired/views/conditions/furni-has-not-furni-on/WiredConditionFurniHasNotFurniOnView.tsx b/src/views/wired/views/conditions/furni-has-not-furni-on/WiredConditionFurniHasNotFurniOnView.tsx new file mode 100644 index 00000000..b9002190 --- /dev/null +++ b/src/views/wired/views/conditions/furni-has-not-furni-on/WiredConditionFurniHasNotFurniOnView.tsx @@ -0,0 +1,40 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionFurniHasNotFurniOnView: FC<{}> = props => +{ + const [ requireAll, setRequireAll ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setRequireAll((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ requireAll ]); + }, [ requireAll, setIntParams ]); + + return ( + +
+ + { [0, 1].map(value => + { + return ( +
+ setRequireAll(value) } /> + +
+ ) + }) } +
+
+ ); +} diff --git a/src/views/wired/views/conditions/furni-is-of-type/WiredConditionFurniIsOfTypeView.tsx b/src/views/wired/views/conditions/furni-is-of-type/WiredConditionFurniIsOfTypeView.tsx new file mode 100644 index 00000000..2f2514a7 --- /dev/null +++ b/src/views/wired/views/conditions/furni-is-of-type/WiredConditionFurniIsOfTypeView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionFurniIsOfTypeView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/conditions/furni-matches-snapshot/WiredConditionFurniMatchesSnapshotView.tsx b/src/views/wired/views/conditions/furni-matches-snapshot/WiredConditionFurniMatchesSnapshotView.tsx new file mode 100644 index 00000000..5fdffee8 --- /dev/null +++ b/src/views/wired/views/conditions/furni-matches-snapshot/WiredConditionFurniMatchesSnapshotView.tsx @@ -0,0 +1,51 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionFurniMatchesSnapshotView: FC<{}> = props => +{ + const [ stateFlag, setStateFlag ] = useState(-1); + const [ directionFlag, setDirectionFlag ] = useState(-1); + const [ positionFlag, setPositionFlag ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setStateFlag(trigger.getBoolean(0) ? 1 : 0); + setDirectionFlag(trigger.getBoolean(1) ? 1 : 0); + setPositionFlag(trigger.getBoolean(2) ? 1 : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ stateFlag, directionFlag, positionFlag ]); + }, [ directionFlag, positionFlag, stateFlag, setIntParams ]); + + return ( + +
+ +
+ setStateFlag(event.target.checked ? 1 : 0) } /> + +
+
+ setDirectionFlag(event.target.checked ? 1 : 0) } /> + +
+
+ setPositionFlag(event.target.checked ? 1 : 0) } /> + +
+
+
+ ); +} diff --git a/src/views/wired/views/conditions/time-elapsed-less/WiredConditionTimeElapsedLessView.tsx b/src/views/wired/views/conditions/time-elapsed-less/WiredConditionTimeElapsedLessView.tsx new file mode 100644 index 00000000..72210acf --- /dev/null +++ b/src/views/wired/views/conditions/time-elapsed-less/WiredConditionTimeElapsedLessView.tsx @@ -0,0 +1,36 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { GetWiredTimeLocale } from '../../../common/GetWiredTimeLocale'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionTimeElapsedLessView: FC<{}> = props => +{ + const [ time, setTime ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ time ]); + }, [ time, setIntParams ]); + + return ( + +
+ + setTime(event) } /> +
+
+ ); +} diff --git a/src/views/wired/views/conditions/time-elapsed-more/WiredConditionTimeElapsedMoreView.tsx b/src/views/wired/views/conditions/time-elapsed-more/WiredConditionTimeElapsedMoreView.tsx new file mode 100644 index 00000000..a8210ccc --- /dev/null +++ b/src/views/wired/views/conditions/time-elapsed-more/WiredConditionTimeElapsedMoreView.tsx @@ -0,0 +1,36 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { GetWiredTimeLocale } from '../../../common/GetWiredTimeLocale'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionTimeElapsedMoreView: FC<{}> = props => +{ + const [ time, setTime ] = useState(-1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ time ]); + }, [ time, setIntParams ]); + + return ( + +
+ + setTime(event) } /> +
+
+ ); +} diff --git a/src/views/wired/views/conditions/user-count-in-room/WiredConditionUserCountInRoomView.tsx b/src/views/wired/views/conditions/user-count-in-room/WiredConditionUserCountInRoomView.tsx new file mode 100644 index 00000000..aa07267b --- /dev/null +++ b/src/views/wired/views/conditions/user-count-in-room/WiredConditionUserCountInRoomView.tsx @@ -0,0 +1,53 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredConditionBaseView } from '../base/WiredConditionBaseView'; + +export const WiredConditionUserCountInRoomView: FC<{}> = props => +{ + const [ min, setMin ] = useState(1); + const [ max, setMax ] = useState(1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + if(trigger.intData.length >= 2) + { + setMin(trigger.intData[0]); + setMax(trigger.intData[1]); + } + else + { + setMin(1); + setMax(1); + } + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ min, max ]); + }, [ min, max, setIntParams ]); + + return ( + +
+ + setMin(event) } /> +
+
+ + setMax(event) } /> +
+
+ ); +} diff --git a/src/views/wired/views/furni-selector/WiredFurniSelectorView.tsx b/src/views/wired/views/furni-selector/WiredFurniSelectorView.tsx new file mode 100644 index 00000000..aef71694 --- /dev/null +++ b/src/views/wired/views/furni-selector/WiredFurniSelectorView.tsx @@ -0,0 +1,84 @@ +import { FC, useCallback, useEffect } from 'react'; +import { WiredSelectObjectEvent } from '../../../../events'; +import { useUiEvent } from '../../../../hooks/events'; +import { LocalizeText } from '../../../../utils/LocalizeText'; +import { WiredSelectionVisualizer } from '../../common/WiredSelectionVisualizer'; +import { useWiredContext } from '../../context/WiredContext'; +import { WiredFurniSelectorViewProps } from './WiredFurniSelectorView.types'; + +export const WiredFurniSelectorView: FC = props => +{ + const { trigger = null, furniIds = [], setFurniIds = null } = useWiredContext(); + + const onWiredSelectObjectEvent = useCallback((event: WiredSelectObjectEvent) => + { + const furniId = event.objectId; + + if(furniId === -1) return; + + let newFurniIds: number[] = null; + + setFurniIds(prevValue => + { + newFurniIds = [ ...prevValue ]; + + const index = prevValue.indexOf(furniId); + + if(index >= 0) + { + newFurniIds.splice(index, 1); + + WiredSelectionVisualizer.hide(furniId); + } + else + { + if(newFurniIds.length < trigger.maximumItemSelectionCount) + { + newFurniIds.push(furniId); + + WiredSelectionVisualizer.show(furniId); + } + } + + return newFurniIds; + }); + }, [ trigger, setFurniIds ]); + + useUiEvent(WiredSelectObjectEvent.SELECT_OBJECT, onWiredSelectObjectEvent); + + useEffect(() => + { + if(!trigger) return; + + setFurniIds(prevValue => + { + if(prevValue && prevValue.length) WiredSelectionVisualizer.clearSelectionShaderFromFurni(prevValue); + + if(trigger.selectedItems && trigger.selectedItems.length) + { + WiredSelectionVisualizer.applySelectionShaderToFurni(trigger.selectedItems); + + return trigger.selectedItems; + } + + return []; + }); + + return () => + { + setFurniIds(prevValue => + { + WiredSelectionVisualizer.clearSelectionShaderFromFurni(prevValue); + + return []; + }); + } + }, [ trigger, setFurniIds ]); + + return ( +
+
{ LocalizeText('wiredfurni.pickfurnis.caption', ['count', 'limit'], [ furniIds.length.toString(), trigger.maximumItemSelectionCount.toString() ]) }
+ { LocalizeText('wiredfurni.pickfurnis.desc') } +
+ ); +} diff --git a/src/views/wired/views/furni-selector/WiredFurniSelectorView.types.ts b/src/views/wired/views/furni-selector/WiredFurniSelectorView.types.ts new file mode 100644 index 00000000..4bca7969 --- /dev/null +++ b/src/views/wired/views/furni-selector/WiredFurniSelectorView.types.ts @@ -0,0 +1,3 @@ +export class WiredFurniSelectorViewProps +{ +} diff --git a/src/views/wired/views/triggers/avatar-enter-room/WiredTriggerAvatarEnterRoomView.tsx b/src/views/wired/views/triggers/avatar-enter-room/WiredTriggerAvatarEnterRoomView.tsx new file mode 100644 index 00000000..c2ae65c3 --- /dev/null +++ b/src/views/wired/views/triggers/avatar-enter-room/WiredTriggerAvatarEnterRoomView.tsx @@ -0,0 +1,48 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerAvatarEnterRoomView: FC<{}> = props => +{ + const [ username, setUsername ] = useState(''); + const [ avatarMode, setAvatarMode ] = useState(0); + const { trigger = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setUsername(trigger.stringData); + setAvatarMode(trigger.stringData ? 1 : 0) + }, [ trigger ]); + + const save = useCallback(() => + { + if(avatarMode === 1) setStringParam(username); + else setStringParam(''); + }, [ username, avatarMode, setStringParam ]); + + return ( + +
+ +
+ setAvatarMode(0) } /> + +
+
+ setAvatarMode(1) } /> + +
+
+ { (avatarMode === 1) && +
+ setUsername(event.target.value) } /> +
} +
+ ); +} diff --git a/src/views/wired/views/triggers/avatar-says-something/WiredTriggerAvatarSaysSomethingView.tsx b/src/views/wired/views/triggers/avatar-says-something/WiredTriggerAvatarSaysSomethingView.tsx new file mode 100644 index 00000000..761006f2 --- /dev/null +++ b/src/views/wired/views/triggers/avatar-says-something/WiredTriggerAvatarSaysSomethingView.tsx @@ -0,0 +1,49 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { GetSessionDataManager } from '../../../../../api'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerAvatarSaysSomethingView: FC<{}> = props => +{ + const [ message, setMessage ] = useState(''); + const [ triggererAvatar, setTriggererAvatar ] = useState(-1); + const { trigger = null, setStringParam = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setMessage(trigger.stringData); + setTriggererAvatar((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(message); + setIntParams([ triggererAvatar ]); + }, [ message, triggererAvatar, setStringParam, setIntParams ]); + + return ( + +
+ + setMessage(event.target.value) } /> +
+
+ +
+ setTriggererAvatar(0)} /> + +
+
+ setTriggererAvatar(1)} /> + +
+
+
+ ); +} diff --git a/src/views/wired/views/triggers/avatar-walks-off-furni/WiredTriggerAvatarWalksOffFurniView.tsx b/src/views/wired/views/triggers/avatar-walks-off-furni/WiredTriggerAvatarWalksOffFurniView.tsx new file mode 100644 index 00000000..4a9176ca --- /dev/null +++ b/src/views/wired/views/triggers/avatar-walks-off-furni/WiredTriggerAvatarWalksOffFurniView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerAvatarWalksOffFurniView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/triggers/avatar-walks-on-furni/WiredTriggerAvatarWalksOnFurni.tsx b/src/views/wired/views/triggers/avatar-walks-on-furni/WiredTriggerAvatarWalksOnFurni.tsx new file mode 100644 index 00000000..1584600d --- /dev/null +++ b/src/views/wired/views/triggers/avatar-walks-on-furni/WiredTriggerAvatarWalksOnFurni.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerAvatarWalksOnFurniView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/triggers/base/WiredTriggerBaseView.tsx b/src/views/wired/views/triggers/base/WiredTriggerBaseView.tsx new file mode 100644 index 00000000..330b3405 --- /dev/null +++ b/src/views/wired/views/triggers/base/WiredTriggerBaseView.tsx @@ -0,0 +1,20 @@ +import { FC, useCallback } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredBaseView } from '../../base/WiredBaseView'; +import { WiredTriggerBaseViewProps } from './WiredTriggerBaseView.types'; + +export const WiredTriggerBaseView: FC = props => +{ + const { requiresFurni = WiredFurniType.STUFF_SELECTION_OPTION_NONE, save = null, children = null } = props; + + const onSave = useCallback(() => + { + if(save) save(); + }, [ save ]); + + return ( + + { children } + + ); +} diff --git a/src/views/wired/views/triggers/base/WiredTriggerBaseView.types.ts b/src/views/wired/views/triggers/base/WiredTriggerBaseView.types.ts new file mode 100644 index 00000000..9e766aa8 --- /dev/null +++ b/src/views/wired/views/triggers/base/WiredTriggerBaseView.types.ts @@ -0,0 +1,5 @@ +export interface WiredTriggerBaseViewProps +{ + requiresFurni: number; + save: () => void; +} diff --git a/src/views/wired/views/triggers/bot-reached-avatar/WiredTriggerBotReachedAvatarView.tsx b/src/views/wired/views/triggers/bot-reached-avatar/WiredTriggerBotReachedAvatarView.tsx new file mode 100644 index 00000000..b16d0489 --- /dev/null +++ b/src/views/wired/views/triggers/bot-reached-avatar/WiredTriggerBotReachedAvatarView.tsx @@ -0,0 +1,30 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerBotReachedAvatarView: FC<{}> = props => +{ + const [ botName, setBotName ] = useState(''); + const { trigger = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setBotName(trigger.stringData); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(botName); + }, [ botName, setStringParam ]); + + return ( + +
+ + setBotName(event.target.value) } /> +
+
+ ); +} diff --git a/src/views/wired/views/triggers/bot-reached-stuff/WiredTriggerBotReachedStuffView.tsx b/src/views/wired/views/triggers/bot-reached-stuff/WiredTriggerBotReachedStuffView.tsx new file mode 100644 index 00000000..0f1070a5 --- /dev/null +++ b/src/views/wired/views/triggers/bot-reached-stuff/WiredTriggerBotReachedStuffView.tsx @@ -0,0 +1,30 @@ +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerBotReachedStuffView: FC<{}> = props => +{ + const [ botName, setBotName ] = useState(''); + const { trigger = null, setStringParam = null } = useWiredContext(); + + useEffect(() => + { + setBotName(trigger.stringData); + }, [ trigger ]); + + const save = useCallback(() => + { + setStringParam(botName); + }, [ botName, setStringParam ]); + + return ( + +
+ + setBotName(event.target.value) } /> +
+
+ ); +} diff --git a/src/views/wired/views/triggers/collision/WiredTriggerCollisionView.tsx b/src/views/wired/views/triggers/collision/WiredTriggerCollisionView.tsx new file mode 100644 index 00000000..2e76dbfe --- /dev/null +++ b/src/views/wired/views/triggers/collision/WiredTriggerCollisionView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerCollisionView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/triggers/execute-once/WiredTriggerExecuteOnceView.tsx b/src/views/wired/views/triggers/execute-once/WiredTriggerExecuteOnceView.tsx new file mode 100644 index 00000000..f9f7cb4c --- /dev/null +++ b/src/views/wired/views/triggers/execute-once/WiredTriggerExecuteOnceView.tsx @@ -0,0 +1,36 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { GetWiredTimeLocale } from '../../../common/GetWiredTimeLocale'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggeExecuteOnceView: FC<{}> = props => +{ + const [ time, setTime ] = useState(1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ time ]); + }, [ time, setIntParams ]); + + return ( + +
+ + setTime(event) } /> +
+
+ ); +} diff --git a/src/views/wired/views/triggers/execute-periodically-long/WiredTriggerExecutePeriodicallyLongView.tsx b/src/views/wired/views/triggers/execute-periodically-long/WiredTriggerExecutePeriodicallyLongView.tsx new file mode 100644 index 00000000..6cf75704 --- /dev/null +++ b/src/views/wired/views/triggers/execute-periodically-long/WiredTriggerExecutePeriodicallyLongView.tsx @@ -0,0 +1,36 @@ +import { FriendlyTime } from 'nitro-renderer'; +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggeExecutePeriodicallyLongView: FC<{}> = props => +{ + const [ time, setTime ] = useState(1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ time ]); + }, [ time, setIntParams ]); + + return ( + +
+ + setTime(event) } /> +
+
+ ); +} diff --git a/src/views/wired/views/triggers/execute-periodically/WiredTriggerExecutePeriodicallyView.tsx b/src/views/wired/views/triggers/execute-periodically/WiredTriggerExecutePeriodicallyView.tsx new file mode 100644 index 00000000..98049d39 --- /dev/null +++ b/src/views/wired/views/triggers/execute-periodically/WiredTriggerExecutePeriodicallyView.tsx @@ -0,0 +1,36 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { GetWiredTimeLocale } from '../../../common/GetWiredTimeLocale'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggeExecutePeriodicallyView: FC<{}> = props => +{ + const [ time, setTime ] = useState(1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ time ]); + }, [ time, setIntParams ]); + + return ( + +
+ + setTime(event) } /> +
+
+ ); +} diff --git a/src/views/wired/views/triggers/game-ends/WiredTriggerGameEndsView.tsx b/src/views/wired/views/triggers/game-ends/WiredTriggerGameEndsView.tsx new file mode 100644 index 00000000..9f219b97 --- /dev/null +++ b/src/views/wired/views/triggers/game-ends/WiredTriggerGameEndsView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerGameEndsView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/triggers/game-starts/WiredTriggerGameStartsView.tsx b/src/views/wired/views/triggers/game-starts/WiredTriggerGameStartsView.tsx new file mode 100644 index 00000000..cee76c33 --- /dev/null +++ b/src/views/wired/views/triggers/game-starts/WiredTriggerGameStartsView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerGameStartsView: FC<{}> = props => +{ + return ; +} diff --git a/src/views/wired/views/triggers/score-achieved/WiredTriggerScoreAchievedView.tsx b/src/views/wired/views/triggers/score-achieved/WiredTriggerScoreAchievedView.tsx new file mode 100644 index 00000000..a6c53191 --- /dev/null +++ b/src/views/wired/views/triggers/score-achieved/WiredTriggerScoreAchievedView.tsx @@ -0,0 +1,35 @@ +import Slider from 'rc-slider/lib/Slider'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useWiredContext } from '../../../context/WiredContext'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggeScoreAchievedView: FC<{}> = props => +{ + const [ points, setPoints ] = useState(1); + const { trigger = null, setIntParams = null } = useWiredContext(); + + useEffect(() => + { + setPoints((trigger.intData.length > 0) ? trigger.intData[0] : 0); + }, [ trigger ]); + + const save = useCallback(() => + { + setIntParams([ points ]); + }, [ points, setIntParams ]); + + return ( + +
+ + setPoints(event) } /> +
+
+ ); +} diff --git a/src/views/wired/views/triggers/toggle-furni/WiredTriggerToggleFurniView.tsx b/src/views/wired/views/triggers/toggle-furni/WiredTriggerToggleFurniView.tsx new file mode 100644 index 00000000..28ae43c8 --- /dev/null +++ b/src/views/wired/views/triggers/toggle-furni/WiredTriggerToggleFurniView.tsx @@ -0,0 +1,8 @@ +import { FC } from 'react'; +import { WiredFurniType } from '../../../WiredView.types'; +import { WiredTriggerBaseView } from '../base/WiredTriggerBaseView'; + +export const WiredTriggerToggleFurniView: FC<{}> = props => +{ + return ; +}