private static void InteropRemoveChild(object parent, object child) => InteropUtility.Invoke(parent, "removeChild", child);
 private static int InteropGetLength(object nodes) => (int)InteropUtility.PropertyGet(nodes, "length");
 private static void InteropInsertBefore(object parent, object newChild, object refNode) => InteropUtility.Invoke(parent, "insertBefore", newChild, refNode);
 private static void InteropAppendChild(object parent, object child) => InteropUtility.Invoke(parent, "appendChild", child);
 private static int InteropGetNodeType(object node) => (int)InteropUtility.PropertyGet(node, "nodeType");
 private static object InteropGetFirstChild(object node) => InteropUtility.PropertyGet(node, "firstChild");
 private static object InteropGetOwnerDocument(object node) => InteropUtility.PropertyGet(node, "ownerDocument");
 private static object InteropCreateTextNode(object document, string text) => InteropUtility.Invoke(document, "createTextNode", (object)text);
 private static string InteropGetNodeName(object node) => (string)InteropUtility.PropertyGet(node, "nodeName");
 private static object InteropGetNodeValue(object node) => InteropUtility.PropertyGet(node, "nodeValue");
 private static void InteropSetAttribute(object node, string name, object value) => InteropUtility.Invoke(node, "setAttribute", (object)name, value);
        private static string InteropGetAttribute(object node, string name)
        {
            object obj = InteropUtility.Invoke(node, "getAttribute", (object)name);

            return(obj == null || obj == DBNull.Value ? (string)null : obj.ToString());
        }
 private static object InteropSelectSingleNode(object node, string pattern) => InteropUtility.Invoke(node, "selectSingleNode", (object)pattern);
 private static object InteropGetItem(object nodes, int index) => InteropUtility.Invoke(nodes, "item", (object)index);
 private static object InteropCreateProcessingInstruction(object doc, string name, string data) => InteropUtility.Invoke(doc, "createProcessingInstruction", (object)name, (object)data);
            public unsafe void Update()
            {
                var throttle = InteropUtility.ReadFloat(new IntPtr(vehicle.MemoryAddress) + MemoryAccess.ThrottleOffset);

                for (int i = 0; i < numEngines; i++)
                {
                    var backThrustDistance = EngineBackThrustExtremityScalar - 28.0f * (1.0f - throttle);

                    if (size == VehicleSize.Small)
                    {
                        backThrustDistance *= 0.6f;
                    }

                    else if (size == VehicleSize.Big)
                    {
                        backThrustDistance *= 1.4f;
                    }

                    Vector3 leftOffset  = offsets[i];
                    Vector3 rightOffset = new Vector3(-leftOffset.X, leftOffset.Y, leftOffset.Z);
                    Vector3 forwardLeft =
                        vehicle.GetOffsetInWorldCoords(leftOffset + new Vector3(0, EngineThrustExtremityScalar, 0f));
                    Vector3 forwardRight =
                        vehicle.GetOffsetInWorldCoords(rightOffset + new Vector3(0, EngineThrustExtremityScalar, 0f));
                    Vector3 rearLeft =
                        vehicle.GetOffsetInWorldCoords(leftOffset - new Vector3(0, backThrustDistance, 0f));

                    var groundHeightLeft = World.GetGroundHeight(rearLeft);

                    Vector3 rearRight =
                        vehicle.GetOffsetInWorldCoords(rightOffset - new Vector3(0, backThrustDistance, 0f));

                    var groundHeightRight = World.GetGroundHeight(rearRight);

                    float scale = ThrustScale * UserConfig.ThrustMultiplier * throttle, bottomOffset;

                    Vector3 direction = Vector3.Normalize(rearLeft - forwardLeft);

                    if (vehicle.Acceleration < 0.0f ||
                        Marshal.ReadInt16(new IntPtr(vehicle.MemoryAddress) + MemoryAccess.GearOffset) <= 0)
                    {
                        scale     = ReverseThrustScale * UserConfig.ReverseThrustMultiplier * throttle;
                        direction = -direction;
                    }

                    switch (size)
                    {
                    case VehicleSize.Big:
                        bottomOffset = 1.469f;
                        scale       *= 1.32f;
                        break;

                    case VehicleSize.Med:
                        bottomOffset = 1.1f;
                        scale       *= 1.0f;
                        break;

                    default:
                        bottomOffset = 1.0f;
                        scale       *= 0.78f;
                        break;
                    }

                    Entity target;

                    float thrustRadius = 4.4f * UserConfig.ThrustRadius;

                    // left turbine
                    if (DoEntityCapsuleTest(forwardLeft, new Vector3(rearLeft.X, rearLeft.Y, groundHeightLeft),
                                            thrustRadius, vehicle, out target))
                    {
                        ApplyThrustForce(target, forwardLeft, direction, scale);
                    }
                    // right turbine
                    if (DoEntityCapsuleTest(forwardRight, new Vector3(rearRight.X, rearRight.Y, groundHeightRight),
                                            thrustRadius, vehicle, out target))
                    {
                        ApplyThrustForce(target, forwardRight, direction, scale);
                    }
                    // left side bottom
                    if (DoEntityCapsuleTest(forwardLeft - new Vector3(0, 0, bottomOffset),
                                            rearLeft - new Vector3(0, 0, bottomOffset), thrustRadius, vehicle, out target))
                    {
                        ApplyThrustForce(target, forwardLeft, direction, scale);
                    }
                    // right side bottom
                    if (DoEntityCapsuleTest(forwardRight - new Vector3(0, 0, bottomOffset),
                                            rearRight - new Vector3(0, 0, bottomOffset), thrustRadius, vehicle, out target))
                    {
                        ApplyThrustForce(target, forwardRight, direction, scale);
                    }

                    if (hazeFX?.Length > i)
                    {
                        hazeFX[i].SetEvolution("throttle", vehicle.Acceleration);
                    }

                    bool b = Game.IsControlPressed(0, Control.VehicleHandbrake);

                    Function.Call(Hash.SET_VEHICLE_BURNOUT, vehicle, b);

                    Function.Call(Hash.SET_VEHICLE_HANDBRAKE, vehicle, b);

                    if (UserConfig.UseThrottleExhaust && Game.IsControlJustPressed(0, Control.VehicleAccelerate))
                    {
                        Function.Call(Hash.REQUEST_NAMED_PTFX_ASSET, "scr_agencyheist");

                        Function.Call(Hash._SET_PTFX_ASSET_NEXT_CALL, "scr_agencyheist");

                        Function.Call(Hash.SET_PARTICLE_FX_NON_LOOPED_COLOUR, 1.0f, 1.0f, 1.0f);

                        Function.Call(Hash.SET_PARTICLE_FX_NON_LOOPED_ALPHA, 0.6f);

                        Function.Call(Hash.START_PARTICLE_FX_NON_LOOPED_AT_COORD, "scr_agency3a_door_hvy_trig",
                                      forwardLeft.X, forwardLeft.Y, forwardLeft.Z, vehicle.Rotation.X, vehicle.Rotation.Y,
                                      vehicle.Rotation.Z, 2f, 0, 0, 0);

                        Function.Call(Hash.START_PARTICLE_FX_NON_LOOPED_AT_COORD, "scr_agency3a_door_hvy_trig",
                                      forwardRight.X, forwardRight.Y, forwardRight.Z, vehicle.Rotation.X, vehicle.Rotation.Y,
                                      vehicle.Rotation.Z, 2f, 0, 0, 0);
                    }
                }
            }
 private static object InteropCreateElement(object document, string name) => InteropUtility.Invoke(document, "createElement", (object)name);