UNPKG

@nativewrappers/client

Version:

Javascript/Typescript wrapper for the FiveM natives

447 lines (446 loc) 15.1 kB
import { Blip } from '../Blip'; import { ForceType } from '../enums'; import { Game } from '../Game'; import { Model } from '../Model'; import { Quaternion, Vector3 } from '../utils'; import { EntityBoneCollection, Ped, Prop, Vehicle } from './'; import cfx from '../cfx'; export class Entity { constructor(handle) { this.stateBagCookies = []; this.handle = handle; } static fromHandle(handle) { switch (GetEntityType(handle)) { case 1: return new Ped(handle); case 2: return new Vehicle(handle); case 3: return new Prop(handle); default: return null; } } static fromNetworkId(networkId) { return this.fromHandle(NetworkGetEntityFromNetworkId(networkId)); } get Handle() { return this.handle; } /** * @returns if the entity is a networked entity or local entity */ get IsNetworked() { return NetworkGetEntityIsNetworked(this.handle); } set IsNetworked(networked) { if (networked) { NetworkRegisterEntityAsNetworked(this.handle); } else { NetworkUnregisterNetworkedEntity(this.handle); } } get NetworkId() { return NetworkGetNetworkIdFromEntity(this.handle); } get IsNetworkConcealed() { return NetworkIsEntityConcealed(this.handle); } set IsNetworkConcealed(concealed) { NetworkConcealEntity(this.handle, concealed); } get State() { return cfx.Entity(this.handle).state; } AddStateBagChangeHandler(keyFilter, handler) { const stateBagName = this.IsNetworked ? `entity:${this.NetworkId}` : `localEntity:${this.handle}`; // keyFilter is casted to any because it can take a null value. /* eslint-disable @typescript-eslint/no-explicit-any */ const cookie = AddStateBagChangeHandler(keyFilter, stateBagName, handler); this.stateBagCookies.push(cookie); return cookie; } /** * A short hand function for AddStateBagChangeHandler, this gets automatically cleaned up on entity deletion. * @param keyFilter the key to filter for or null * @param handler the function to handle the change * @returns a cookie to be used in RemoveStateBagChangeHandler */ listenForStateChange(keyFilter, handler) { return this.AddStateBagChangeHandler(keyFilter, handler); } removeStateListener(tgtCookie) { this.stateBagCookies = this.stateBagCookies.filter(cookie => { const isCookie = cookie == tgtCookie; if (isCookie) RemoveStateBagChangeHandler(cookie); return isCookie; }); } get Owner() { return NetworkGetEntityOwner(this.handle); } isPlayerOwner(player) { return this.Owner === player.Handle; } get Speed() { return GetEntitySpeed(this.handle); } getSpeedVector(isRelative = false) { return Vector3.fromArray(GetEntitySpeedVector(this.handle, isRelative)); } get ForwardVector() { return Vector3.fromArray(GetEntityForwardVector(this.handle)); } get Matrix() { return Vector3.fromArrays(GetEntityMatrix(this.handle)); } set Matrix(vectors) { if (vectors.length !== 4) throw Error(`Expected 4 Vectors, got ${vectors.length}`); const [forward, right, up, pos] = vectors; SetEntityMatrix(this.handle, forward.x, forward.y, forward.z, right.x, right.y, right.z, up.x, up.y, up.z, pos.x, pos.y, pos.z); } get Health() { return GetEntityHealth(this.handle); } set Health(amount) { SetEntityHealth(this.handle, amount); } get MaxHealth() { return GetEntityMaxHealth(this.handle); } set MaxHealth(amount) { SetEntityMaxHealth(this.handle, amount); } set IsDead(value) { if (value) { SetEntityHealth(this.handle, 0); } else { SetEntityHealth(this.handle, 200); } } get IsDead() { return IsEntityDead(this.handle); } get IsAlive() { return !IsEntityDead(this.handle); } /** * @deprecated use [[IsDead]] instead */ isDead() { return IsEntityDead(this.handle); } /** * @deprecated use [[IsAlive]] instead */ isAlive() { return !this.isDead(); } get Model() { return new Model(GetEntityModel(this.handle)); } /** * Returns if the entity is set as a mission entity and will not be cleaned up by the engine */ get IsMissionEntity() { return IsEntityAMissionEntity(this.handle); } /** * Sets if the entity is a mission entity and will not be cleaned up by the engine */ set IsMissionEntity(value) { if (value) { SetEntityAsMissionEntity(this.handle, false, false); } else { SetEntityAsNoLongerNeeded(this.handle); } } get Position() { return Vector3.fromArray(GetEntityCoords(this.handle, false)); } set Position(position) { SetEntityCoords(this.handle, position.x, position.y, position.z, false, false, false, true); } set PositionNoOffset(position) { SetEntityCoordsNoOffset(this.handle, position.x, position.y, position.z, true, true, true); } get Rotation() { return Vector3.fromArray(GetEntityRotation(this.handle, 2)); } set Rotation(rotation) { SetEntityRotation(this.handle, rotation.x, rotation.y, rotation.z, 2, true); } get Quaternion() { const quaternion = GetEntityQuaternion(this.handle); return new Quaternion(quaternion[0], quaternion[1], quaternion[2], quaternion[3]); } set Quaternion(quaternion) { SetEntityQuaternion(this.handle, quaternion.x, quaternion.y, quaternion.z, quaternion.w); } get Heading() { return GetEntityHeading(this.handle); } set Heading(heading) { SetEntityHeading(this.handle, heading); } get IsPositionFrozen() { return IsEntityPositionFrozen(this.handle); } set IsPositionFrozen(value) { FreezeEntityPosition(this.handle, value); } get Velocity() { return Vector3.fromArray(GetEntityVelocity(this.handle)); } set Velocity(velocity) { SetEntityVelocity(this.handle, velocity.x, velocity.y, velocity.z); } get RotationVelocity() { return Vector3.fromArray(GetEntityRotationVelocity(this.handle)); } set MaxSpeed(value) { SetEntityMaxSpeed(this.handle, value); } set HasGravity(value) { SetEntityHasGravity(this.handle, value); } get HeightAboveGround() { return GetEntityHeightAboveGround(this.handle); } get SubmersionLevel() { return GetEntitySubmergedLevel(this.handle); } get LodDistance() { return GetEntityLodDist(this.handle); } set LodDistance(value) { SetEntityLodDist(this.handle, value); } get IsVisible() { return IsEntityVisible(this.handle); } set IsVisible(value) { SetEntityVisible(this.handle, value, false); } get IsOccluded() { return IsEntityOccluded(this.handle); } get IsOnScreen() { return IsEntityOnScreen(this.handle); } get IsUpright() { return IsEntityUpright(this.handle, 0); } get IsUpsideDown() { return IsEntityUpsidedown(this.handle); } get IsInAir() { return IsEntityInAir(this.handle); } get IsInWater() { return IsEntityInWater(this.handle); } /** * @deprecated use [[IsMissionEntity]] instead as its more obvious as what it does */ get IsPersistent() { return IsEntityAMissionEntity(this.handle); } /** * @deprecated use [[IsMissionEntity]] instead as its more obvious as what it does */ set IsPersistent(value) { if (value) { SetEntityAsMissionEntity(this.handle, true, false); } else { SetEntityAsNoLongerNeeded(this.handle); } } get IsOnFire() { return IsEntityOnFire(this.handle); } set IsInvincible(value) { SetEntityInvincible(this.handle, value); } set IsOnlyDamagedByPlayer(value) { SetEntityOnlyDamagedByPlayer(this.handle, value); } get Opacity() { return GetEntityAlpha(this.handle); } /** * Sets how transparent an entity is, if you want to reset the alpha level use [[resetOpacity]] instead; */ set Opacity(value) { SetEntityAlpha(this.handle, value, false); } resetOpacity() { ResetEntityAlpha(this.handle); } get HasCollided() { return HasEntityCollidedWithAnything(this.handle); } get MaterialCollidingWith() { return GetLastMaterialHitByEntity(this.handle); } get IsCollisionEnabled() { return !GetEntityCollisonDisabled(this.handle); } set IsCollisionEnabled(value) { SetEntityCollision(this.handle, value, false); } set IsRecordingCollisions(value) { SetEntityRecordsCollisions(this.handle, value); } get Bones() { if (!this.bones) { this.bones = new EntityBoneCollection(this); } return this.bones; } get AttachedBlip() { const handle = GetBlipFromEntity(this.handle); if (DoesBlipExist(handle)) { return new Blip(handle); } return null; } attachBlip() { return new Blip(AddBlipForEntity(this.handle)); } setNoCollision(entity, toggle) { SetEntityNoCollisionEntity(this.handle, entity.Handle, toggle); } hasClearLosToEntity(entity, traceType = 17) { return HasEntityClearLosToEntity(this.handle, entity.Handle, traceType); } hasClearLosToEntityInFront(entity) { return HasEntityClearLosToEntityInFront(this.handle, entity.Handle); } hasBeenDamagedBy(entity) { return HasEntityBeenDamagedByEntity(this.handle, entity.Handle, true); } hasBeenDamagedByWeapon(weapon) { return HasEntityBeenDamagedByWeapon(this.handle, Number(weapon), 0); } hasBeenDamagedByAnyWeapon() { return HasEntityBeenDamagedByWeapon(this.handle, 0, 2); } hasBeenDamagedByAnyMeleeWeapon() { return HasEntityBeenDamagedByWeapon(this.handle, 0, 1); } clearLastWeaponDamage() { ClearEntityLastWeaponDamage(this.handle); } isInArea(minBounds, maxBounds) { return IsEntityInArea(this.handle, minBounds.x, minBounds.y, minBounds.z, maxBounds.x, maxBounds.y, maxBounds.z, false, false, 0); } isInAngledArea(origin, edge, angle) { return IsEntityInAngledArea(this.handle, origin.x, origin.y, origin.z, edge.x, edge.y, edge.z, angle, false, true, 0); } isInRangeOf(position, range) { const v = Vector3.subtract(this.Position, position); return v.dotProduct(v) < range * range; } isNearEntity(entity, bounds) { return IsEntityAtEntity(this.handle, entity.Handle, bounds.x, bounds.y, bounds.z, false, true, 0); } isTouching(entity) { return IsEntityTouchingEntity(this.handle, entity.Handle); } isTouchingModel(model) { return IsEntityTouchingModel(this.handle, model.Hash); } /** * @param offset: the amount to offset from the entity * @returns the offset position from the entity in world coords */ getOffsetPosition(offset) { return Vector3.fromArray(GetOffsetFromEntityInWorldCoords(this.handle, offset.x, offset.y, offset.z)); } getPositionOffset(worldCoords) { return Vector3.fromArray(GetOffsetFromEntityGivenWorldCoords(this.handle, worldCoords.x, worldCoords.y, worldCoords.z)); } attachTo(entity, position, rotation, collisions = false, unk9 = true, useSoftPinning = true, rotationOrder = 1) { if (this.handle == entity.Handle) { throw new Error('You cannot attach an entity to the same entity this will result in a crash!'); } AttachEntityToEntity(this.handle, entity.Handle, -1, position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, unk9, useSoftPinning, collisions, IsEntityAPed(entity.Handle), rotationOrder, true); } /* * Attaches an entity to another entity via a bone * @example * ```typescript * const ply = Game.PlayerPed; * const bag = await World.createProp(new Model('ba_prop_battle_bag_01b'), ply.Position, true, true, true); * bag.attachToBone( * ply.Bones.getBone(64113), * new Vector3(0.12, -0.25, 0.0), * new Vector3(105.0, 50.0, 190.0) * ) * ``` */ attachToBone(entityBone, position, rotation, collisions = false, unk9 = true, useSoftPinning = true, rotationOrder = 1) { if (this.handle == entityBone.Owner.Handle) { throw new Error('You cannot attach an entity to the same entity this will result in a crash!'); } AttachEntityToEntity(this.handle, entityBone.Owner.Handle, entityBone.Index, position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, unk9, useSoftPinning, collisions, IsEntityAPed(entityBone.Owner.Handle), rotationOrder, true); } detach() { DetachEntity(this.handle, true, true); } isAttached() { return IsEntityAttached(this.handle); } isAttachedTo(entity) { return IsEntityAttachedToEntity(this.handle, entity.Handle); } getEntityAttachedTo() { return Entity.fromHandle(GetEntityAttachedTo(this.handle)); } applyForce(direction, rotation, forceType = ForceType.MaxForceRot2) { ApplyForceToEntity(this.handle, Number(forceType), direction.x, direction.y, direction.z, rotation.x, rotation.y, rotation.z, 0, false, true, true, false, true); } applyForceRelative(direction, rotation, forceType = ForceType.MaxForceRot2) { ApplyForceToEntity(this.handle, Number(forceType), direction.x, direction.y, direction.z, rotation.x, rotation.y, rotation.z, 0, true, true, true, false, true); } /** * Removes all particle effects from the entity */ removePtfxEffects() { RemoveParticleFxFromEntity(this.handle); } /** * @deprecated use [[removePtfxEffects]] */ removeAllParticleEffects() { this.removePtfxEffects(); } exists() { return DoesEntityExist(this.handle); } delete() { if (this.handle !== Game.PlayerPed.Handle) { this.IsMissionEntity = true; DeleteEntity(this.handle); for (const cookie of this.stateBagCookies) { RemoveStateBagChangeHandler(cookie); } } } /** * @deprecated use [[IsMissionEntity]] setter as false instead. */ markAsNoLongerNeeded() { SetEntityAsNoLongerNeeded(this.Handle); } }