UNPKG

@nativewrappers/client

Version:

Javascript/Typescript wrapper for the FiveM natives

727 lines (726 loc) 26.7 kB
import { Model, Prop } from './'; import { Blip } from './Blip'; import { Camera } from './Camera'; import { CameraTypes, CloudHat, Weather, } from './enums'; import { GameplayCamera } from './GameplayCamera'; import { VehicleHash } from './hashes'; import { Ped, Vehicle } from './models'; import { Pickup } from './Pickup'; import { RaycastResult } from './Raycast'; import { Rope } from './Rope'; import { Maths, Vector3, Wait } from './utils'; /** * Class with common world manipulations. * * This class includes methods for creating entities and common world rendering. * * You can create blips, entities, cameras and more. * * @abstract */ export class World { /** * Get the current camera that's rendering. * * @returns The camera that's currently used. */ static get RenderingCamera() { return new Camera(GetRenderingCam()); } /** * Set the rendering camera. World.RenderingCamera = null to reset. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446); * const myCamera = World.createCamera(position, new Vector3(0,0,0), 180); * World.RenderingCamera = myCamera; * * // Reset to default cam * World.RenderingCamera = null; * ``` * * @param value The camera to render. */ static set RenderingCamera(value) { if (value === null) { RenderScriptCams(false, false, 3000, true, false); } else { value.IsActive = true; RenderScriptCams(true, false, 3000, true, false); } } /** * Whether to create a network world state for Ropes * This currently does nothing */ static set RopesCreateNetworkWorldState(value) { SetRopesCreateNetworkWorldState(value); } /** * Get the current date in the world. * * @returns The current date. */ static get CurrentDate() { const year = GetClockYear(); const month = GetClockMonth(); const day = GetClockDayOfMonth(); const hour = GetClockHours(); const minutes = GetClockMinutes(); const seconds = GetClockSeconds(); return new Date(year, month, day, hour, minutes, seconds); } /** * Set the current date of the world. */ static set CurrentDate(date) { SetClockDate(date.getDate(), date.getMonth(), date.getFullYear()); NetworkOverrideClockTime(date.getHours(), date.getMinutes(), date.getSeconds()); } /** * Disables all emissive textures, street/building/vehicle lights. "EMP" effect. * * @param value On or off. */ static set Blackout(value) { SetBlackout(value); } /** * Get the current cloud hat. * * @returns The current cloud hat type. */ static get CloudHat() { return this.currentCloudHat; } /** * Set the current cloud hat. * * @param value The type of cloud hat. */ static set CloudHat(value) { this.currentCloudHat = value; if (this.currentCloudHat === CloudHat.Unknown) { this.currentCloudHat = CloudHat.Clear; ClearCloudHat(); return; } SetCloudHatTransition(this.cloudHatDict.get(this.currentCloudHat) ?? '', 3); } /** * Get the opacity of current cloud hat. Value is between 0-1. * * @returns The current cloud opacity between 0.0 and 1.0 */ static get CloudHatOpacity() { return GetCloudHatOpacity(); } /** * Set opacity of current cloud hat between 0-1. * * @param value Opacity between 0.0 and 1.0 */ static set CloudHatOpacity(value) { SetCloudHatOpacity(Maths.clamp(value, 0, 1)); } /** * Get the current weather type. * * @returns The current type of weather. */ static get Weather() { switch (GetPrevWeatherTypeHashName()) { case -1750463879: return Weather.ExtraSunny; case 916995460: return Weather.Clear; case -1530260698: return Weather.Neutral; case 282916021: return Weather.Smog; case -1368164796: return Weather.Foggy; case 821931868: return Weather.Clouds; case -1148613331: return Weather.Overcast; case 1840358669: return Weather.Clearing; case 1420204096: return Weather.Raining; case -1233681761: return Weather.ThunderStorm; case 669657108: return Weather.Blizzard; case -273223690: return Weather.Snowing; case 603685163: return Weather.Snowlight; case -1429616491: return Weather.Christmas; case -921030142: return Weather.Halloween; default: return Weather.Unknown; } } /** * Set the current weather. * * @param value Type of weather to set. */ static set Weather(value) { if (value !== Weather.Unknown) { const weather = this.weatherDict[value]; SetWeatherTypeOverTime(weather, 1); setTimeout(() => { SetWeatherTypeNow(weather); }, 100); } } /** * Get the next weather type. * * @returns The Weather type */ static get NextWeather() { switch (GetNextWeatherTypeHashName()) { case -1750463879: return Weather.ExtraSunny; case 916995460: return Weather.Clear; case -1530260698: return Weather.Neutral; case 282916021: return Weather.Smog; case -1368164796: return Weather.Foggy; case 821931868: return Weather.Clouds; case -1148613331: return Weather.Overcast; case 1840358669: return Weather.Clearing; case 1420204096: return Weather.Raining; case -1233681761: return Weather.ThunderStorm; case 669657108: return Weather.Blizzard; case -273223690: return Weather.Snowing; case 603685163: return Weather.Snowlight; case -1429616491: return Weather.Christmas; case -921030142: return Weather.Halloween; default: return Weather.Unknown; } } /** * Set weather type instantly. Similar to World.transitionToWeather with duration 0. */ static set NextWeather(value) { if (value !== Weather.Unknown) { const weather = this.weatherDict[value]; SetWeatherTypeOverTime(weather, 0); } } /** * Doesn't work */ static get WeatherTransition() { const transition = GetWeatherTypeTransition(); return [this.weatherDict[transition[0]], this.weatherDict[transition[1]], transition[2]]; } /** * Doesn't work */ static set WeatherTransition(transition) { SetWeatherTypeTransition(transition[0], transition[1], transition[2]); } /** * Transition to different weather type within a certain time. * * @param weather Weather type to change to. * @param duration Time for full weather change (in milliseconds); */ static transitionToWeather(weather, duration) { if (weather !== Weather.Unknown) { SetWeatherTypeOverTime(this.weatherDict[weather], duration); } } /** * Destroys all existing cameras and sets your rendering camera back to GameplayCam. */ static destroyAllCameras() { DestroyAllCams(false); } /** * Creates a blip at a given position and optionally radius. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446); * const myStoreBlip = World.createBlip(position, 5.0); * myStoreBlip.Sprite = BlipSprite.Store; * ``` * * @param position World coordinate of blip. * @param radius (Optional) Radius of where blip should be shown. * @returns Blip object. */ static createBlip(position, radius) { if (radius !== null && radius !== undefined) { return new Blip(AddBlipForRadius(position.x, position.y, position.z, radius)); } return new Blip(AddBlipForCoord(position.x, position.y, position.z)); } /** * Creates a cam that defaults to {@link CameraTypes.Scripted} * * ```ts * const cam = World.createCamera(CameraTypes.Spline, true); * ``` * @param cameraType the camera type to create * @param active unknown * @returns */ static createCamera(cameraType = CameraTypes.Scripted, active = true) { return new Camera(CreateCam(cameraType, active)); } /** * Creates a camera using 'DEFAULT_SCRIPTED_CAMERA'. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446); * const myCamera = World.createCameraWithParams(position, new Vector3(0,0,0), 180); * ``` * * @param position World coordinate where the camera should render. * @param rotation Rotation of camera relative to world. * @param fieldOfView Field of view angle of camera. * @returns Camera object. */ static createCameraWithParams(cameraType = CameraTypes.Scripted, position, rotation, fieldOfView) { return new Camera(CreateCamWithParams(cameraType, position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, fieldOfView, true, 2)); } /** * Create a ped at a desired location. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446); * const model = new Model("a_f_m_beach_01"); * const myPed = await World.createPed(model, position); * ``` * * @param model Ped model to be spawned. * @param position World position (coordinates) of Ped spawn. * @param heading Heading of Ped when spawning. * @param isNetwork * @returns Ped object. */ static async createPed(model, position, heading = 0, isNetwork = true) { if (!model.IsPed || !(await model.request(1000))) { return null; } return new Ped(CreatePed(26, model.Hash, position.x, position.y, position.z, heading, isNetwork, false)); } /** * Creates a [[`Ped`]] with a random model. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446); * const randomPed = World.createRandomPed(position); * ``` * * @param position World coordinate of Ped spawn. * @returns Ped object. */ static createRandomPed(position) { return new Ped(CreateRandomPed(position.x, position.y, position.z)); } /** * Create a vehicle at a desired location. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446); * const model = new Model("adder"); * const myVehicle = await World.createVehicle(model, position); * ``` * * @param model Vehicle model to be spawned. * @param position World position (coordinates) of Vehicle spawn. * @param heading Heading of Vehicle when spawning. * @param isNetwork * @returns Vehicle object. */ static async createVehicle(model, position, heading = 0, isNetwork = true) { if (!model.IsVehicle || !(await model.request(1000))) { return null; } return new Vehicle(CreateVehicle(model.Hash, position.x, position.y, position.z, heading, isNetwork, false)); } /** * Create a random vehicle at a desired location. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446); * const randomVehicle = await World.createRandomVehicle(position); * ``` * * @param position World position (coordinates) of Vehicle spawn. * @param heading Heading of Vehicle when spawning. * @param isNetwork * @returns Vehicle object. */ static async createRandomVehicle(position, heading = 0, isNetwork = true) { const vehicleCount = Object.keys(VehicleHash).length / 2; // check const randomIndex = Maths.getRandomInt(0, vehicleCount); const randomVehicleName = VehicleHash[randomIndex]; const modelHash = GetHashKey(randomVehicleName); const model = new Model(modelHash); if (!model.IsVehicle || !(await model.request(1000))) { return null; } return new Vehicle(CreateVehicle(model.Hash, position.x, position.y, position.z, heading, isNetwork, false)); } /* * Creates a rope at the specified location. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446) * const rotation = new Vector3(0,0,0) * const rope = await World.createRope(position, rotation, 15.0, RopeType.ThickRope, 3.0, 0.5); * ``` * * You should manually call `RopeUnloadTextures()` after you finish using **all** ropes, unlike models requesting rope models is instantaneous * If called with collisionOn you will have to LoadRopeData after */ static async createRope(position, rotation, maxLength, ropeType, initLength, minLength, lengthChangeRate = 1.0, onlyPPU = false, collisionOn = false, lockFromFront = false, timeMultiplier = 1.0, breakable = false, shouldLoadTextures = true) { if (shouldLoadTextures) { if (!RopeAreTexturesLoaded()) { RopeLoadTextures(); } while (!RopeAreTexturesLoaded()) { await Wait(0); } } const [ropeHandle] = AddRope(position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, maxLength, ropeType, initLength, minLength, lengthChangeRate, onlyPPU, collisionOn, lockFromFront, timeMultiplier, breakable); return new Rope(ropeHandle); } /** * Spawns a [[`Prop`]] at the given position. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446); * const model = new Model("prop_barrel_02a"); * const myBarrelProp = await World.createProp(model, position, false, true); * ``` * * @param model The [[`Model`]] to spawn (must be a Prop) * @param position Location of Prop * @param dynamic If set to true, the Prop will have physics otherwise it's static. * @param placeOnGround If set to true, sets the Prop on the ground nearest to position. * @param isNetwork * @returns Prop object. */ static async createProp(model, position, dynamic, placeOnGround, isNetwork = true) { if (!model.IsProp || !(await model.request(1000))) { return null; } const prop = new Prop(CreateObject(model.Hash, position.x, position.y, position.z, isNetwork, true, dynamic)); if (placeOnGround) { prop.placeOnGround(); } return prop; } /** * Create a pickup in a specific position in the world with a specified type and value. * * @param type The [[`PickupType`]] of pickup. * @param position The position in the world it should be spawned. * @param model The model of the spawned pickup. * @param value Give a value for the pickup when picked up. * @param rotation If set, create a rotating pickup with this rotation. * @returns Pickup object. */ static async CreatePickup(type, position, model, value, rotation) { if (!(await model.request(1000))) { return null; } let handle = 0; if (rotation !== undefined) handle = CreatePickupRotate(type, position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, 0, value, 2, true, model.Hash); else handle = CreatePickup(type, position.x, position.y, position.z, 0, value, true, model.Hash); if (handle === 0) { return null; } return new Pickup(handle); } /** * Creates an ambient pickup. * * @param type The [[`PickupType`]] of the pickup. * @param position The position where it should be spawned. * @param model The model. * @param value The value tied to the pickup. * @returns The pickup in form of a Prop. */ static async CreateAmbientPickup(type, position, model, value) { if (!(await model.request(1000))) { return null; } const handle = CreateAmbientPickup(type, position.x, position.y, position.z, 0, value, model.Hash, false, true); if (handle === 0) { return null; } return new Prop(handle); } /** * Draw a marker at a desired location. Careful! Must be drawn every tick. * * ```typescript * const position = new Vector3(-802.311, 175.056, 72.8446); * const zeroVector = new Vector3(0,0,0); * * setTick(() => { * World.drawMarker(MarkerType.ThickChevronUp, position, zeroVector, zeroVector, 1.0, new Color(255,0,0)); * }) * ``` * * @param type Type of marker. * @param position Location of marker. * @param direction Direction facing. * @param rotation World rotation. * @param scale Size of marker. * @param color Color of marker. * @param bobUpAndDown Animated movement along marker's own X axis. * @param faceCamera Rendering marker facing rendering camera. * @param rotateY Rotate along Y axis. * @param textureDict Custom texture dictionary for custom marker. * @param textureName Custom texture name for custom marker. * @param drawOnEntity Render the marker on an entity. */ static drawMarker(type, position, direction, rotation, scale, color, bobUpAndDown = false, faceCamera = false, rotateY = false, textureDict = null, textureName = null, drawOnEntity = false) { DrawMarker(Number(type), position.x, position.y, position.z, direction.x, direction.y, direction.z, rotation.x, rotation.y, rotation.z, scale.x, scale.y, scale.z, color.r, color.g, color.b, color.a, bobUpAndDown, faceCamera, 2, rotateY, textureDict, textureName, drawOnEntity); } /** * Creates a light in the world with a certain length (range). * * @param pos World coordinate where to draw the light. * @param color RGB colors of the light. * @param range How far to draw the light. * @param intensity Intensity of the light ("alpha"). */ static drawLightWithRange(pos, color, range, intensity) { DrawLightWithRange(pos.x, pos.y, pos.z, color.r, color.g, color.b, range, intensity); } /** * Creates a light in the world. More configurable than World.drawLightWithRange. * * @param pos World coordinate of spotlight. * @param dir Direction to face spotlight. * @param color RGB colors of spotlight. * @param distance The maximum distance the spotlight can reach. * @param brightness Brightness of the spotlight. * @param roundness "Smoothness" of the edge of the spotlight. * @param radius Radius size of spotlight. * @param fadeOut Falloff size of the spotlight's edge. */ static drawSpotLight(pos, dir, color, distance, brightness, roundness, radius, fadeOut) { DrawSpotLight(pos.x, pos.y, pos.z, dir.x, dir.y, dir.z, color.r, color.g, color.b, distance, brightness, roundness, radius, fadeOut); } /** * Creates a light in the world. Same as World.drawSpotlight, but also draws shadows. * * @param pos World coordinate of spotlight. * @param dir Direction to face spotlight. * @param color RGB colors of spotlight. * @param distance The maximum distance the spotlight can reach. * @param brightness Brightness of the spotlight. * @param roundness "Smoothness" of the edge of the spotlight. * @param radius Radius size of spotlight. * @param fadeOut Falloff size of the spotlight's edge. */ static drawSpotLightWithShadow(pos, dir, color, distance, brightness, roundness, radius, fadeOut) { DrawSpotLightWithShadow(pos.x, pos.y, pos.z, dir.x, dir.y, dir.z, color.r, color.g, color.b, distance, brightness, roundness, radius, fadeOut, 0); } /** * Draws a line in the world. It's not possible to change thickness. * * @param start World coordinate of start position of line. * @param end World coordinate of end position of line. * @param color RGB color of line. */ static drawLine(start, end, color) { DrawLine(start.x, start.y, start.z, end.x, end.y, end.z, color.r, color.g, color.b, color.a); } /** * Draw polygon in the world. * * @param vertexA World coordinate of first point. * @param vertexB World coordinate of second point. * @param vertexC World coordinate of third point. * @param color RGB color of polygon. */ static drawPoly(vertexA, vertexB, vertexC, color) { DrawPoly(vertexA.x, vertexA.y, vertexA.z, vertexB.x, vertexB.y, vertexB.z, vertexC.x, vertexC.y, vertexC.z, color.r, color.g, color.b, color.a); } /** * Cast ("shoot") a ray in a certain direction to detect entities in the way. * * @param source Starting position of raycast. * @param direction Direction to cast a ray to. * @param maxDistance Max distance to cast the ray. * @param options Possible entity types to detect. * @param ignoreEntity An entity to ignore (usually player's Ped). * @returns RaycastResult object. */ static raycast(source, direction, maxDistance, options, ignoreEntity) { const target = Vector3.add(source, Vector3.multiply(direction, maxDistance)); return new RaycastResult(StartExpensiveSynchronousShapeTestLosProbe(source.x, source.y, source.z, target.x, target.y, target.z, Number(options), ignoreEntity.Handle, 7)); } /** * Cast a ray from the local players camera until it hits an entity * * @param maxDistance Max distance to cast the ray. * @param options Possible entity types to detect. * @returns RaycastResult object. */ static raycastPlayerCamera(maxDistance, options) { const camera = GameplayCamera.Position; const direction = GameplayCamera.ForwardVector; const destination = direction.multiply(maxDistance).add(camera); return new RaycastResult(StartExpensiveSynchronousShapeTestLosProbe(camera.x, camera.y, camera.z, destination.x, destination.y, destination.z, Number(options), PlayerPedId(), 7)); } /** * Gets the closest object of this model */ static getClosestObject(model, coords, radius = 25.0, isMission = false) { const prop = GetClosestObjectOfType(coords.x, coords.y, coords.z, radius, model.Hash, isMission, false, false); if (prop !== 0) { return new Prop(prop); } return null; } /** * Get all [[`Prop`]] entities in your own scope. * * @returns Array of Props. */ static getAllProps() { const handles = GetGamePool('CObject'); const props = []; handles.forEach(handle => props.push(new Prop(handle))); return props; } /** * Get all [[`Rope`]] entities in your own scope. * * @returns Array of Ropes. */ static getAllRopes() { const handles = GetAllRopes(); const props = []; handles.forEach(handle => props.push(new Rope(handle))); return props; } /** * Get all [[`Ped`]] entities in your own scope. * * @returns Array of Peds. */ static getAllPeds() { const handles = GetGamePool('CPed'); const peds = []; handles.forEach(handle => peds.push(new Ped(handle))); return peds; } /** * Get all [[`Vehicle`]] entities in your own scope. * * @returns Array of Vehicles. */ static getAllVehicles() { const handles = GetGamePool('CVehicle'); const vehicles = []; handles.forEach(handle => vehicles.push(new Vehicle(handle))); return vehicles; } /** * Gets the cloest [[`Vehicle`]] to the current coords, or null if none are found * @returns the closest vehicle or null */ static getClosestVehicle(coords) { const vehicles = this.getAllVehicles(); let currentVeh = null; let lastDistance = 9999.0; for (const vehicle of vehicles) { if (!currentVeh) { currentVeh = vehicle; lastDistance = coords.distance(vehicle.Position); continue; } const distance = coords.distance(vehicle.Position); if (distance < lastDistance) { currentVeh = vehicle; lastDistance = distance; } } return currentVeh; } /** * Get all [[`Pickup`]] entities using the GetGamePool. * @returns Array of Pickups. */ static getAllPickups() { const handles = GetGamePool('CPickup'); const pickups = []; handles.forEach(handle => pickups.push(new Pickup(handle))); return pickups; } } World.currentCloudHat = CloudHat.Clear; World.cloudHatDict = new Map([ [CloudHat.Unknown, 'Unknown'], [CloudHat.Altostratus, 'altostratus'], [CloudHat.Cirrus, 'Cirrus'], [CloudHat.Cirrocumulus, 'cirrocumulus'], [CloudHat.Clear, 'Clear 01'], [CloudHat.Cloudy, 'Cloudy 01'], [CloudHat.Contrails, 'Contrails'], [CloudHat.Horizon, 'Horizon'], [CloudHat.HorizonBand1, 'horizonband1'], [CloudHat.HorizonBand2, 'horizonband2'], [CloudHat.HorizonBand3, 'horizonband3'], [CloudHat.Horsey, 'horsey'], [CloudHat.Nimbus, 'Nimbus'], [CloudHat.Puffs, 'Puffs'], [CloudHat.Rain, 'RAIN'], [CloudHat.Snowy, 'Snowy 01'], [CloudHat.Stormy, 'Stormy 01'], [CloudHat.Stratoscumulus, 'stratoscumulus'], [CloudHat.Stripey, 'Stripey'], [CloudHat.Shower, 'shower'], [CloudHat.Wispy, 'Wispy'], ]); World.weatherDict = [ 'EXTRASUNNY', 'CLEAR', 'CLOUDS', 'SMOG', 'FOGGY', 'OVERCAST', 'RAIN', 'THUNDER', 'CLEARING', 'NEUTRAL', 'SNOW', 'BLIZZARD', 'SNOWLIGHT', 'XMAS', ];