summaryrefslogtreecommitdiffstats
path: root/src/peds
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/peds/Ped.cpp139
-rw-r--r--src/peds/Ped.h6
2 files changed, 116 insertions, 29 deletions
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 44148f14..cbd32cea 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -520,7 +520,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bGonnaKillTheCarJacker = false;
bFadeOut = false;
- bKnockedUpIntoAir = false;
+ m_ped_flagH1 = false;
bHitSteepSlope = false;
m_ped_flagH4 = false;
bClearObjective = false;
@@ -537,6 +537,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
#ifdef KANGAROO_CHEAT
m_ped_flagI80 = false;
#endif
+#ifdef VC_PED_PORTS
+ bKnockedUpIntoAir = false;
+#endif
if ((CGeneral::GetRandomNumber() & 3) == 0)
bHasACamera = true;
@@ -3336,7 +3339,7 @@ CPed::ClearAll(void)
ClearLookFlag();
bIsPointingGunAt = false;
bRenderPedInCar = true;
- bKnockedUpIntoAir = false;
+ m_ped_flagH1 = false;
m_pCollidingEntity = nil;
}
@@ -4021,7 +4024,7 @@ CPed::SetGetUp(void)
}
bGetUpAnimStarted = true;
m_pCollidingEntity = nil;
- bKnockedUpIntoAir = false;
+ m_ped_flagH1 = false;
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT);
if (animAssoc) {
if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN)) {
@@ -7965,7 +7968,11 @@ CPed::InTheAir(void)
if (m_vecMoveSpeed.z < 0.0f && !bIsPedDieAnimPlaying) {
if (!DyingOrDead()) {
if (CWorld::ProcessLineOfSight(ourPos, bitBelow, foundCol, foundEnt, true, true, false, true, false, false, false)) {
- if (GetPosition().z - foundCol.point.z < 1.3f)
+ if (GetPosition().z - foundCol.point.z < 1.3f
+#ifdef VC_PED_PORTS
+ || bIsStanding
+#endif
+ )
SetLanding();
} else {
if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL)) {
@@ -8514,9 +8521,9 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
m_pCollidingEntity = car;
}
if (nodeToDamage == PED_MID)
- bKnockedUpIntoAir = true;
+ m_ped_flagH1 = true;
else
- bKnockedUpIntoAir = false;
+ m_ped_flagH1 = false;
distVec.Normalise();
@@ -8547,7 +8554,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
m_pCollidingEntity = car;
}
- bKnockedUpIntoAir = false;
+ m_ped_flagH1 = false;
if (car->m_modelIndex != MI_TRAIN && !bHasHitWall) {
m_vecMoveSpeed = car->m_vecMoveSpeed * 0.75f;
}
@@ -9857,29 +9864,54 @@ CPed::ProcessControl(void)
if (m_nCollisionRecords == 1 && m_aCollisionRecords[0] != nil && m_aCollisionRecords[0]->m_type == ENTITY_TYPE_BUILDING
&& m_nPedStateTimer > 50.0f / (2.0f * adjustedTs) && m_nPedStateTimer * 1.0f / 250.0f > Abs(forceDir.z)) {
offsetToCheck.x = -forceDir.y;
+#ifdef VC_PED_PORTS
+ offsetToCheck.z = 1.0f;
+#else
offsetToCheck.z = 0.0f;
+#endif
offsetToCheck.y = forceDir.x;
offsetToCheck.Normalise();
CVector posToCheck = GetPosition() + offsetToCheck;
- float lastCollidingColZ;
- if (CWorld::ProcessVerticalLine(posToCheck, -20.0f, foundCol, foundEnt, true, false, false, false, false, false, false)) {
- lastCollidingColZ = foundCol.point.z;
+ // These are either obstacle or ground to land, I don't know which one.
+ float obstacleForFlyingZ, obstacleForFlyingOtherDirZ;
+ CColPoint obstacleForFlying, obstacleForFlyingOtherDir;
+
+ // Check is there any room for being knocked up in reverse direction of force
+ if (CWorld::ProcessVerticalLine(posToCheck, -20.0f, obstacleForFlying, foundEnt, true, false, false, false, false, false, false)) {
+ obstacleForFlyingZ = obstacleForFlying.point.z;
} else {
- lastCollidingColZ = 500.0f;
+ obstacleForFlyingZ = 500.0f;
}
posToCheck = GetPosition() - offsetToCheck;
- float lastCollidingColInOtherDirZ;
- if (CWorld::ProcessVerticalLine(posToCheck, -20.0f, foundCol, foundEnt, true, false, false, false, false, false, false)) {
- lastCollidingColInOtherDirZ = foundCol.point.z;
+ // Now check for direction of force this time
+ if (CWorld::ProcessVerticalLine(posToCheck, -20.0f, obstacleForFlyingOtherDir, foundEnt, true, false, false, false, false, false, false)) {
+ obstacleForFlyingOtherDirZ = obstacleForFlyingOtherDir.point.z;
} else {
- lastCollidingColInOtherDirZ = 501.0f;
+ obstacleForFlyingOtherDirZ = 501.0f;
+ }
+#ifdef VC_PED_PORTS
+ uint8 flyDir = 0;
+ float feetZ = GetPosition().z - FEET_OFFSET;
+ if ((obstacleForFlyingZ <= feetZ || obstacleForFlyingOtherDirZ >= 500.0f) && (obstacleForFlyingZ <= feetZ || obstacleForFlyingOtherDirZ <= feetZ)) {
+ if (obstacleForFlyingOtherDirZ > feetZ && obstacleForFlyingZ < 499.0f)
+ flyDir = 2;
+ } else {
+ flyDir = 1;
}
- if (lastCollidingColZ < lastCollidingColInOtherDirZ) {
+ if (flyDir != 0 && !bKnockedUpIntoAir) {
+ GetPosition() = (flyDir == 2 ? obstacleForFlyingOtherDir.point : obstacleForFlying.point);
+ GetPosition().z += FEET_OFFSET;
+ GetMatrix().UpdateRW();
+ SetLanding();
+ bIsStanding = true;
+ }
+#endif
+ if (obstacleForFlyingZ < obstacleForFlyingOtherDirZ) {
offsetToCheck *= -1.0f;
}
offsetToCheck.z = 1.0f;
@@ -9977,8 +10009,17 @@ CPed::ProcessControl(void)
offsetToCheck.z += 0.5f;
if (CWorld::ProcessVerticalLine(offsetToCheck, GetPosition().z - FEET_OFFSET, foundCol, foundEnt, true, true, false, true, false, false, false)) {
+#ifdef VC_PED_PORTS
+ if (!bKnockedUpIntoAir || FEET_OFFSET + foundCol.point.z < GetPosition().z) {
+ GetPosition().z = FEET_OFFSET + foundCol.point.z;
+ GetMatrix().UpdateRW();
+ if (bKnockedUpIntoAir)
+ bKnockedUpIntoAir = false;
+ }
+#else
GetPosition().z = FEET_OFFSET + foundCol.point.z;
GetMatrix().UpdateRW();
+#endif
SetLanding();
bIsStanding = true;
}
@@ -10041,8 +10082,18 @@ CPed::ProcessControl(void)
PlayFootSteps();
if (IsPedInControl() && !bIsStanding && !m_pDamageEntity && CheckIfInTheAir()) {
SetInTheAir();
+#ifdef VC_PED_PORTS
+ bKnockedUpIntoAir = true;
+#endif
}
-
+#ifdef VC_PED_PORTS
+ if (bKnockedUpIntoAir) {
+ CVector posToCheck = GetPosition();
+ posToCheck.z += 0.9f;
+ if (!CWorld::TestSphereAgainstWorld(posToCheck, 0.2f, this, true, true, false, true, false, false))
+ bKnockedUpIntoAir = false;
+ }
+#endif
ProcessObjective();
if (!bIsAimingGun) {
if (bIsRestoringGun)
@@ -13531,6 +13582,19 @@ LocalPosForWalkAround(CVector2D colMin, CVector2D colMax, int walkAround, uint32
return CVector(0.0f, 0.0f, 0.0f);
}
}
+
+bool
+CanWeSeeTheCorner(CVector2D dist, CVector2D fwdOffset)
+{
+ // because if dist is more then 5 unit, fov isn't important, we want shortest way
+ if (dist.Magnitude() > 5.0f)
+ return true;
+
+ if (DotProduct2D(dist, fwdOffset) < 0.0f)
+ return false;
+
+ return true;
+}
#endif
// This function looks completely same on VC.
@@ -13677,10 +13741,11 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
#ifdef NEW_WALK_AROUND_ALGORITHM
else {
CVector tl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMax.y, 0.0f) - GetPosition();
- cornerToGo = tl;
if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) {
+ cornerToGo = tl;
m_walkAroundType = 1;
- } else {
+ } else if(CanWeSeeTheCorner(tl, GetForward())){
+ cornerToGo = tl;
dirToGo = GetLocalDirection(tl);
if (dirToGo == 1)
m_walkAroundType = 0; // ALL of the next turns will be right turn
@@ -13711,10 +13776,11 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
else {
CVector tr = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMax.y, 0.0f) - GetPosition();
if (tr.Magnitude2D() < cornerToGo.Magnitude2D()) {
- cornerToGo = tr;
if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) {
+ cornerToGo = tr;
m_walkAroundType = 2;
- } else {
+ } else if (CanWeSeeTheCorner(tr, GetForward())) {
+ cornerToGo = tr;
dirToGo = GetLocalDirection(tr);
if (dirToGo == 1)
m_walkAroundType = 2; // ALL of the next turns will be right turn
@@ -13746,10 +13812,11 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
else {
CVector br = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMin.y, 0.0f) - GetPosition();
if (br.Magnitude2D() < cornerToGo.Magnitude2D()) {
- cornerToGo = br;
if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) {
+ cornerToGo = br;
m_walkAroundType = 5;
- } else {
+ } else if (CanWeSeeTheCorner(br, GetForward())) {
+ cornerToGo = br;
dirToGo = GetLocalDirection(br);
if (dirToGo == 1)
m_walkAroundType = 4; // ALL of the next turns will be right turn
@@ -13781,10 +13848,11 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
else {
CVector bl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMin.y, 0.0f) - GetPosition();
if (bl.Magnitude2D() < cornerToGo.Magnitude2D()) {
- cornerToGo = bl;
if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) {
+ cornerToGo = bl;
m_walkAroundType = 6;
- } else {
+ } else if (CanWeSeeTheCorner(bl, GetForward())) {
+ cornerToGo = bl;
dirToGo = GetLocalDirection(bl);
if (dirToGo == 1)
m_walkAroundType = 6; // ALL of the next turns will be right turn
@@ -14114,8 +14182,16 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
}
if (CCollision::IsStoredPolyStillValidVerticalLine(pos, potentialGroundZ, intersectionPoint, &m_collPoly)) {
bStillOnValidPoly = true;
- // VC conditionally sets GetPosition().z here with nonexisting flag in III
+#ifdef VC_PED_PORTS
+ if(!bKnockedUpIntoAir || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) {
+ GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
+ if (bKnockedUpIntoAir)
+ bKnockedUpIntoAir = false;
+ }
+#else
GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
+#endif
+
m_vecMoveSpeed.z = 0.0f;
bIsStanding = true;
} else {
@@ -14184,8 +14260,15 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
bOnBoat = false;
}
}
- // VC conditionally sets GetPosition().z here with nonexisting flag in III
+#ifdef VC_PED_PORTS
+ if (!bKnockedUpIntoAir || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) {
+ GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
+ if (bKnockedUpIntoAir)
+ bKnockedUpIntoAir = false;
+ }
+#else
GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
+#endif
m_nSurfaceTouched = intersectionPoint.surfaceB;
if (m_nSurfaceTouched == SURFACE_STONE) {
bHitSteepSlope = true;
@@ -14290,7 +14373,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
sphereNormal.x = -m_vecMoveSpeed.x / max(0.001f, speed);
sphereNormal.y = -m_vecMoveSpeed.y / max(0.001f, speed);
GetPosition().z -= 0.05f;
- // VC sets bKnockedUpIntoAir here
+ bKnockedUpIntoAir = true;
}
#endif
sphereNormal.Normalise();
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index bf4849b2..0b1b80d6 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -328,7 +328,7 @@ public:
uint8 bGonnaKillTheCarJacker : 1; // only set when car is jacked from right door
uint8 bFadeOut : 1;
- uint8 bKnockedUpIntoAir : 1; // NOT CERTAIN - has ped been knocked up into the air by a car collision
+ uint8 m_ped_flagH1 : 1;
uint8 bHitSteepSlope : 1; // has ped collided/is standing on a steep slope (surface type)
uint8 m_ped_flagH4 : 1;
uint8 bClearObjective : 1;
@@ -342,7 +342,11 @@ public:
uint8 m_ped_flagI4 : 1; // seems like related with cars
uint8 bHasAlreadyBeenRecorded : 1;
uint8 bFallenDown : 1;
+#ifdef VC_PED_PORTS
+ uint8 bKnockedUpIntoAir : 1; // has ped been knocked up into the air by a car collision
+#else
uint8 m_ped_flagI20 : 1;
+#endif
uint8 m_ped_flagI40 : 1;
uint8 m_ped_flagI80 : 1;