commit 4f733c86900d16135529816d5dc0ce86dd41b415 Author: ShuriZma Date: Tue Jan 16 08:46:51 2024 +0100 init diff --git a/client/SeatSelector.ts b/client/SeatSelector.ts new file mode 100644 index 0000000..00cc3d1 --- /dev/null +++ b/client/SeatSelector.ts @@ -0,0 +1,88 @@ +import * as alt from 'alt-client'; +import * as native from 'natives'; +import * as AthenaClient from '@AthenaClient/api/index.js'; +import { SEAT_SELECTOR_EVENTS } from '@AthenaPlugins/odyssey-seat-selector/shared/events.js'; +import { IPage } from '@AthenaClient/webview/page.js'; +import { WebViewEventNames } from '@AthenaShared/enums/webViewEvents.js'; + +const PAGE_NAME = 'SeatSelectorMenu'; + +export function handleOpen() { + let tick; + if (alt.LocalPlayer.local.vehicle !== null) { + return; + } + + const vehicle = alt.Utils.getClosestVehicle({ pos: alt.LocalPlayer.local.pos, range: 5 }); + if (vehicle === null || vehicle.seatCount < 2) { + return; + } + + if (vehicle.seatCount === 2) { + if (!native.isVehicleSeatFree(vehicle, 0, true)) { + return; + } + + native.setPedConfigFlag(alt.Player.local.scriptID, 184, true); + native.taskEnterVehicle(alt.Player.local.scriptID, vehicle, 5000, 0, 2.0, 1, null, 0); + return; + } + + new AthenaClient.webview.Page({ + name: PAGE_NAME, + callbacks: { + onReady: () => { + AthenaClient.webview.emit(SEAT_SELECTOR_EVENTS.SET_VEHICLE, vehicle.scriptID); + + updateData(vehicle.scriptID); + + tick = alt.everyTick(() => { + if (!AthenaClient.webview.isPageOpen(PAGE_NAME)) { + return; + } + + updateData(vehicle.scriptID); + }); + }, + onClose: () => { + alt.clearEveryTick(tick); + }, + }, + options: { + onOpen: { + focus: true, + showCursor: true, + setIsMenuOpenToTrue: true, + disablePauseMenu: true, + disableControls: 'all', + }, + onClose: { + hideCursor: true, + unfocus: true, + setIsMenuOpenToFalse: true, + enablePauseMenu: true, + enableControls: true, + }, + }, + } as IPage).open(); +} + +function updateData(vehicleScriptId: number) { + const vehicle = alt.Vehicle.getByScriptID(vehicleScriptId); + if (vehicle === null || AthenaClient.utility.vector.distance(vehicle.pos, alt.LocalPlayer.local.pos) > 5) { + AthenaClient.webview.emit(WebViewEventNames.CLOSE_PAGE); + } + + try { + let data: object[] = []; + for (let seat = 0; seat < vehicle.seatCount; seat++) { + data.push({ + isFree: native.isVehicleSeatFree(vehicle, seat - 1, true), + index: seat - 1, + }); + } + AthenaClient.webview.emit(SEAT_SELECTOR_EVENTS.UPDATE_DATA, data); + } catch (error) { + alt.logWarning(`Error while updating SeatSelectorMenu: ${error}!`); + } +} diff --git a/client/index.ts b/client/index.ts new file mode 100644 index 0000000..b1c708a --- /dev/null +++ b/client/index.ts @@ -0,0 +1,55 @@ +import { handleOpen } from './SeatSelector.js'; +import { SEAT_SELECTOR_EVENTS } from '@AthenaPlugins/odyssey-seat-selector/shared/events.js'; +import { KEY_BINDS } from '@AthenaShared/enums/keyBinds.js'; +import * as KEYBOARD_MAP from '@AthenaShared/information/keyboardMap.js'; +import * as AthenaClient from '@AthenaClient/api/index.js'; +import * as alt from 'alt-client'; +import * as native from 'natives'; + +AthenaClient.systems.hotkeys.add({ + key: KEY_BINDS.SELECT_SEAT ?? KEYBOARD_MAP.default.indexOf('G'), + description: 'Select a seat', + identifier: 'seat-selector', + keyDown: () => { + handleOpen(); + }, + restrictions: { + isOnFoot: true, + }, +}); + +AthenaClient.webview.on(SEAT_SELECTOR_EVENTS.ENTER_VEHICLE, (vehicle: number, index: number) => { + native.setPedConfigFlag(alt.Player.local.scriptID, 184, true); + native.taskEnterVehicle(alt.Player.local.scriptID, vehicle, 5000, index, 2.0, 1, null, 0); +}); + +AthenaClient.systems.hotkeys.add({ + key: KEY_BINDS.VEHICLE_FUNCS ?? KEYBOARD_MAP.default.indexOf('F'), + description: 'Enter vehicle as driver', + identifier: 'enter-vehicle-as-driver', + keyDown: () => { + if (alt.Player.local.vehicle !== null) { + if (native.getEntitySpeed(alt.Player.local.vehicle) > 0.0) { + native.taskLeaveVehicle(alt.Player.local.scriptID, alt.Player.local.vehicle.scriptID, 4160); + return; + } + native.taskLeaveVehicle(alt.Player.local.scriptID, alt.Player.local.vehicle.scriptID, 0); + return; + } + + let vehicle = alt.Utils.getClosestVehicle({ pos: alt.LocalPlayer.local.pos, range: 5 }); + if (vehicle === null) { + return; + } + + if (!native.isVehicleSeatFree(vehicle, -1, true)) { + return; + } + + native.taskEnterVehicle(alt.Player.local.scriptID, vehicle, 5000, -1, 2.0, 1, null, 0); + }, +}); + +alt.on('leftVehicle', () => { + native.setPedConfigFlag(alt.Player.local.scriptID, 184, false); +}); diff --git a/server/index.ts b/server/index.ts new file mode 100644 index 0000000..7db6065 --- /dev/null +++ b/server/index.ts @@ -0,0 +1,6 @@ +import * as Athena from '@AthenaServer/api/index.js'; + +const PLUGIN_NAME = 'seat-selector'; + +Athena.systems.plugins.registerPlugin(PLUGIN_NAME, () => { +}); diff --git a/shared/events.ts b/shared/events.ts new file mode 100644 index 0000000..def9050 --- /dev/null +++ b/shared/events.ts @@ -0,0 +1,5 @@ +export const enum SEAT_SELECTOR_EVENTS { + SET_VEHICLE = 'SEAT-SELECTOR:set-vehicle', + UPDATE_DATA = 'SEAT-SELECTOR:update-data', + ENTER_VEHICLE = 'SEAT-SELECTOR:enter-vehicle', +} diff --git a/webview/SeatSelectorMenu.vue b/webview/SeatSelectorMenu.vue new file mode 100644 index 0000000..50d4b22 --- /dev/null +++ b/webview/SeatSelectorMenu.vue @@ -0,0 +1,178 @@ + + + diff --git a/webview/images/bus.png b/webview/images/bus.png new file mode 100644 index 0000000..0124050 Binary files /dev/null and b/webview/images/bus.png differ diff --git a/webview/images/car-seat-bg.svg b/webview/images/car-seat-bg.svg new file mode 100644 index 0000000..473fd3e --- /dev/null +++ b/webview/images/car-seat-bg.svg @@ -0,0 +1,51 @@ + + + + + + + + + diff --git a/webview/images/car-seat.svg b/webview/images/car-seat.svg new file mode 100644 index 0000000..cd823b7 --- /dev/null +++ b/webview/images/car-seat.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + diff --git a/webview/images/car.png b/webview/images/car.png new file mode 100644 index 0000000..85dd809 Binary files /dev/null and b/webview/images/car.png differ diff --git a/webview/images/ov.png b/webview/images/ov.png new file mode 100644 index 0000000..7957f74 Binary files /dev/null and b/webview/images/ov.png differ