1335 {
1336 int idx;
1337 float distance;
1338 float hit_fraction;
1339 vector start, end;
1340 vector direction;
1341 vector hit_pos, hit_normal;
1343
1346
1348
1349 if ( HasSelection("Usti hlavne") )
1350 return false;
1351
1352 if (!player)
1353 {
1354 Print(
"Error: No weapon owner, returning");
1355 return false;
1356 }
1357
1358
1359 HumanMovementState movementState = new HumanMovementState();
1360 player.GetMovementState(movementState);
1362 return false;
1363
1364
1366 {
1367 return false;
1368 }
1369
1370
1371
1372
1374 if (hcw)
1375 {
1376 vector yawPitchRoll =
Vector(
1379 0.0);
1380
1383
1384 yawPitchRoll[0] = yawPitchRoll[0] + xAimHandsOffset;
1386
1388 }
1389 else
1390 {
1391
1392 if (player.GetInputController().CameraIsFreeLook())
1393 {
1394 if (player.m_DirectionToCursor != vector.Zero)
1395 {
1396 direction = player.m_DirectionToCursor;
1397 }
1398
1399 else
1400 {
1401 direction = MiscGameplayFunctions.GetHeadingVector(player);
1402 }
1403 }
1404 else
1405 {
1407 }
1408 }
1409
1410 idx = player.GetBoneIndexByName("Neck");
1411 if ( idx == -1 )
1412 { start = player.GetPosition()[1] + 1.5; }
1413 else
1414 { start = player.GetBonePositionWS(idx); }
1415
1416
1417
1418 {
1419
1420
1421
1422
1423 vector resTM[4];
1426 resTM[2] = direction;
1427 resTM[1] = resTM[2] * resTM[0];
1428 resTM[3] = start;
1429
1430
1431 HumanMovementState hms = new HumanMovementState();
1432 player.GetMovementState(hms);
1434 vector rotTM[3];
1435 Math3D.YawPitchRollMatrix(
Vector(xAimHandsOffset , yAimHandsOffset, leanAngle), rotTM );
1436 Math3D.MatrixMultiply3(resTM, rotTM, resTM);
1437
1438
1439 #ifdef DIAG_DEVELOPER
1440 if (DiagMenu.GetValue(
DiagMenuIDs.WEAPON_LIFT_DEBUG))
1441 {
1445 }
1446 #endif
1447
1448
1449
1450 float udAngle = Math.Asin(direction[1]) * Math.RAD2DEG;
1451
1452
1453
1454 vector offsets[] =
1455 {
1456 "0.11 0.17 0.0",
1457 "0.12 0.05 0.0",
1458 "0.112 0.03 0.0"
1459 };
1460 const int lastIndex = 2;
1461
1462
1464 int lo = a * lastIndex;
1465 int hi = Math.Clamp(lo+1, 0, lastIndex);
1466
1467
1468 float t = Math.Clamp(a * lastIndex - lo, 0, 1);
1469 vector offset = vector.Lerp(offsets[lo], offsets[hi], t);
1470
1471
1472
1473 vector stanceOffsets[] =
1474 {
1475 "0 -0.015 0",
1476 "0 0.03 0",
1477 "0 -0.04 0",
1478 };
1479
1480
1481
1485
1487 offset += stanceOffsets[stanceOffsetIndex];
1488
1489
1491 {
1493 }
1494
1495
1497
1498
1499
1500
1502 }
1503
1504
1506
1508 vector weaponEnd = weaponStart + (distance * direction);
1509
1510
1511 #ifdef DIAG_DEVELOPER
1512 if (DiagMenu.GetValue(
DiagMenuIDs.WEAPON_LIFT_DEBUG))
1513 {
1514 vector diagNoAttachEnd = weaponStart + (
m_WeaponLength * direction);
1516 float diagPtsRadius = 0.025;
1517 Shape.CreateSphere(
COLOR_GREEN, diagPtsShpFlgs, weaponStart, diagPtsRadius);
1518 Shape.CreateSphere(
COLOR_YELLOW, diagPtsShpFlgs, diagNoAttachEnd, diagPtsRadius);
1519 Shape.CreateSphere(
COLOR_BLUE, diagPtsShpFlgs, weaponEnd, diagPtsRadius);
1520 }
1521 #endif
1522
1523
1524
1525 end = weaponEnd + ((0.1 * distance) * direction);
1526
1527
1528 RaycastRVParams rayParm = new RaycastRVParams(start, end, player, 0.02);
1530 rayParm.type = ObjIntersect.Fire;
1531
1532 #ifdef DIAG_DEVELOPER
1533 DbgUI.BeginCleanupScope();
1534 #endif
1535 array<ref RaycastRVResult> results = {};
1536 if (!DayZPhysics.RaycastRVProxy(rayParm, results) || results.Count() == 0)
1537 {
1538 hit_pos = vector.
Zero;
1539 hit_fraction = 0;
1540 }
1541 else
1542 {
1543 RaycastRVResult res = results[0];
1544
1545 #ifdef DIAG_DEVELOPER
1546 if (DiagMenu.GetValue(
DiagMenuIDs.WEAPON_LIFT_DEBUG) == 2)
1547 {
1548 DbgUI.Begin("Weapon Lift Diag");
1549 {
1551 {
1552 DbgUI.Text("Intersection data:");
1556
1559 }
1560 else
1561 {
1562 DbgUI.Text("Intersection with no surface");
1563 }
1564 }
1565 DbgUI.End();
1566 }
1567 #endif
1568
1570 {
1572 float len0 = (hit_pos - start).Length();
1573 float len1 = (end - start).Length();
1574 if (len0 <= 0 || len1 <= 0)
1575 {
1576 hit_fraction = 1;
1577 }
1578 else
1579 {
1580 hit_fraction = len0 / len1;
1581 }
1582 }
1583 else
1584 {
1585 hit_pos = vector.
Zero;
1586 hit_fraction = 0;
1587 }
1588 }
1589 #ifdef DIAG_DEVELOPER
1590 DbgUI.EndCleanupScope();
1591 #endif
1592
1593
1594 #ifdef DIAG_DEVELOPER
1595 if (DiagMenu.GetValue(
DiagMenuIDs.WEAPON_LIFT_DEBUG))
1596 {
1597 const vector epsilon = "0 0.0002 0";
1598 if (lastLiftPosition!=vector.Zero)
1599 {
1601 }
1602
1604
1605 if (hit_fraction != 0)
1606 {
1608 }
1609 }
1610 #endif
1611
1612
1613 bool wantsLift = wasLift;
1614
1615
1616 const float inThreshold = 0.002;
1617
1618 const float outThreshold = 0.003;
1619 const float noIsctOutThreshold = 0.01;
1620
1621
1622 const int maxNumMissedTicks = 10;
1623
1624
1625
1626 float angleThreshold = 0.75 + Math.Clamp(
m_WeaponLength * 0.6, 0, 1.5 );
1627
1628
1629 if (hit_fraction != 0)
1630 {
1631 vector v1 = hit_pos - weaponEnd;
1632 vector v2 = hit_pos - end;
1633 float d = vector.
Dot(v1, v2);
1634
1635
1636 if (!wasLift && d > inThreshold)
1637 {
1638 wantsLift = true;
1639 }
1640 else if (wasLift && d < -outThreshold)
1641 {
1642 wantsLift = false;
1643 }
1644
1647 }
1648 else
1649 {
1650
1651 if (lastLiftPosition == vector.Zero)
1652 {
1653 wantsLift = false;
1655 }
1656
1657
1658 else
1659 {
1660 vector v3 = (lastLiftPosition - start).Normalized();
1661 vector v4 = (end-start).Normalized();
1662 float d2 = vector.Dot(v3, v4);
1663
1664 if (Math.Acos(d2) > (angleThreshold * Math.DEG2RAD))
1665 {
1666 wantsLift = false;
1668 }
1669
1670 else
1671 {
1672 float d3 = vector.Dot( lastLiftPosition - weaponEnd, (start-end).Normalized() );
1673 if (d3 < -noIsctOutThreshold)
1674 {
1675 wantsLift = false;
1677 }
1678
1679
1680 int timeSinceHit = player.GetSimulationTimeStamp() -
m_LastLiftHit;
1681 if (timeSinceHit > maxNumMissedTicks)
1682 {
1683 wantsLift = false;
1685 }
1686 }
1687 }
1688 }
1689
1690
1691 if (wantsLift)
1692 {
1693
1695 return true;
1696 }
1697 return false;
1698 }
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 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/...
int m_iStanceIdx
current command's id
float m_fLeaning
current movement (0 idle, 1 walk, 2-run, 3-sprint), only if the command has a movement
SurfaceInfo surface
surface material info handle
vector pos
position of collision (in world coord)
proto string GetSurfaceType()
proto bool IsPassthrough()
proto string GetEntryName()
float m_WeaponLiftCheckVerticalOffset
float GetEffectiveAttachmentLength()
Returns effective length of attachments that influence total weapon length.
vector m_LastLiftPosition
bool LiftWeaponRaycastResultCheck(notnull RaycastRVResult res)
Return whether provided material triggers weapon lift (true) or not (false).
proto vector Normalized()
return normalized vector (keeps orginal vector untouched)
proto vector Multiply4(vector mat[4])
Transforms position.
static vector RotateAroundZeroDeg(vector vec, vector axis, float angle)
Rotate a vector around 0,0,0 by an angle in degrees.
static float Dot(vector v1, vector v2)
Returns Dot product of vector v1 and vector v2.
proto vector InvMultiply3(vector mat[3])
Invert-transforms vector.
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.
void HumanCommandWeapons()