1658 {
1661
1663
1664
1665
1666
1667
1668
1669
1670 if (!player)
1671 {
1672 #ifndef SERVER
1673 #ifdef DIAG_DEVELOPER
1674 PluginDiagMenuClient.GetWeaponLiftDiag().Reset();
1675 #endif
1676 #endif
1677 Print(
"Error: No weapon owner for LiftWeaponCheckEx, returning.");
1678 return false;
1679 }
1680
1681
1682 HumanMovementState movementState = new HumanMovementState();
1683 player.GetMovementState(movementState);
1685 return false;
1686
1687
1689 {
1690 #ifndef SERVER
1691 #ifdef DIAG_DEVELOPER
1692 PluginDiagMenuClient.GetWeaponLiftDiag().Reset();
1693 #endif
1694 #endif
1695 return false;
1696 }
1697
1698
1699
1700
1701 vector direction;
1702 HumanInputController hic = player.GetInputController();
1705 if (hcw)
1706 {
1707 vector yawPitchRoll =
Vector(
1710 0.0);
1711
1714
1715 yawPitchRoll[0] = yawPitchRoll[0] + xAimHandsOffset;
1717
1719 }
1720 else
1721 {
1722
1724 {
1725 if (player.m_DirectionToCursor != vector.Zero)
1726 {
1727 direction = player.m_DirectionToCursor;
1728 }
1729
1730 else
1731 {
1732 direction = MiscGameplayFunctions.GetHeadingVector(player);
1733 }
1734 }
1735 else
1736 {
1738 }
1739 }
1740
1741
1742 vector start;
1743 int boneIdx = player.GetBoneIndexByName("Neck");
1744 if (boneIdx == -1)
1745 {
1746 start = player.GetPosition()[1] + 1.5;
1747 }
1748 else
1749 {
1750 start = player.GetBonePositionWS(boneIdx);
1751 }
1752
1753
1755 velocity = player.VectorToLocal(velocity);
1757
1759
1760
1762
1763
1764
1766 float weaponEndDist = weaponStartDist + weaponLength;
1767
1768
1769 vector weaponStart = start + (weaponStartDist * direction);
1770 vector weaponEnd = start + (weaponEndDist * direction);
1771
1772
1773
1774
1775
1777 if (baseObstructionLength==0)
1778 {
1780 }
1781
1782 float weaponObstructionDist = baseObstructionLength + effectiveAttachmentLength;
1783 float rayRadius = 0.02;
1784
1785 #ifndef SERVER
1786 #ifdef DIAG_DEVELOPER
1787 float overrideObstDist = PluginDiagMenuClient.GetWeaponLiftDiag().Data().m_ObstructionDistance;
1788 PluginDiagMenuClient.GetWeaponLiftDiag().Data().SetWeaponRayParams(start, direction, weaponStartDist, weaponEndDist, effectiveAttachmentLength,
m_ObstructionDistance, weaponObstructionDist, rayRadius);
1789 weaponObstructionDist = overrideObstDist;
1790 rayRadius = PluginDiagMenuClient.GetWeaponLiftDiag().Data().m_RayRadiusOverride;
1791 #endif
1792 #endif
1793
1794
1795
1796 float rayEndDist = weaponEndDist + 0.30;
1797 vector rayEnd = start + rayEndDist * direction;
1798
1799
1800 RaycastRVParams rayParm = new RaycastRVParams(start, rayEnd, player, rayRadius);
1802 rayParm.
type = ObjIntersect.Fire;
1803
1804 RaycastRVResult hitResult;
1805 float hitFraction;
1806 float hitDist;
1807
1808 array<ref RaycastRVResult> results = {};
1809 if (!DayZPhysics.RaycastRVProxy(rayParm, results) || results.Count() == 0)
1810 {
1811 hitFraction = 0;
1812 }
1813 else
1814 {
1815
1816 int numRes = results.Count();
1817 if (numRes == 1)
1818 {
1819 hitResult = results[0];
1820 }
1821 else
1822 {
1823 int bi = -1;
1824 float maxDist = float.MAX;
1825 for (int i = 0, nr = results.Count(); i < nr; ++i)
1826 {
1827 float sqDist = vector.DistanceSq(results[i].pos, weaponStart);
1828 if (sqDist < maxDist)
1829 {
1830 maxDist = sqDist;
1831 bi = i;
1832 }
1833 }
1834 hitResult = results[bi];
1835 }
1836
1838 {
1839 float len0 = (hitResult.
pos - start).Length();
1840 float len1 = (weaponEnd - start).Length();
1841
1842 if (len0 <= 0 || len1 <= 0)
1843 {
1844 hitFraction = 1;
1845 }
1846 else
1847 {
1848 hitFraction = len0 / len1;
1849 }
1850 hitDist = hitFraction * weaponEndDist;
1851 }
1852 else
1853 {
1854 hitFraction = 0;
1855 hitDist = 0;
1856 }
1857 }
1858
1859 #ifndef SERVER
1860 #ifdef DIAG_DEVELOPER
1861 PluginDiagMenuClient.GetWeaponLiftDiag().Data().SetIntersectionParams(hitResult, hitFraction, hitDist);
1862 PluginDiagMenuClient.GetWeaponLiftDiag().Data().SetLastPosition(lastLiftPosition);
1863 #endif
1864 #endif
1865
1866
1867 bool wantsLift = wasLift;
1868
1869
1870 const float inThreshold = 0.002;
1871
1872 const float outThreshold = 0.003;
1873 const float noIsctOutThreshold = 0.01;
1874
1875
1876 const int maxNumMissedTicks = 10;
1877
1878
1879
1880 float angleThreshold = 0.75 + Math.Clamp(
m_WeaponLength * 0.6, 0, 1.5 );
1881
1882
1883 if (hitFraction != 0)
1884 {
1885 vector v1 = hitResult.
pos - weaponEnd;
1886 vector v2 = hitResult.
pos - rayEnd;
1887 float d = vector.
Dot(v1, v2);
1888
1889
1890 if (!wasLift && d > inThreshold)
1891 {
1892 wantsLift = true;
1893 }
1894 else if (wasLift && d < -outThreshold)
1895 {
1896 wantsLift = false;
1897 }
1898
1901 }
1902 else
1903 {
1904
1905 if (lastLiftPosition == vector.Zero)
1906 {
1907 wantsLift = false;
1909 }
1910
1911
1912 else
1913 {
1914 vector v3 = (lastLiftPosition - start).Normalized();
1915 vector v4 = (weaponEnd-start).Normalized();
1916 float d2 = vector.Dot(v3, v4);
1917
1918 if (Math.Acos(d2) > (angleThreshold * Math.DEG2RAD))
1919 {
1920 wantsLift = false;
1922 }
1923
1924 else
1925 {
1926 float d3 = vector.Dot( lastLiftPosition - weaponEnd, (start-weaponEnd).Normalized() );
1927 if (d3 < -noIsctOutThreshold)
1928 {
1929 wantsLift = false;
1931 }
1933
1934 int timeSinceHit = player.GetSimulationTimeStamp() -
m_LastLiftHit;
1935 if (timeSinceHit > maxNumMissedTicks)
1936 {
1937 wantsLift = false;
1939 }
1941 {
1943 float l1 = (weaponEnd - start).Length();
1944 if (l0 <= 0 || l1 <= 0)
1945 {
1946 hitFraction = 1;
1947 }
1948 else
1949 {
1950 hitFraction = l0 / l1;
1951 }
1952 hitDist = hitFraction * weaponEndDist;
1953 }
1954 }
1955 }
1956 }
1957
1958
1959 if (wantsLift)
1960 {
1961
1962 float begDist = weaponObstructionDist;
1963 float endDist = weaponStartDist + weaponLength;
1964
1965 float obstFraction;
1966 if (begDist < endDist)
1967 obstFraction = Math.InverseLerp( begDist, endDist, hitDist );
1968
1969 if (hitResult)
1970 outHitObject = hitResult.
obj;
1971
1972 outObstruction = 1.0 - obstFraction;
1974 return true;
1975 }
1976
1977 return false;
1978 }
void DayZPlayerCamera1stPerson(DayZPlayer pPlayer, HumanInputController pInput)
proto native vector GetCurrentCameraDirection()
proto native float GetAimingHandsOffsetUD()
returns aiming hands up/down (y) offset angle
proto native float GetWeaponObstruction()
return obstruction value
proto native float GetBaseAimingAngleLR()
returns base aiming angle LR - without sway/offsets/...
proto native float GetAimingHandsOffsetLR()
returns aiming hands left/right (x) offset angle
proto native float GetBaseAimingAngleUD()
returns base aiming angle UD - without sway/offsets/...
Object obj
object,that we collide with (NULL if none), If hierLevel > 0 object is the proxy object
vector pos
position of collision (in world coord)
float m_ObstructionDistance
float GetEffectiveAttachmentLength()
Returns effective length of attachments that influence total weapon length.
void ApproximateWeaponLiftTransform(inout vector start, inout vector direction, HumanMovementState hms, HumanInputController hic, HumanCommandWeapons hcw, HumanCommandMove hcm, vector localVelocity="0 0 0")
vector m_LastLiftPosition
bool LiftWeaponRaycastResultCheck(notnull RaycastRVResult res)
Return whether provided material triggers weapon lift (true) or not (false).
float ApproximateBaseObstructionLength()
Approximate ObstructionDistance for weapons with no configuration. Returned length doesn't account fo...
static float Dot(vector v1, vector v2)
Returns Dot product of vector v1 and vector v2.
proto vector AnglesToVector()
Converts spherical coordinates (yaw, pitch, roll in degrees) to unit length vector.
DayZPlayerConstants
defined in C++
proto native CGame GetGame()
proto void Print(void var)
Prints content of variable to console/log.
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
proto native vector GetVelocity(notnull IEntity ent)
Returns linear velocity.
void HumanCommandWeapons()