Skip to content

Commit

Permalink
Merge pull request #7 from Mojito-Fivem/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
LiamDormon authored Feb 10, 2022
2 parents a05bc52 + d206616 commit f764e2f
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 116 deletions.
36 changes: 8 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ React / Typescript Catalogue for PDM, complete with test driving and purchasing
- Buy vehicles from the catalogue
- Finance vehicles
- View Outstanding Balances neatly organised in a menu
- Choose custom RGB colours for your vehicles

## Instalation
Download the latest version from the releases. Note that the master branch is not considered the most stable branch and you should not build from master unless you know what you're doing.
Expand All @@ -34,9 +35,7 @@ CREATE TABLE `vehicle_finance` (
`warning` TINYINT(4) NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
INDEX `citizenid` (`citizenid`) USING BTREE,
INDEX `plate` (`plate`) USING BTREE,
CONSTRAINT `citizenid` FOREIGN KEY (`citizenid`) REFERENCES `qbcore`.`players` (`citizenid`) ON UPDATE NO ACTION ON DELETE CASCADE,
CONSTRAINT `plate` FOREIGN KEY (`plate`) REFERENCES `qbcore`.`player_vehicles` (`plate`) ON UPDATE NO ACTION ON DELETE CASCADE
INDEX `plate` (`plate`) USING BTREE
) COLLATE='utf8_general_ci' ENGINE=InnoDB AUTO_INCREMENT=1;

```
Expand All @@ -53,6 +52,7 @@ CREATE TABLE `vehicle_finance` (
"time": 120 // Time (in seconds) of the test drive
},
"canbuy": true, // Set to false to disable buying vehicles
"colours": true, // Set to false to disable custom RGB colours
"limit": {
"enabled": true, // Set to true to restrict usage when car dealers are online
"jobname": "cardealer", // Name of car dealer job
Expand All @@ -62,7 +62,8 @@ CREATE TABLE `vehicle_finance` (
"installment_percent": 10, // Percentage cost of finance installments
"runs_on": 1, // The day of the week the installments are taken 1 = monday
"runs_at": "18:30" // The time of day the installments are taken in 24h format
}
},
"qbtarget": true // Enable qb-target by default
}
```

Expand All @@ -71,32 +72,11 @@ This data is matching that of the shared.lua of the offical qbcore repository at

## Usage

To open trigger the event `mojito_pdm:client:open`, you can do this with 3D text, DrawTextUI or qb-target like so:
By default, the resource is configured with qb-target however if you wish to disable this and do it your own way you can do the following:

To open the catalogue trigger the event `mojito_pdm:client:open`
To open the propmt to check finance trigger the event `mojito_pdm:client:check_finance`

```lua
["mojito_pdm"] = {
name="mojito_pdm",
coords=vector3(-55.17767, -1096.946, 26.62873),
radius=0.4,
useZ=true,
options = {
{
type="client",
event="mojito_pdm:client:open",
icon="fas fa-book-open",
label="Open Catalogue"
},
{
type="client",
event="mojito_pdm:client:check_finance",
icon="fas fa-comment-dollar",
label="Check Finance"
}
},
distance=1.0
}
```

## Building

Expand Down
4 changes: 3 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"time": 120
},
"canbuy": true,
"colours": true,
"limit": {
"enabled": false,
"jobname": "cardealer",
Expand All @@ -16,5 +17,6 @@
"installment_percent": 20,
"runs_on": 1,
"runs_at": "18:30"
}
},
"qbtarget": true
}
93 changes: 71 additions & 22 deletions resources/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,38 @@ import { Menu, MenuAlignment, Timerbar, UIMenuItem } from '@nativewrappers/clien
import Config from './config';
import { VehicleProperties } from 'qbcore.js/@types/client';

const exp = global.exports;

if (Config.qbtarget) {
exp['qb-target'].AddCircleZone(
'mojito_pdm',
{ x: -55.17767, y: -1096.946, z: 26.62873 },
0.4,
{
name: 'mojito_pdm',
useZ: true,
debugPoly: false,
},
{
options: [
{
type: 'client',
event: 'mojito_pdm:client:open',
icon: 'fas fa-book-open',
label: 'Open Catalogue',
},
{
type: 'client',
event: 'mojito_pdm:client:check_finance',
icon: 'fas fa-comment-dollar',
label: 'Check Finance',
},
],
distance: 1.0,
},
);
}

