generated from project-error/fivem-react-boilerplate-lua
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Demigod
committed
Aug 21, 2023
1 parent
ed197ff
commit 7701870
Showing
21 changed files
with
1,770 additions
and
357 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,216 +1,78 @@ | ||
<div align="center"> | ||
<img href="https://projecterror.dev" width="150" src="https://i.tasoagc.dev/c1pD" alt="Material-UI logo" /> | ||
</div> | ||
<h1 align="center">FiveM React and Lua Boilerplate</h1> | ||
# demi_lootbox - README.md | ||
|
||
<div align="center"> | ||
A simple and extendable React (TypeScript) boilerplate designed around the Lua ScRT | ||
</div> | ||
## Overview | ||
|
||
<div align="center"> | ||
|
||
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/project-error/pe-utils/master/LICENSE) | ||
![Discord](https://img.shields.io/discord/791854454760013827?label=Our%20Discord) | ||
![David](https://img.shields.io/david/project-error/fivem-react-boilerplate-lua) | ||
[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=project-error/fivem-react-boilerplate-lua)](https://dependabot.com) | ||
</div> | ||
|
||
This repository is a basic boilerplate for getting started | ||
with React in NUI. It contains several helpful utilities and | ||
is bootstrapped using `create-react-app`. It is for both browser | ||
and in-game based development workflows. | ||
|
||
For in-game workflows, Utilizing `craco` to override CRA, we can have hot | ||
builds that just require a resource restart instead of a full | ||
production build | ||
|
||
This version of the boilerplate is meant for the CfxLua runtime. | ||
|
||
## Requirements | ||
* [Node > v10.6](https://nodejs.org/en/) | ||
* [Yarn](https://yarnpkg.com/getting-started/install) (Preferred but not required) | ||
|
||
*A basic understanding of the modern web development workflow. If you don't | ||
know this yet, React might not be for you just yet.* | ||
|
||
## Getting Started | ||
|
||
First clone the repository or use the template option and place | ||
it within your `resources` folder | ||
|
||
### Installation | ||
|
||
*The boilerplate was made using `yarn` but is still compatible with | ||
`npm`.* | ||
|
||
Install dependencies by navigating to the `web` folder within | ||
a terminal of your choice and type `npm i` or `yarn`. | ||
`demi_lootbox` is a FiveM script that brings a CSGO-style case opening user interface into your server. With a visual representation and configurable case contents, this script enhances the in-game economy with randomized loot mechanics. | ||
|
||
## Features | ||
|
||
This boilerplate comes with some utilities and examples to work off of. | ||
|
||
### Lua Utils | ||
- **Customizable Cases:** Define your own cases with varying rarity levels (common, uncommon, rare, epic, legendary). | ||
- **UI:** A UI that gives players a sense of anticipation when opening cases. | ||
- **Dependencies:** The script requires `ox_inventory` to function properly. | ||
|
||
**SendReactMessage** | ||
## Installation | ||
|
||
This is a small wrapper for dispatching NUI messages. This is designed | ||
to be used with the `useNuiEvent` React hook. | ||
|
||
Signature | ||
```lua | ||
---@param action string The action you wish to target | ||
---@param data any The data you wish to send along with this action | ||
SendReactMessage(action, data) | ||
``` | ||
|
||
Usage | ||
```lua | ||
SendReactMessage('setVisible', true) | ||
``` | ||
1. Ensure you have the `ox_inventory` installed and properly configured in your FiveM server. | ||
2. Copy the `demi_lootbox` folder into your server's resources directory. | ||
3. Add `ensure demi_lootbox` to your server configuration file. | ||
|
||
**debugPrint** | ||
## Configuration | ||
|
||
A debug printing utility that is dependent on a convar, | ||
if the convar is set this will print out to the console. | ||
The primary configuration for your cases is done within the `CASES` table found in `server/data.lua` Here, you can define your own cases with varying rarity levels and the weapons/items each rarity level might contain. | ||
|
||
The convar is dependent on the name given to the resource. | ||
It follows this format `YOUR_RESOURCE_NAME-debugMode` | ||
each rarity should have at least 1 item in it, or the script wont work properly. | ||
|
||
To turn on debugMode add `setr YOUR_RESOURCE_NAME-debugMode 1` to | ||
your server.cfg or use the `setr` console command instead. | ||
Example: | ||
|
||
Signature (Replicates `print`) | ||
```lua | ||
---@param ... any[] The arguments you wish to send | ||
debugPrint(...) | ||
``` | ||
|
||
Usage | ||
```lua | ||
debugPrint('wow cool string to print', true, someOtherVar) | ||
``` | ||
|
||
### React Utils | ||
|
||
Signatures are not included for these utilities as the type definitions | ||
are sufficient enough. | ||
|
||
**useNuiEvent** | ||
|
||
This is a custom React hook that is designed to intercept and handle | ||
messages dispatched by the game scripts. This is the primary | ||
way of creating passive listeners. | ||
|
||
|
||
*Note: For now handlers can only be registered a single time. I haven't | ||
come across a personal usecase for a cascading event system* | ||
|
||
**Usage** | ||
```jsx | ||
const MyComp: React.FC = () => { | ||
const [state, setState] = useState('') | ||
|
||
useNuiEvent<string>('myAction', (data) => { | ||
// the first argument to the handler function | ||
// is the data argument sent using SendReactMessage | ||
|
||
// do whatever logic u want here | ||
setState(data) | ||
}) | ||
|
||
return( | ||
<div> | ||
<h1>Some component</h1> | ||
<p>{state}</p> | ||
</div> | ||
) | ||
CASES = { | ||
['weapon_case'] = { | ||
common = { | ||
{ | ||
name = 'WEAPON_PISTOL', | ||
amount = 1, | ||
}, | ||
... | ||
}, | ||
... | ||
} | ||
} | ||
|
||
``` | ||
|
||
**fetchNui** | ||
|
||
This is a simple NUI focused wrapper around the standard `fetch` API. | ||
This is the main way to accomplish active NUI data fetching | ||
or to trigger NUI callbacks in the game scripts. | ||
|
||
When using this, you must always at least callback using `{}` | ||
in the gamescripts. | ||
|
||
*This can be heavily customized to your use case* | ||
## Usage | ||
|
||
**Usage** | ||
```ts | ||
// First argument is the callback event name. | ||
fetchNui<ReturnData>('getClientData').then(retData => { | ||
console.log('Got return data from client scripts:') | ||
console.dir(retData) | ||
setClientData(retData) | ||
}).catch(e => { | ||
console.error('Setting mock data due to error', e) | ||
setClientData({ x: 500, y: 300, z: 200}) | ||
}) | ||
To test a case: | ||
``` | ||
|
||
**debugData** | ||
|
||
This is a function allowing for mocking dispatched game script | ||
actions in a browser environment. It will trigger `useNuiEvent` handlers | ||
as if they were dispatched by the game scripts. **It will only fire if the current | ||
environment is a regular browser and not CEF** | ||
|
||
**Usage** | ||
```ts | ||
// This will target the useNuiEvent hooks registered with `setVisible` | ||
// and pass them the data of `true` | ||
debugData([ | ||
{ | ||
action: 'setVisible', | ||
data: true, | ||
} | ||
]) | ||
/opencase [case_name] | ||
``` | ||
Replace `[case_name]` with the actual name of the case you want to open (for instance, `weapon_case`). | ||
|
||
**Misc Utils** | ||
|
||
These are small but useful included utilities. | ||
|
||
* `isEnvBrowser()` - Will return a boolean indicating if the current | ||
environment is a regular browser. (Useful for logic in development) | ||
|
||
## Development Workflow | ||
ideally you would remove this command before putting it in your server | ||
|
||
This boilerplate was designed with development workflow in mind. | ||
It includes some helpful scripts to accomplish that. | ||
## Exported Functions | ||
You can use the exported function to open a case programmatically through an item use or something: | ||
|
||
**Hot Builds In-Game** | ||
```lua | ||
exports.demi_lootbox.openCase(caseName) | ||
``` | ||
|
||
When developing in-game, you can use the hot build system by | ||
running the `start:game` script. This is essentially the start | ||
script but it writes to disk. Meaning all that is required is a | ||
resource restart to update the game script | ||
|
||
**Usage** | ||
```sh | ||
# yarn | ||
yarn start:game | ||
# npm | ||
npm run start:game | ||
``` | ||
## Probabilities | ||
for those curious about the chances | ||
|
||
**Production Builds** | ||
- Common: 80% | ||
- Uncommon: 16% | ||
- Rare: 3.10% | ||
- Epic: 0.64% | ||
- Legendary: 0.26% | ||
|
||
When you are done with development phase for your resource. You | ||
must create a production build that is optimized and minimized. | ||
## Client-Side Functions | ||
|
||
You can do this by running the following: | ||
- `getWinnerForCase(case)`: A function to get the winning item for a specific case. | ||
- Command `/opencase`: To open a specified case. | ||
- NUI Callback for when the case opening animation finishes. | ||
|
||
```sh | ||
npm run build | ||
yarn build | ||
``` | ||
## Feedback & Support | ||
|
||
## Additional Notes | ||
For any feedback or support regarding the script, please reach out in the forums or discord `demiautomatic`. | ||
|
||
Need further support? Join our [Discord](https://discord.com/invite/HYwBjTbAY5)! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,18 @@ | ||
local function toggleNuiFrame(shouldShow) | ||
SetNuiFocus(shouldShow, shouldShow) | ||
SendReactMessage('setVisible', shouldShow) | ||
end | ||
local function getWinnerForCase(case) | ||
local lootPool, winner = lib.callback.await('demi_lootbox:getCaseAndWinner', false, case) | ||
|
||
RegisterCommand('show-nui', function() | ||
toggleNuiFrame(true) | ||
debugPrint('Show NUI frame') | ||
end) | ||
SendReactMessage('setLootData', { pool = lootPool, winner = winner }) | ||
end | ||
|
||
RegisterNUICallback('hideFrame', function(_, cb) | ||
toggleNuiFrame(false) | ||
debugPrint('Hide NUI frame') | ||
cb({}) | ||
RegisterCommand('opencase', function(src, args) | ||
if not args[1] then return end | ||
getWinnerForCase(args[1]) | ||
end) | ||
|
||
RegisterNUICallback('getClientData', function(data, cb) | ||
debugPrint('Data sent by React', json.encode(data)) | ||
exports('openCase', getWinnerForCase) | ||
|
||
-- Lets send back client coords to the React frame for use | ||
local curCoords = GetEntityCoords(PlayerPedId()) | ||
|
||
local retData <const> = { x = curCoords.x, y = curCoords.y, z = curCoords.z } | ||
cb(retData) | ||
end) | ||
RegisterNUICallback('finished', function(_,cb) | ||
TriggerServerEvent('demi_lootbox:getQueuedItem') | ||
cb({}) | ||
end) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,15 @@ | ||
fx_version "cerulean" | ||
|
||
description "Basic React (TypeScript) & Lua Game Scripts Boilerplate" | ||
author "Project Error" | ||
version '1.0.0' | ||
repository 'https://github.com/project-error/fivem-react-boilerplate-lua' | ||
|
||
lua54 'yes' | ||
|
||
games { | ||
"gta5", | ||
"rdr3" | ||
} | ||
game "gta5" | ||
|
||
ui_page 'web/build/index.html' | ||
|
||
shared_script '@ox_lib/init.lua' | ||
|
||
client_script "client/**/*" | ||
server_script "server/**/*" | ||
|
||
files { | ||
'web/build/index.html', | ||
'web/build/**/*', | ||
} | ||
'web/build/index.html', | ||
'web/build/**/*', | ||
} |
Oops, something went wrong.