Merge pull request #218 from erorcun/erorcun

Fixes & peds
This commit is contained in:
aap 2019-10-03 10:19:57 +02:00 committed by GitHub
commit 0346d44626
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 289 additions and 39 deletions

View File

@ -1707,7 +1707,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
ped->SetOrientation(0.0f, 0.0f, 0.0f); ped->SetOrientation(0.0f, 0.0f, 0.0f);
CTheScripts::ClearSpaceForMissionEntity(pos, ped); CTheScripts::ClearSpaceForMissionEntity(pos, ped);
CWorld::Add(ped); CWorld::Add(ped);
ped->m_level = CTheZones::GetLevelFromPosition(pos); ped->m_nZoneLevel = CTheZones::GetLevelFromPosition(pos);
CPopulation::ms_nTotalMissionPeds++; CPopulation::ms_nTotalMissionPeds++;
ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped); ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
@ -1948,7 +1948,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
car->AutoPilot.m_nCruiseSpeed = car->AutoPilot.m_fMaxTrafficSpeed = 9.0f; car->AutoPilot.m_nCruiseSpeed = car->AutoPilot.m_fMaxTrafficSpeed = 9.0f;
car->AutoPilot.m_nCurrentLane = car->AutoPilot.m_nNextLane = 0; car->AutoPilot.m_nCurrentLane = car->AutoPilot.m_nNextLane = 0;
car->bEngineOn = false; car->bEngineOn = false;
car->m_level = CTheZones::GetLevelFromPosition(pos); car->m_nZoneLevel = CTheZones::GetLevelFromPosition(pos);
car->bHasBeenOwnedByPlayer = true; car->bHasBeenOwnedByPlayer = true;
CWorld::Add(car); CWorld::Add(car);
handle = CPools::GetVehiclePool()->GetIndex(car); handle = CPools::GetVehiclePool()->GetIndex(car);
@ -2748,7 +2748,7 @@ int8 CRunningScript::ProcessCommandsFrom200To299(int32 command)
AnimationId anim = pVehicle->bLowVehicle ? ANIM_CAR_LSIT : ANIM_CAR_SIT; AnimationId anim = pVehicle->bLowVehicle ? ANIM_CAR_LSIT : ANIM_CAR_SIT;
pPed->m_pVehicleAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, anim, 100.0f); pPed->m_pVehicleAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, anim, 100.0f);
pPed->StopNonPartialAnims(); pPed->StopNonPartialAnims();
pPed->m_level = CTheZones::GetLevelFromPosition(pPed->GetPosition()); pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(pPed->GetPosition());
CWorld::Add(pPed); CWorld::Add(pPed);
ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);

View File