on('mojito_pdm:client:open', async () => {
const serverResp = await utils.emitNetPromise<ServerPromiseResp<number>>('fetch:pdm_online', {});
if (Config.limit.enabled && serverResp.data > Config.limit.count)
Expand Down Expand Up @@ -43,11 +75,19 @@ onNet('mojito_pdm:client:start_testdrive', (time: number) => {
}, 1000);
});

RegisterNuiCB('fetch:canbuy', async (data, cb) => {
cb(Config.canbuy);
RegisterNuiCB('fetchconfig', async (data, cb) => {
cb({
buy: Config.canbuy,
colours: Config.colours
});
});

RegisterNuiCB('buy_vehicle', async (data, cb) => {
interface IVehicleBoughtCB {
vehicle: string;
colour: RgbColour | null;
}

RegisterNuiCB<IVehicleBoughtCB>('buy_vehicle', async (data, cb) => {
const { vehicle, colour } = data;

if (!QBCore.Shared.Vehicles[vehicle]) {
Expand Down Expand Up @@ -80,23 +120,27 @@ interface RgbColour {
interface incommingVehicleBought {
vehicle: string;
plate: string;
colour: RgbColour;
colour: RgbColour | null;
}

utils.registerRPCListener<incommingVehicleBought>(
'mojito_pdm:client:vehiclebought',
async (data) => {
const properties: Promise<VehicleProperties> = new Promise((resolve) => {
const { r, g, b } = data.colour;


QBCore.Functions.SpawnVehicle(
data.vehicle,
(veh: number) => {
SetEntityHeading(veh, Config.buylocation.h);
SetVehicleNumberPlateText(veh, data.plate);
SetEntityAsMissionEntity(veh, true, true);
SetPedIntoVehicle(PlayerPedId(), veh, -1);
SetVehicleCustomPrimaryColour(veh, r, g, b);
SetVehicleCustomSecondaryColour(veh, r, g, b);
if (data.colour) {
const { r, g, b } = data.colour;
SetVehicleCustomPrimaryColour(veh, r, g, b);
SetVehicleCustomSecondaryColour(veh, r, g, b);
}
global.exports['LegacyFuel'].SetFuel(veh, 100);
emit('vehiclekeys:client:SetOwner', data.plate);

Expand All @@ -113,26 +157,32 @@ utils.registerRPCListener<incommingVehicleBought>(
interface IFinanceCB {
vehicle: string;
downpayPercent: number;
colour: RgbColour;
colour: RgbColour | null;
}

RegisterNuiCB<IFinanceCB>('finance_vehicle', (data, cb) => {
interface FinanceResp {
msg: string;
vehicleName: string;
interest: number;
outstanding: number;
}

RegisterNuiCB<IFinanceCB>('finance_vehicle', async (data, cb) => {
const { vehicle, downpayPercent, colour } = data;
if (!QBCore.Shared.Vehicles[vehicle])
return QBCore.Functions.Notify('This vehicle does not appear to exist', 'error');
emitNet('mojito_pdm:server:finance_vehicle', vehicle, downpayPercent, colour);

cb({});
});

interface IncommingFinanceMail {
vehicleName: string;
interest: number;
outstanding: number;
}
const resp = await utils.emitNetPromise<ServerPromiseResp<FinanceResp>>(
'mojito_pdm:server:finance_vehicle',
{ vehicle, downpayPercent, colour },
);
const { vehicleName, interest, outstanding } = resp.data;
const success = resp.status === 'ok';

onNet('mojito_pdm:client:financed_vehicle_mail', (data: IncommingFinanceMail) => {
const { vehicleName, interest, outstanding } = data;
const type: string = success ? 'success' : 'error';
QBCore.Functions.Notify(resp.data.msg, type);
if (!success) return;

emitNet('qb-phone:server:sendNewMail', {
sender: 'Premium Deluxue Motorsport',
Expand All @@ -144,6 +194,8 @@ onNet('mojito_pdm:client:financed_vehicle_mail', (data: IncommingFinanceMail) =>
Los Santos Finance Ltd.
`,
});

cb({});
});

interface FinancedVehicles {
Expand All @@ -153,9 +205,6 @@ interface FinancedVehicles {
}

on('mojito_pdm:client:check_finance', async () => {
// const plate = await utils.TakePlateInput();
// emitNet('mojito_pdm:server:check_finance', plate);

const MENU = new Menu('PDM Finance Ltd', 'Check your outstanding balances');
MENU.Alignment = MenuAlignment.Right;

Expand Down
66 changes: 47 additions & 19 deletions resources/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ interface RgbColour {

interface incommingBuyVeh {
vehicle: string;
colour: RgbColour;
colour: RgbColour | null
}

interface outgoingBuyVeh {
Expand Down Expand Up @@ -185,38 +185,62 @@ utils.onNetPromise<null, number>('fetch:pdm_online', (req, res) => {
interface IInterest {
[key: number]: number;
}

const interestRates: IInterest = {
10: 20,
20: 15,
30: 10,
40: 5,
};

onNet(
interface FinanceIncomming {
vehicle: string;
downpayPercent: number;
colour: RgbColour | null;
}

interface FinanceResp {
msg: string;
vehicleName?: string;
interest?: number;
outstanding?: number;
}

utils.onNetPromise<FinanceIncomming, FinanceResp>(
'mojito_pdm:server:finance_vehicle',
async (spawncode: string, downpayPercent: number, colour: RgbColour) => {
const { price, name, brand } = QBCore.Shared.Vehicles[spawncode];
async (req, res) => {
const { vehicle, downpayPercent, colour } = req.data;

if (!QBCore.Shared.Vehicles[vehicle]) {
return res({
data: { msg: 'Vehicle does not exist' },
status: 'error',
});
}

const { price, name, brand } = QBCore.Shared.Vehicles[vehicle];

const downpay = Math.round(price * (downpayPercent / 100));
const interestPercent = interestRates[downpayPercent];
const src = global.source;
const src = req.source;

const Player = QBCore.Functions.GetPlayer(src);
const { bank } = Player.PlayerData.money;

if (bank - downpay <= 0) {
return emitNet(
'QBCore:Notify',
src,
'You have insufficient funds to finance this vehicle',
'error',
);
return res({
status: 'error',
data: {
msg: 'You have insufficient funds to finance this vehicle',
},
});
}

Player.Functions.RemoveMoney('bank', downpay, 'finance-vehicle');

const plate = await utils.GeneratePlate();
const mods = await utils.callClientRPC('mojito_pdm:client:vehiclebought', src, {
vehicle: spawncode,
vehicle: vehicle,
plate: plate,
colour: colour,
});
Expand All @@ -226,8 +250,8 @@ onNet(
[
Player.PlayerData.license,
Player.PlayerData.citizenid,
spawncode,
GetHashKey(spawncode),
vehicle,
GetHashKey(vehicle),
JSON.stringify(mods),
plate,
0,
Expand All @@ -238,7 +262,7 @@ onNet(

global.exports.oxmysql.insert(
'INSERT INTO vehicle_finance (plate, citizenid, model, interest_rate, outstanding_bal) VALUES (?, ?, ?, ?, ?)',
[plate, Player.PlayerData.citizenid, spawncode, interestPercent, outstandingBal],
[plate, Player.PlayerData.citizenid, vehicle, interestPercent, outstandingBal],
);

emit(
Expand All @@ -251,10 +275,14 @@ onNet(
)}** financed a ${name} ${brand}: \n Downpay: ${downpay} \n Interest Rate: ${interestPercent}`,
);

emitNet('mojito_pdm:client:financed_vehicle_mail', src, {
vehicleName: `${brand} ${name}`,
outstanding: outstandingBal,
interest: interestPercent,
return res({
status: 'ok',
data: {
msg: 'You have successfully financed this vehicle',
vehicleName: `${brand} ${name}`,
outstanding: outstandingBal,
interest: interestPercent,
},
});
},
);
Expand Down
2 changes: 2 additions & 0 deletions resources/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export interface IConfig {
buylocation: Vector;
temporary: ITemporary;
canbuy: boolean;
colours: boolean;
limit: ILimit;
finance: IFinance;
qbtarget: boolean;
}
Loading

0 comments on commit f764e2f

Please sign in to comment.