1652 {
1655
1657
1658
1659
1660
1661
1662
1663
1664 if (!player)
1665 {
1666 #ifndef SERVER
1667 #ifdef DIAG_DEVELOPER
1668 PluginDiagMenuClient.GetWeaponLiftDiag().Reset();
1669 #endif
1670 #endif
1671 Print(
"Error: No weapon owner for LiftWeaponCheckEx, returning.");
1672 return false;
1673 }
1674
1675
1676 HumanMovementState movementState = new HumanMovementState();
1677 player.GetMovementState(movementState);
1679 return false;
1680
1681
1683 {
1684 #ifndef SERVER
1685 #ifdef DIAG_DEVELOPER
1686 PluginDiagMenuClient.GetWeaponLiftDiag().Reset();
1687 #endif
1688 #endif
1689 return false;
1690 }
1691
1692
1693
1694
1695 vector direction;
1696 HumanInputController hic = player.GetInputController();
1699 if (hcw)
1700 {
1701 vector yawPitchRoll =
Vector(
1704 0.0);
1705
1708
1709 yawPitchRoll[0] = yawPitchRoll[0] + xAimHandsOffset;
1711
1713 }
1714 else
1715 {
1716
1718 {
1719 if (player.m_DirectionToCursor != vector.Zero)
1720 {
1721 direction = player.m_DirectionToCursor;
1722 }
1723
1724 else
1725 {
1726 direction = MiscGameplayFunctions.GetHeadingVector(player);
1727 }
1728 }
1729 else
1730 {
1731 direction =
g_Game.GetCurrentCameraDirection();
1732 }
1733 }
1734
1735
1736 vector start;
1737 int boneIdx = player.GetBoneIndexByName("Neck");
1738 if (boneIdx == -1)
1739 {
1740 start = player.GetPosition()[1] + 1.5;
1741 }
1742 else
1743 {
1744 start = player.GetBonePositionWS(boneIdx);
1745 }
1746
1747
1749 velocity = player.VectorToLocal(velocity);
1751
1753
1754
1756
1757
1758
1760 float weaponEndDist = weaponStartDist + weaponLength;
1761
1762
1763 vector weaponStart = start + (weaponStartDist * direction);
1764 vector weaponEnd = start + (weaponEndDist * direction);
1765
1766
1767
1768
1769
1771 if (baseObstructionLength==0)
1772 {
1774 }
1775
1776 float weaponObstructionDist = baseObstructionLength + effectiveAttachmentLength;
1777 float rayRadius = 0.02;
1778
1779 #ifndef SERVER
1780 #ifdef DIAG_DEVELOPER
1781 float overrideObstDist = PluginDiagMenuClient.GetWeaponLiftDiag().Data().m_ObstructionDistance;
1782 PluginDiagMenuClient.GetWeaponLiftDiag().Data().SetWeaponRayParams(start, direction, weaponStartDist, weaponEndDist, effectiveAttachmentLength,
m_ObstructionDistance, weaponObstructionDist, rayRadius);
1783 weaponObstructionDist = overrideObstDist;
1784 rayRadius = PluginDiagMenuClient.GetWeaponLiftDiag().Data().m_RayRadiusOverride;
1785 #endif
1786 #endif
1787
1788
1789
1790 float rayEndDist = weaponEndDist + 0.30;
1791 vector rayEnd = start + rayEndDist * direction;
1792
1793
1794 RaycastRVParams rayParm = new RaycastRVParams(start, rayEnd, player, rayRadius);
1796 rayParm.
type = ObjIntersect.Fire;
1797
1798 RaycastRVResult hitResult;
1800 float hitDist;
1801
1802 array<ref RaycastRVResult> results = {};
1803 if (!DayZPhysics.RaycastRVProxy(rayParm, results) || results.Count() == 0)
1804 {
1806 }
1807 else
1808 {
1809
1810 int numRes = results.Count();
1811 if (numRes == 1)
1812 {
1813 hitResult = results[0];
1814 }
1815 else
1816 {
1817 int bi = -1;
1818 float maxDist = float.MAX;
1819 for (int i = 0, nr = results.Count(); i < nr; ++i)
1820 {
1821 float sqDist = vector.DistanceSq(results[i].pos, weaponStart);
1822 if (sqDist < maxDist)
1823 {
1824 maxDist = sqDist;
1825 bi = i;
1826 }
1827 }
1828 hitResult = results[bi];
1829 }
1830
1832 {
1833 float len0 = (hitResult.
pos - start).Length();
1834 float len1 = (weaponEnd - start).Length();
1835
1836 if (len0 <= 0 || len1 <= 0)
1837 {
1839 }
1840 else
1841 {
1843 }
1845 }
1846 else
1847 {
1849 hitDist = 0;
1850 }
1851 }
1852
1853 #ifndef SERVER
1854 #ifdef DIAG_DEVELOPER
1855 PluginDiagMenuClient.GetWeaponLiftDiag().Data().SetIntersectionParams(hitResult,
hitFraction, hitDist);
1856 PluginDiagMenuClient.GetWeaponLiftDiag().Data().SetLastPosition(lastLiftPosition);
1857 #endif
1858 #endif
1859
1860
1861 bool wantsLift = wasLift;
1862
1863
1864 const float inThreshold = 0.002;
1865
1866 const float outThreshold = 0.003;
1867 const float noIsctOutThreshold = 0.01;
1868
1869
1870 const int maxNumMissedTicks = 10;
1871
1872
1873
1874 float angleThreshold = 0.75 + Math.Clamp(
m_WeaponLength * 0.6, 0, 1.5 );
1875
1876
1878 {
1879 vector v1 = hitResult.
pos - weaponEnd;
1880 vector v2 = hitResult.
pos - rayEnd;
1881 float d = vector.
Dot(v1, v2);
1882
1883
1884 if (!wasLift && d > inThreshold)
1885 {
1886 wantsLift = true;
1887 }
1888 else if (wasLift && d < -outThreshold)
1889 {
1890 wantsLift = false;
1891 }
1892
1895 }
1896 else
1897 {
1898
1899 if (lastLiftPosition == vector.Zero)
1900 {
1901 wantsLift = false;
1903 }
1904
1905
1906 else
1907 {
1908 vector v3 = (lastLiftPosition - start).Normalized();
1909 vector v4 = (weaponEnd-start).Normalized();
1910 float d2 = vector.Dot(v3, v4);
1911
1912 if (Math.Acos(d2) > (angleThreshold * Math.DEG2RAD))
1913 {
1914 wantsLift = false;
1916 }
1917
1918 else
1919 {
1920 float d3 = vector.Dot( lastLiftPosition - weaponEnd, (start-weaponEnd).Normalized() );
1921 if (d3 < -noIsctOutThreshold)
1922 {
1923 wantsLift = false;
1925 }
1927
1928 int timeSinceHit = player.GetSimulationTimeStamp() -
m_LastLiftHit;
1929 if (timeSinceHit > maxNumMissedTicks)
1930 {
1931 wantsLift = false;
1933 }
1935 {
1937 float l1 = (weaponEnd - start).Length();
1938 if (l0 <= 0 || l1 <= 0)
1939 {
1941 }
1942 else
1943 {
1945 }
1947 }
1948 }
1949 }
1950 }
1951
1952
1953 if (wantsLift)
1954 {
1955
1956 float begDist = weaponObstructionDist;
1957 float endDist = weaponStartDist + weaponLength;
1958
1959 float obstFraction;
1960 if (begDist < endDist)
1961 obstFraction = Math.InverseLerp( begDist, endDist, hitDist );
1962
1963 if (hitResult)
1964 outHitObject = hitResult.
obj;
1965
1966 outObstruction = 1.0 - obstFraction;
1968 return true;
1969 }
1970
1971 return false;
1972 }
void DayZPlayerCamera1stPerson(DayZPlayer pPlayer, HumanInputController pInput)
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 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()