@ -139,5 +139,4 @@ enum Config {
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher #define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
#define ANIMATE_PED_COL_MODEL #define ANIMATE_PED_COL_MODEL
//#define REMOVE_TREADABLE_PATHFIND //#define REMOVE_TREADABLE_PATHFIND
#define CANCELLABLE_CAR_ENTER
#define VC_PED_PORTS #define VC_PED_PORTS

View File

@ -61,7 +61,7 @@ public:
uint8 m_phy_flagA80 : 1; uint8 m_phy_flagA80 : 1;
uint8 m_nSurfaceTouched; uint8 m_nSurfaceTouched;
uint8 m_nZoneLevel; int8 m_nZoneLevel;
CPhysical(void); CPhysical(void);
~CPhysical(void); ~CPhysical(void);

View File

@ -48,7 +48,6 @@
WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); } WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); }
WRAPPER void CPed::SetPedPositionInCar(void) { EAXJMP(0x4D4970); } WRAPPER void CPed::SetPedPositionInCar(void) { EAXJMP(0x4D4970); }
WRAPPER void CPed::PreRender(void) { EAXJMP(0x4CFDD0); } WRAPPER void CPed::PreRender(void) { EAXJMP(0x4CFDD0); }
WRAPPER int32 CPed::ProcessEntityCollision(CEntity*, CColPoint*) { EAXJMP(0x4CBB30); }
WRAPPER void CPed::SetMoveAnim(void) { EAXJMP(0x4C5A40); } WRAPPER void CPed::SetMoveAnim(void) { EAXJMP(0x4C5A40); }
WRAPPER void CPed::SetFollowRoute(int16, int16) { EAXJMP(0x4DD690); } WRAPPER void CPed::SetFollowRoute(int16, int16) { EAXJMP(0x4DD690); }
WRAPPER void CPed::SetDuck(uint32) { EAXJMP(0x4E4920); } WRAPPER void CPed::SetDuck(uint32) { EAXJMP(0x4E4920); }
@ -68,7 +67,10 @@ WRAPPER void CPed::SetEnterCar(CVehicle*, uint32) { EAXJMP(0x4E0920); }
WRAPPER bool CPed::WarpPedToNearEntityOffScreen(CEntity*) { EAXJMP(0x4E5570); } WRAPPER bool CPed::WarpPedToNearEntityOffScreen(CEntity*) { EAXJMP(0x4E5570); }
WRAPPER void CPed::SetExitCar(CVehicle*, uint32) { EAXJMP(0x4E1010); } WRAPPER void CPed::SetExitCar(CVehicle*, uint32) { EAXJMP(0x4E1010); }
#define FEET_OFFSET 1.04f
#define NEW_WALK_AROUND_ALGORITHM #define NEW_WALK_AROUND_ALGORITHM
#define CANCELLABLE_CAR_ENTER
CPed *gapTempPedList[50]; CPed *gapTempPedList[50];
uint16 gnNumTempPedList; uint16 gnNumTempPedList;
@ -512,17 +514,17 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bObstacleShowedUpDuringKillObjective = false; bObstacleShowedUpDuringKillObjective = false;
bDuckAndCover = false; bDuckAndCover = false;
m_ped_flagG1 = false; bStillOnValidPoly = false;
m_ped_flagG2 = true; m_ped_flagG2 = true;
m_ped_flagG4 = false; m_ped_flagG4 = false;
bStartWanderPathOnFoot = false; bStartWanderPathOnFoot = false;
m_ped_flagG10 = false; bOnBoat = false;
bBusJacked = false; bBusJacked = false;
bGonnaKillTheCarJacker = false; bGonnaKillTheCarJacker = false;
bFadeOut = false; bFadeOut = false;
bKnockedUpIntoAir = false; bKnockedUpIntoAir = false;
m_ped_flagH2 = false; bHitSteepSlope = false;
m_ped_flagH4 = false; m_ped_flagH4 = false;
bClearObjective = false; bClearObjective = false;
m_ped_flagH10 = false; m_ped_flagH10 = false;
@ -1891,7 +1893,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
bool stillGettingInOut = false; bool stillGettingInOut = false;
if (CTimer::GetTimeInMilliseconds() < m_nPedStateTimer) if (CTimer::GetTimeInMilliseconds() < m_nPedStateTimer)
stillGettingInOut = veh->m_vehType != VEHICLE_TYPE_BOAT || m_ped_flagG10; stillGettingInOut = veh->m_vehType != VEHICLE_TYPE_BOAT || bOnBoat;
if (!stillGettingInOut) { if (!stillGettingInOut) {
m_fRotationCur = m_fRotationDest; m_fRotationCur = m_fRotationDest;
@ -2429,6 +2431,7 @@ CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal = nil)
return CWorld::GetIsLineOfSightClear(pos, forwardPos, true, false, false, true, false, false, false); return CWorld::GetIsLineOfSightClear(pos, forwardPos, true, false, false, true, false, false, false);
} }
#else #else
bool
CPed::CanPedJumpThis(CEntity *unused) CPed::CanPedJumpThis(CEntity *unused)
{ {
CVector2D forward(-Sin(m_fRotationCur), Cos(m_fRotationCur)); CVector2D forward(-Sin(m_fRotationCur), Cos(m_fRotationCur));
@ -3310,7 +3313,7 @@ CPed::CheckIfInTheAir(void)
bool foundGround = CWorld::ProcessVerticalLine(pos, startZ, foundColPoint, foundEntity, true, true, false, true, false, false, nil); bool foundGround = CWorld::ProcessVerticalLine(pos, startZ, foundColPoint, foundEntity, true, true, false, true, false, false, nil);
if (!foundGround && m_nPedState != PED_JUMP) if (!foundGround && m_nPedState != PED_JUMP)
{ {
pos.z -= 1.04f; pos.z -= FEET_OFFSET;
if (CWorld::TestSphereAgainstWorld(pos, 0.15f, this, true, false, false, false, false, false)) if (CWorld::TestSphereAgainstWorld(pos, 0.15f, this, true, false, false, false, false, false))
foundGround = true; foundGround = true;
} }
@ -9976,8 +9979,8 @@ CPed::ProcessControl(void)
offsetToCheck = GetPosition(); offsetToCheck = GetPosition();
offsetToCheck.z += 0.5f; offsetToCheck.z += 0.5f;
if (CWorld::ProcessVerticalLine(offsetToCheck, GetPosition().z - 1.04f, foundCol, foundEnt, true, true, false, true, false, false, false)) { if (CWorld::ProcessVerticalLine(offsetToCheck, GetPosition().z - FEET_OFFSET, foundCol, foundEnt, true, true, false, true, false, false, false)) {
GetPosition().z = 1.04f + foundCol.point.z; GetPosition().z = FEET_OFFSET + foundCol.point.z;
GetMatrix().UpdateRW(); GetMatrix().UpdateRW();
SetLanding(); SetLanding();
bIsStanding = true; bIsStanding = true;
@ -11802,7 +11805,7 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->ReplaceWeaponWhenExitingVehicle(); ped->ReplaceWeaponWhenExitingVehicle();
ped->m_ped_flagG10 = false; ped->bOnBoat = false;
if (ped->bBusJacked) { if (ped->bBusJacked) {
ped->SetFall(1500, ANIM_KO_SKID_BACK, false); ped->SetFall(1500, ANIM_KO_SKID_BACK, false);
ped->bBusJacked = false; ped->bBusJacked = false;
@ -13518,8 +13521,7 @@ LocalPosForWalkAround(CVector2D colMin, CVector2D colMax, int walkAround) {
case 7: case 7:
return CVector(colMin.x, colMin.y, 0.0f); return CVector(colMin.x, colMin.y, 0.0f);
default: default:
// case 9: return CVector(0.0f, 0.0f, 0.0f);
return CVector(0.0f, 0.0f, 0.0f); // just a placeholder, supposed to be -GetForward();
} }
} }
#endif #endif
@ -13588,11 +13590,11 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
objUpsideDown = false; objUpsideDown = false;
} }
float oldRotDest = m_fRotationDest; float oldRotDest = m_fRotationDest;
#ifndef NEW_WALK_AROUND_ALGORITHM
float angleToFaceObjCenter = (objColCenter - GetPosition()).Heading(); float angleToFaceObjCenter = (objColCenter - GetPosition()).Heading();
float angleDiffBtwObjCenterAndForward = CGeneral::LimitRadianAngle(dirToSet - angleToFaceObjCenter); float angleDiffBtwObjCenterAndForward = CGeneral::LimitRadianAngle(dirToSet - angleToFaceObjCenter);
// What is the purpose of using this?
float objTopRightHeading = Atan2(adjustedColMax.x - adjustedColMin.x, adjustedColMax.y - adjustedColMin.y); float objTopRightHeading = Atan2(adjustedColMax.x - adjustedColMin.x, adjustedColMax.y - adjustedColMin.y);
#endif
if (IsPlayer()) { if (IsPlayer()) {
if (FindPlayerPed()->m_fMoveSpeed <= 0.0f) if (FindPlayerPed()->m_fMoveSpeed <= 0.0f)
@ -13641,7 +13643,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
collidingThingChanged = false; collidingThingChanged = false;
} else { } else {
#else #else
CVector cornerToGo; CVector cornerToGo = CVector(10.0f, 10.0f, 10.0f);
int dirToGo; int dirToGo;
m_walkAroundType = 0; m_walkAroundType = 0;
#endif #endif
@ -13669,10 +13671,10 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
else { else {
CVector tl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMax.y, 0.0f) - GetPosition(); CVector tl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMax.y, 0.0f) - GetPosition();
cornerToGo = tl; cornerToGo = tl;
dirToGo = GetLocalDirection(tl);
if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) {
m_walkAroundType = 1; m_walkAroundType = 1;
} else { } else {
dirToGo = GetLocalDirection(tl);
if (dirToGo == 1) if (dirToGo == 1)
m_walkAroundType = 0; // ALL of the next turns will be right turn m_walkAroundType = 0; // ALL of the next turns will be right turn
else if (dirToGo == 3) else if (dirToGo == 3)
@ -13703,10 +13705,10 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
CVector tr = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMax.y, 0.0f) - GetPosition(); CVector tr = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMax.y, 0.0f) - GetPosition();
if (tr.Magnitude2D() < cornerToGo.Magnitude2D()) { if (tr.Magnitude2D() < cornerToGo.Magnitude2D()) {
cornerToGo = tr; cornerToGo = tr;
dirToGo = GetLocalDirection(tr);
if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) {
m_walkAroundType = 2; m_walkAroundType = 2;
} else { } else {
dirToGo = GetLocalDirection(tr);
if (dirToGo == 1) if (dirToGo == 1)
m_walkAroundType = 2; // ALL of the next turns will be right turn m_walkAroundType = 2; // ALL of the next turns will be right turn
else if (dirToGo == 3) else if (dirToGo == 3)
@ -13738,10 +13740,10 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
CVector br = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMin.y, 0.0f) - GetPosition(); CVector br = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMin.y, 0.0f) - GetPosition();
if (br.Magnitude2D() < cornerToGo.Magnitude2D()) { if (br.Magnitude2D() < cornerToGo.Magnitude2D()) {
cornerToGo = br; cornerToGo = br;
dirToGo = GetLocalDirection(br);
if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) {
m_walkAroundType = 5; m_walkAroundType = 5;
} else { } else {
dirToGo = GetLocalDirection(br);
if (dirToGo == 1) if (dirToGo == 1)
m_walkAroundType = 4; // ALL of the next turns will be right turn m_walkAroundType = 4; // ALL of the next turns will be right turn
else if (dirToGo == 3) else if (dirToGo == 3)
@ -13773,10 +13775,10 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
CVector bl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMin.y, 0.0f) - GetPosition(); CVector bl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMin.y, 0.0f) - GetPosition();
if (bl.Magnitude2D() < cornerToGo.Magnitude2D()) { if (bl.Magnitude2D() < cornerToGo.Magnitude2D()) {
cornerToGo = bl; cornerToGo = bl;
dirToGo = GetLocalDirection(bl);
if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) {
m_walkAroundType = 6; m_walkAroundType = 6;
} else { } else {
dirToGo = GetLocalDirection(bl);
if (dirToGo == 1) if (dirToGo == 1)
m_walkAroundType = 6; // ALL of the next turns will be right turn m_walkAroundType = 6; // ALL of the next turns will be right turn
else if (dirToGo == 3) else if (dirToGo == 3)
@ -13786,7 +13788,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
} }
#else #else
} }
#endif
if (entityOnTopLeftOfObj && entityOnTopRightOfObj && entityOnBottomRightOfObj && entityOnBottomLeftOfObj) { if (entityOnTopLeftOfObj && entityOnTopRightOfObj && entityOnBottomRightOfObj && entityOnBottomLeftOfObj) {
collidingThingChanged = false; collidingThingChanged = false;
entityOnTopLeftOfObj = 0; entityOnTopLeftOfObj = 0;
@ -13795,7 +13797,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
entityOnBottomRightOfObj = 0; entityOnBottomRightOfObj = 0;
} }
#ifndef NEW_WALK_AROUND_ALGORITHM
if (!collidingThingChanged) { if (!collidingThingChanged) {
m_walkAroundType = 0; m_walkAroundType = 0;
} else { } else {
@ -13879,15 +13880,25 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
nextWalkAround = 7; nextWalkAround = 7;
} }
if (CGeneral::GetRandomNumber() & 1){ CVector nextPosToHead = objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, nextWalkAround);
bool nextRouteIsClear = CWorld::GetIsLineOfSightClear(GetPosition(), objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, nextWalkAround), bool nextRouteIsClear = CWorld::GetIsLineOfSightClear(GetPosition(), nextPosToHead, true, true, true, true, true, true, false);
true, true, true, true, true, true, false);
if(nextRouteIsClear) if(nextRouteIsClear)
m_walkAroundType = nextWalkAround; m_walkAroundType = nextWalkAround;
} else { else {
bool currentRouteIsClear = CWorld::GetIsLineOfSightClear(GetPosition(), objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, m_walkAroundType), CVector posToHead = objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, m_walkAroundType);
bool currentRouteIsClear = CWorld::GetIsLineOfSightClear(GetPosition(), posToHead,
true, true, true, true, true, true, false); true, true, true, true, true, true, false);
if (!currentRouteIsClear) {
/* Either;
* - Some obstacle came in and it's impossible to reach current destination
* - We reached to the destination, but since next route is not clear, we're turning around us
*/
if (!currentRouteIsClear ||
((posToHead - GetPosition()).Magnitude2D() < 0.8f &&
!CWorld::GetIsLineOfSightClear(GetPosition() + GetForward(), nextPosToHead,
true, true, true, true, true, true, false))) {
// Change both target and direction (involves changing even/oddness) // Change both target and direction (involves changing even/oddness)
if (m_walkAroundType % 2 == 0) { if (m_walkAroundType % 2 == 0) {
m_walkAroundType -= 2; m_walkAroundType -= 2;
@ -13897,7 +13908,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
m_walkAroundType += 1; m_walkAroundType += 1;
} else { } else {
m_walkAroundType += 2; m_walkAroundType += 2;
if (m_walkAroundType > 6) if (m_walkAroundType > 7)
m_walkAroundType = 0; m_walkAroundType = 0;
else else
m_walkAroundType -= 1; m_walkAroundType -= 1;
@ -14030,6 +14041,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
m_actionY = localPosToHead.y; m_actionY = localPosToHead.y;
localPosToHead -= GetPosition(); localPosToHead -= GetPosition();
m_fRotationDest = CGeneral::LimitRadianAngle(localPosToHead.Heading()); m_fRotationDest = CGeneral::LimitRadianAngle(localPosToHead.Heading());
if (m_fRotationDest != m_fRotationCur && bHitSomethingLastFrame) { if (m_fRotationDest != m_fRotationCur && bHitSomethingLastFrame) {
if (m_fRotationDest == oldRotDest) { if (m_fRotationDest == oldRotDest) {
m_fRotationDest = oldRotDest; m_fRotationDest = oldRotDest;
@ -14047,6 +14059,243 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 280.0f * dist * checkIntervalInTime; m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 280.0f * dist * checkIntervalInTime;
} }
int32
CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
{
bool collidedWithBoat = false;
bool belowTorsoCollided = false;
float gravityEffect = -0.15f * CTimer::GetTimeStep();
CColPoint intersectionPoint;
CColLine ourLine;
CColModel *ourCol = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel();
CColModel *hisCol = CModelInfo::GetModelInfo(collidingEnt->m_modelIndex)->GetColModel();
if (!bUsesCollision)
return false;
if (collidingEnt->IsVehicle() && ((CVehicle*)collidingEnt)->IsBoat())
collidedWithBoat = true;
if (!field_EF && !m_phy_flagA80
#ifdef VC_PED_PORTS
&& !collidingEnt->IsPed()
#endif
) {
if (!bCollisionProcessed) {
#ifdef VC_PED_PORTS
m_pCurrentPhysSurface = nil;
#endif
if (bIsStanding) {
bIsStanding = false;
m_ped_flagA2 = true;
}
bCollisionProcessed = true;
m_fCollisionSpeed += m_vecMoveSpeed.Magnitude2D() * CTimer::GetTimeStep();
bStillOnValidPoly = false;
if (IsPlayer() || m_fCollisionSpeed >= 1.0f
&& (m_fCollisionSpeed >= 2.0f || m_nPedState != PED_WANDER_PATH)) {
m_collPoly.valid = false;
m_fCollisionSpeed = 0.0f;
bHitSteepSlope = false;
} else {
CVector pos = GetPosition();
float potentialGroundZ = GetPosition().z - FEET_OFFSET;
if (m_ped_flagA2) {
pos.z += -0.25f;
potentialGroundZ += gravityEffect;
}
if (CCollision::IsStoredPolyStillValidVerticalLine(pos, potentialGroundZ, intersectionPoint, &m_collPoly)) {
bStillOnValidPoly = true;
// VC conditionally sets GetPosition().z here with nonexisting flag in III
GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
m_vecMoveSpeed.z = 0.0f;
bIsStanding = true;
} else {
m_collPoly.valid = false;
m_fCollisionSpeed = 0.0f;
bHitSteepSlope = false;
}
}
}
if (!bStillOnValidPoly) {
CVector potentialCenter = GetPosition();
potentialCenter.z = GetPosition().z - 0.52f;
// 0.52f should be a ped's approx. radius
float totalRadiusWhenCollided = collidingEnt->GetBoundRadius() + 0.52f - gravityEffect;
if (m_ped_flagA2) {
if (collidedWithBoat) {
potentialCenter.z += 2.0f * gravityEffect;
totalRadiusWhenCollided += Abs(gravityEffect);
} else {
potentialCenter.z += gravityEffect;
}
}
if (sq(totalRadiusWhenCollided) > (potentialCenter - collidingEnt->GetBoundCentre()).MagnitudeSqr()) {
ourLine.p0 = GetPosition();
ourLine.p1 = GetPosition();
ourLine.p1.z = GetPosition().z - FEET_OFFSET;
if (m_ped_flagA2) {
ourLine.p1.z = ourLine.p1.z + gravityEffect;
ourLine.p0.z = ourLine.p0.z + -0.25f;
}
float minDist = 1.0f;
belowTorsoCollided = CCollision::ProcessVerticalLine(ourLine, collidingEnt->GetMatrix(), *hisCol,
intersectionPoint, minDist, false, &m_collPoly);
if (collidedWithBoat && m_ped_flagA2 && !belowTorsoCollided) {
ourLine.p0.z = ourLine.p1.z;
ourLine.p1.z = ourLine.p1.z + gravityEffect;
belowTorsoCollided = CCollision::ProcessVerticalLine(ourLine, collidingEnt->GetMatrix(), *hisCol,
intersectionPoint, minDist, false, &m_collPoly);
}
if (belowTorsoCollided) {
#ifndef VC_PED_PORTS
if (!collidingEnt->IsPed()) {
#endif
if (!bIsStanding
|| FEET_OFFSET + intersectionPoint.point.z > GetPosition().z
|| collidedWithBoat && 3.12f + intersectionPoint.point.z > GetPosition().z) {
if (!collidingEnt->IsVehicle() && !collidingEnt->IsObject()) {
m_pCurSurface = collidingEnt;
collidingEnt->RegisterReference((CEntity**)&m_pCurSurface);
m_ped_flagH10 = false;
bOnBoat = false;
} else {
m_pCurrentPhysSurface = collidingEnt;
collidingEnt->RegisterReference((CEntity**)m_pCurrentPhysSurface);
m_vecOffsetFromPhysSurface = intersectionPoint.point - collidingEnt->GetPosition();
m_pCurSurface = collidingEnt;
collidingEnt->RegisterReference((CEntity**)&m_pCurSurface);
m_collPoly.valid = false;
if (collidingEnt->IsVehicle() && ((CVehicle*)collidingEnt)->IsBoat()) {
bOnBoat = true;
} else {
bOnBoat = false;
}
}
// VC conditionally sets GetPosition().z here with nonexisting flag in III
GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
m_nSurfaceTouched = intersectionPoint.surfaceB;
if (m_nSurfaceTouched == SURFACE_STONE) {
bHitSteepSlope = true;
m_vecDamageNormal = intersectionPoint.normal;
}
}
#ifdef VC_PED_PORTS
float upperSpeedLimit = 0.33f;
float lowerSpeedLimit = -0.25f;
float speed = m_vecMoveSpeed.Magnitude2D();
if (m_nPedState == PED_IDLE) {
upperSpeedLimit *= 2.0f;
lowerSpeedLimit *= 1.5f;
}
if (m_ped_flagA2
|| (speed <= upperSpeedLimit /* || (bfFlagsL >> 5) & 1 */) && m_vecMoveSpeed.z >= lowerSpeedLimit
|| m_pCollidingEntity == collidingEnt) {
if (!m_ped_flagA2 && RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL)
&& -0.016f * CTimer::GetTimeStep() > m_vecMoveSpeed.z) {
InflictDamage(collidingEnt, WEAPONTYPE_FALL_DAMAGE, 15.0f, PEDPIECE_TORSO, 2);
}
} else {
float damage = 100.0f * max(speed - 0.25f, 0.0f);
float damage2 = damage;
if (m_vecMoveSpeed.z < -0.25f)
damage += (-0.25f - m_vecMoveSpeed.z) * 150.0f;
uint8 dir = 2; // from backward
if (m_vecMoveSpeed.x > 0.01f || m_vecMoveSpeed.x < -0.01f
|| m_vecMoveSpeed.y > 0.01f || m_vecMoveSpeed.y < -0.01f) {
CVector2D offset = -m_vecMoveSpeed;
dir = GetLocalDirection(offset);
}
InflictDamage(collidingEnt, WEAPONTYPE_FALL_DAMAGE, damage, PEDPIECE_TORSO, dir);
if (IsPlayer() && damage2 > 5.0f)
Say(SOUND_PED_LAND);
}
#else
float speedSqr = m_vecMoveSpeed.MagnitudeSqr();
if (m_ped_flagA2
|| m_vecMoveSpeed.z >= -0.25f && speedSqr <= 0.25f) {
if (!m_ped_flagA2 && RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL)
&& -0.016f * CTimer::GetTimeStep() > m_vecMoveSpeed.z) {
InflictDamage(collidingEnt, WEAPONTYPE_FALL_DAMAGE, 15.0f, PEDPIECE_TORSO, 2);
}
} else {
if (speedSqr == 0.0f)
speedSqr = sq(m_vecMoveSpeed.z);
uint8 dir = 2; // from backward
if (m_vecMoveSpeed.x > 0.01f || m_vecMoveSpeed.x < -0.01f
|| m_vecMoveSpeed.y > 0.01f || m_vecMoveSpeed.y < -0.01f) {
CVector2D offset = -m_vecMoveSpeed;
dir = GetLocalDirection(offset);
}
InflictDamage(collidingEnt, WEAPONTYPE_FALL_DAMAGE, 350.0f * sq(speedSqr), PEDPIECE_TORSO, dir);
}
#endif
m_vecMoveSpeed.z = 0.0f;
bIsStanding = true;
#ifndef VC_PED_PORTS
} else {
bOnBoat = false;
}
#endif
} else {
bOnBoat = false;
}
}
}
}
int ourCollidedSpheres = CCollision::ProcessColModels(GetMatrix(), *ourCol, collidingEnt->GetMatrix(), *hisCol, collidingPoints, nil, nil);
if (ourCollidedSpheres > 0 || belowTorsoCollided) {
AddCollisionRecord(collidingEnt);
if (!collidingEnt->IsBuilding())
((CPhysical*)collidingEnt)->AddCollisionRecord(this);
if (ourCollidedSpheres > 0 && (collidingEnt->IsBuilding() || collidingEnt->bIsStatic)) {
bHasHitWall = true;
}
}
if (collidingEnt->IsBuilding() || collidingEnt->bIsStatic) {
if (m_ped_flagA2) {
CVector sphereNormal;
float normalLength;
for(int sphere = 0; sphere < ourCollidedSpheres; sphere++) {
sphereNormal = collidingPoints[sphere].normal;
#ifdef VC_PED_PORTS
if (sphereNormal.z >= -1.0f || !IsPlayer()) {
#endif
normalLength = sphereNormal.Magnitude2D();
if (normalLength != 0.0f) {
sphereNormal.x = sphereNormal.x / normalLength;
sphereNormal.y = sphereNormal.y / normalLength;
}
#ifdef VC_PED_PORTS
} else {
float speed = m_vecMoveSpeed.Magnitude2D();
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
}
#endif
sphereNormal.Normalise();
collidingPoints[sphere].normal = sphereNormal;
if (collidingPoints[sphere].surfaceB == SURFACE_STONE)
bHitSteepSlope = true;
}
}
}
return ourCollidedSpheres;
}
class CPed_ : public CPed class CPed_ : public CPed
{ {
public: public:
@ -14060,6 +14309,7 @@ public:
void Teleport_(CVector pos) { CPed::Teleport(pos); } void Teleport_(CVector pos) { CPed::Teleport(pos); }
void ProcessControl_(void) { CPed::ProcessControl(); } void ProcessControl_(void) { CPed::ProcessControl(); }
void Render_(void) { CPed::Render(); } void Render_(void) { CPed::Render(); }
int32 ProcessEntityCollision_(CEntity *collidingEnt, CColPoint *collidingPoints) { return CPed::ProcessEntityCollision(collidingEnt, collidingPoints); }
}; };
STARTPATCHES STARTPATCHES
@ -14072,6 +14322,7 @@ STARTPATCHES
InjectHook(0x4D3E70, &CPed_::Teleport_, PATCH_JUMP); InjectHook(0x4D3E70, &CPed_::Teleport_, PATCH_JUMP);
InjectHook(0x4C8910, &CPed_::ProcessControl_, PATCH_JUMP); InjectHook(0x4C8910, &CPed_::ProcessControl_, PATCH_JUMP);
InjectHook(0x4D03F0, &CPed_::Render_, PATCH_JUMP); InjectHook(0x4D03F0, &CPed_::Render_, PATCH_JUMP);
InjectHook(0x4CBB30, &CPed_::ProcessEntityCollision_, PATCH_JUMP);
InjectHook(0x4CF8F0, &CPed::AddWeaponModel, PATCH_JUMP); InjectHook(0x4CF8F0, &CPed::AddWeaponModel, PATCH_JUMP);
InjectHook(0x4C6AA0, &CPed::AimGun, PATCH_JUMP); InjectHook(0x4C6AA0, &CPed::AimGun, PATCH_JUMP);

View File

@ -319,20 +319,20 @@ public:
uint8 bObstacleShowedUpDuringKillObjective : 1; uint8 bObstacleShowedUpDuringKillObjective : 1;
uint8 bDuckAndCover : 1; uint8 bDuckAndCover : 1;
uint8 m_ped_flagG1 : 1; uint8 bStillOnValidPoly : 1;
uint8 m_ped_flagG2 : 1; uint8 m_ped_flagG2 : 1;
uint8 m_ped_flagG4 : 1; // bStillOnValidPoly? uint8 m_ped_flagG4 : 1; // bResetWalkAnims?
uint8 bStartWanderPathOnFoot : 1; // exits the car if he's in it, reset after path found uint8 bStartWanderPathOnFoot : 1; // exits the car if he's in it, reset after path found
uint8 m_ped_flagG10 : 1; // bOnBoat? (but not in the sense of driving) uint8 bOnBoat : 1; // not just driver, may be just standing
uint8 bBusJacked : 1; uint8 bBusJacked : 1;
uint8 bGonnaKillTheCarJacker : 1; // only set when car is jacked from right door uint8 bGonnaKillTheCarJacker : 1; // only set when car is jacked from right door
uint8 bFadeOut : 1; uint8 bFadeOut : 1;
uint8 bKnockedUpIntoAir : 1; // NOT CERTAIN - has ped been knocked up into the air by a car collision uint8 bKnockedUpIntoAir : 1; // NOT CERTAIN - has ped been knocked up into the air by a car collision
uint8 m_ped_flagH2 : 1; uint8 bHitSteepSlope : 1; // has ped collided/is standing on a steep slope (surface type)
uint8 m_ped_flagH4 : 1; uint8 m_ped_flagH4 : 1;
uint8 bClearObjective : 1; uint8 bClearObjective : 1;
uint8 m_ped_flagH10 : 1; uint8 m_ped_flagH10 : 1; // bTryingToReachDryLand? reset when we landed on something not vehicle and object
uint8 bCollidedWithMyVehicle : 1; uint8 bCollidedWithMyVehicle : 1;
uint8 bRichFromMugging : 1; // ped has lots of cash from mugging people - will drop money if someone points gun to him uint8 bRichFromMugging : 1; // ped has lots of cash from mugging people - will drop money if someone points gun to him
uint8 m_ped_flagH80 : 1; uint8 m_ped_flagH80 : 1;