Merge pull request #266 from erorcun/erorcun

Peds & a few fixes
This commit is contained in:
erorcun 2019-11-05 15:05:47 +03:00 committed by GitHub
commit 996bc0293f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 387 additions and 28 deletions

View File

@ -354,6 +354,7 @@ DebugMenuPopulate(void)
#ifndef MASTER #ifndef MASTER
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil); DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil); DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
#endif #endif
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start); DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);

View File

@ -49,9 +49,6 @@ public:
CVector2D operator+(const CVector2D &rhs) const { CVector2D operator+(const CVector2D &rhs) const {
return CVector2D(x+rhs.x, y+rhs.y); return CVector2D(x+rhs.x, y+rhs.y);
} }
CVector2D operator*(float t) const {
return CVector2D(x*t, y*t);
}
CVector2D operator/(float t) const { CVector2D operator/(float t) const {
return CVector2D(x/t, y/t); return CVector2D(x/t, y/t);
} }
@ -91,3 +88,13 @@ NormalizeXY(float &x, float &y)
}else }else
x = 1.0f; x = 1.0f;
} }
inline CVector2D operator*(const CVector2D &left, float right)
{
return CVector2D(left.x * right, left.y * right);
}
inline CVector2D operator*(float left, const CVector2D &right)
{
return CVector2D(left * right.x, left * right.y);
}

View File

@ -49,16 +49,12 @@
#include "ParticleObject.h" #include "ParticleObject.h"
#include "Floater.h" #include "Floater.h"
WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); }
WRAPPER void CPed::SetPedPositionInCar(void) { EAXJMP(0x4D4970); }
WRAPPER void CPed::SetMoveAnim(void) { EAXJMP(0x4C5A40); } WRAPPER void CPed::SetMoveAnim(void) { EAXJMP(0x4C5A40); }
WRAPPER void CPed::UpdatePosition(void) { EAXJMP(0x4C7A00); }
WRAPPER void CPed::WanderPath(void) { EAXJMP(0x4D28D0); } WRAPPER void CPed::WanderPath(void) { EAXJMP(0x4D28D0); }
WRAPPER void CPed::SetEnterCar_AllClear(CVehicle*, uint32, uint32) { EAXJMP(0x4E0A40); } WRAPPER void CPed::SetEnterCar_AllClear(CVehicle*, uint32, uint32) { EAXJMP(0x4E0A40); }
WRAPPER bool CPed::WarpPedToNearEntityOffScreen(CEntity*) { EAXJMP(0x4E5570); } WRAPPER bool CPed::WarpPedToNearEntityOffScreen(CEntity*) { EAXJMP(0x4E5570); }
WRAPPER void CPed::SetObjective(eObjective, CVector) { EAXJMP(0x4D8A90); } WRAPPER void CPed::SetObjective(eObjective, CVector) { EAXJMP(0x4D8A90); }
WRAPPER void CPed::SetObjective(eObjective, CVector, float) { EAXJMP(0x4D8770); } WRAPPER void CPed::SetObjective(eObjective, CVector, float) { EAXJMP(0x4D8770); }
WRAPPER void CPed::WarpPedIntoCar(CVehicle*) { EAXJMP(0x4D7D20); }
WRAPPER void CPed::SetCarJack(CVehicle*) { EAXJMP(0x4E0220); } WRAPPER void CPed::SetCarJack(CVehicle*) { EAXJMP(0x4E0220); }
WRAPPER void CPed::WarpPedToNearLeaderOffScreen(void) { EAXJMP(0x4E52A0); } WRAPPER void CPed::WarpPedToNearLeaderOffScreen(void) { EAXJMP(0x4E52A0); }
@ -78,6 +74,8 @@ CPedAudioData (&CPed::CommentWaitTime)[38] = *(CPedAudioData(*)[38]) * (uintptr*
uint16 nPlayerInComboMove; uint16 nPlayerInComboMove;
RpClump *flyingClumpTemp;
// This is beta fistfite.dat array. Not used anymore since they're being fetched from fistfite.dat. // This is beta fistfite.dat array. Not used anymore since they're being fetched from fistfite.dat.
FightMove tFightMoves[NUM_FIGHTMOVES] = { FightMove tFightMoves[NUM_FIGHTMOVES] = {
{NUM_ANIMS, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0}, {NUM_ANIMS, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
@ -286,6 +284,7 @@ static char WaitStateText[][16] = {
#ifndef MASTER #ifndef MASTER
int nDisplayDebugInfo = 0; int nDisplayDebugInfo = 0;
bool CPed::bUnusedFightThingOnPlayer = false; bool CPed::bUnusedFightThingOnPlayer = false;
bool CPed::bPopHeadsOnHeadshot = false;
void void
CPed::SwitchDebugDisplay(void) CPed::SwitchDebugDisplay(void)
@ -878,7 +877,11 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
frame = GetNodeFrame(nodeId); frame = GetNodeFrame(nodeId);
if (frame) { if (frame) {
if (CGame::nastyGame) { if (CGame::nastyGame) {
#ifndef MASTER
if (bPopHeadsOnHeadshot || nodeId != PED_HEAD)
#else
if (nodeId != PED_HEAD) if (nodeId != PED_HEAD)
#endif
SpawnFlyingComponent(nodeId, direction); SpawnFlyingComponent(nodeId, direction);
RecurseFrameChildrenVisibilityCB(frame, nil); RecurseFrameChildrenVisibilityCB(frame, nil);
@ -1852,11 +1855,11 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
// Getting out // Getting out
if (!veh->bIsBus || (veh->bIsBus && vehIsUpsideDown)) { if (!veh->bIsBus || (veh->bIsBus && vehIsUpsideDown)) {
float pedZSpeedOnExit = m_vecMoveSpeed.z - 0.008f * CTimer::GetTimeStep(); float nextZSpeed = m_vecMoveSpeed.z - GRAVITY * CTimer::GetTimeStep();
// If we're not in ground at next step, apply animation // If we're not in ground at next step, apply animation
if (neededPos.z + pedZSpeedOnExit >= autoZPos.z) { if (neededPos.z + nextZSpeed >= autoZPos.z) {
m_vecMoveSpeed.z = pedZSpeedOnExit; m_vecMoveSpeed.z = nextZSpeed;
ApplyMoveSpeed(); ApplyMoveSpeed();
// Removing below line breaks the animation // Removing below line breaks the animation
neededPos.z = GetPosition().z; neededPos.z = GetPosition().z;
@ -6893,8 +6896,8 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
} }
#ifdef VC_PED_PORTS #ifdef VC_PED_PORTS
if (ped->m_pCurrentPhysSurface) { if (ped->m_pCurrentPhysSurface) {
ped->m_vecMoveSpeed.x += ((CPhysical*)ped->m_pCurrentPhysSurface)->m_vecMoveSpeed.x; ped->m_vecMoveSpeed.x += ped->m_pCurrentPhysSurface->m_vecMoveSpeed.x;
ped->m_vecMoveSpeed.y += ((CPhysical*)ped->m_pCurrentPhysSurface)->m_vecMoveSpeed.y; ped->m_vecMoveSpeed.y += ped->m_pCurrentPhysSurface->m_vecMoveSpeed.y;
} }
#endif #endif
} }
@ -8330,8 +8333,7 @@ CPed::InvestigateEvent(void)
bool bool
CPed::IsPedDoingDriveByShooting(void) CPed::IsPedDoingDriveByShooting(void)
{ {
if (this == FindPlayerPed() && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) { if (FindPlayerPed() == this && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) {
if (TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight) if (TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight)
return true; return true;
} }
@ -13638,7 +13640,7 @@ LocalPosForWalkAround(CVector2D colMin, CVector2D colMax, int walkAround, uint32
bool bool
CanWeSeeTheCorner(CVector2D dist, CVector2D fwdOffset) CanWeSeeTheCorner(CVector2D dist, CVector2D fwdOffset)
{ {
// because if dist is more then 5 unit, fov isn't important, we want shortest way // because fov isn't important if dist is more then 5 unit, we want shortest way
if (dist.Magnitude() > 5.0f) if (dist.Magnitude() > 5.0f)
return true; return true;
@ -13769,6 +13771,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
CVector cornerToGo = CVector(10.0f, 10.0f, 10.0f); CVector cornerToGo = CVector(10.0f, 10.0f, 10.0f);
int dirToGo; int dirToGo;
m_walkAroundType = 0; m_walkAroundType = 0;
int iWouldPreferGoingBack = 0; // 1:left 2:right
#endif #endif
float adjustedCheckInterval = 0.7f * checkIntervalInDist; float adjustedCheckInterval = 0.7f * checkIntervalInDist;
CVector posToCheck; CVector posToCheck;
@ -13796,6 +13799,9 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) {
cornerToGo = tl; cornerToGo = tl;
m_walkAroundType = 1; m_walkAroundType = 1;
if (m_vehEnterType == CAR_DOOR_LR)
iWouldPreferGoingBack = 1;
} else if(CanWeSeeTheCorner(tl, GetForward())){ } else if(CanWeSeeTheCorner(tl, GetForward())){
cornerToGo = tl; cornerToGo = tl;
dirToGo = GetLocalDirection(tl); dirToGo = GetLocalDirection(tl);
@ -13831,6 +13837,9 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) {
cornerToGo = tr; cornerToGo = tr;
m_walkAroundType = 2; m_walkAroundType = 2;
if (m_vehEnterType == CAR_DOOR_RR)
iWouldPreferGoingBack = 2;
} else if (CanWeSeeTheCorner(tr, GetForward())) { } else if (CanWeSeeTheCorner(tr, GetForward())) {
cornerToGo = tr; cornerToGo = tr;
dirToGo = GetLocalDirection(tr); dirToGo = GetLocalDirection(tr);
@ -13863,7 +13872,9 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
#ifdef NEW_WALK_AROUND_ALGORITHM #ifdef NEW_WALK_AROUND_ALGORITHM
else { else {
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 (iWouldPreferGoingBack == 2)
m_walkAroundType = 4;
else if (br.Magnitude2D() < cornerToGo.Magnitude2D()) {
if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) {
cornerToGo = br; cornerToGo = br;
m_walkAroundType = 5; m_walkAroundType = 5;
@ -13899,7 +13910,9 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
#ifdef NEW_WALK_AROUND_ALGORITHM #ifdef NEW_WALK_AROUND_ALGORITHM
else { else {
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 (iWouldPreferGoingBack == 1)
m_walkAroundType = 7;
else if (bl.Magnitude2D() < cornerToGo.Magnitude2D()) {
if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) {
cornerToGo = bl; cornerToGo = bl;
m_walkAroundType = 6; m_walkAroundType = 6;
@ -14300,7 +14313,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
m_ped_flagH10 = false; m_ped_flagH10 = false;
bOnBoat = false; bOnBoat = false;
} else { } else {
m_pCurrentPhysSurface = collidingEnt; m_pCurrentPhysSurface = (CPhysical*)collidingEnt;
collidingEnt->RegisterReference((CEntity**)&m_pCurrentPhysSurface); collidingEnt->RegisterReference((CEntity**)&m_pCurrentPhysSurface);
m_vecOffsetFromPhysSurface = intersectionPoint.point - collidingEnt->GetPosition(); m_vecOffsetFromPhysSurface = intersectionPoint.point - collidingEnt->GetPosition();
m_pCurSurface = collidingEnt; m_pCurSurface = collidingEnt;
@ -14505,7 +14518,7 @@ CPed::WillChat(CPed *stranger)
} }
if (m_nSurfaceTouched == SURFACE_TARMAC) if (m_nSurfaceTouched == SURFACE_TARMAC)
return false; return false;
if (this == stranger) if (stranger == this)
return false; return false;
if (m_nPedType == stranger->m_nPedType) if (m_nPedType == stranger->m_nPedType)
return true; return true;
@ -14784,7 +14797,7 @@ CPed::ProcessBuoyancy(void)
float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.8f : 1.1f); float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.8f : 1.1f);
#endif #endif
if (mod_Buoyancy.ProcessBuoyancy(this, 0.008f * m_fMass * buoyancyLevel, &buoyancyPoint, &buoyancyImpulse)) { if (mod_Buoyancy.ProcessBuoyancy(this, GRAVITY * m_fMass * buoyancyLevel, &buoyancyPoint, &buoyancyImpulse)) {
m_flagD8 = true; m_flagD8 = true;
CEntity *entity; CEntity *entity;
CColPoint point; CColPoint point;
@ -16209,6 +16222,338 @@ CPed::UpdateFromLeader(void)
} }
} }
void
CPed::UpdatePosition(void)
{
if (CReplay::IsPlayingBack() || !bIsStanding)
return;
CVector2D velocityChange;
SetHeading(m_fRotationCur);
if (m_pCurrentPhysSurface) {
CVector2D velocityOfSurface;
CPhysical *curSurface = m_pCurrentPhysSurface;
if (!IsPlayer() && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat()) {
// It seems R* didn't like m_vecOffsetFromPhysSurface for boats
CVector offsetToSurface = GetPosition() - curSurface->GetPosition();
offsetToSurface.z -= FEET_OFFSET;
CVector surfaceMoveVelocity = curSurface->m_vecMoveSpeed;
CVector surfaceTurnVelocity = CrossProduct(curSurface->m_vecTurnSpeed, offsetToSurface);
// Also we use that weird formula instead of friction if it's boat
float slideMult = -curSurface->m_vecTurnSpeed.MagnitudeSqr();
velocityOfSurface = slideMult * offsetToSurface * CTimer::GetTimeStep() + (surfaceTurnVelocity + surfaceMoveVelocity);
m_vecMoveSpeed.z = slideMult * offsetToSurface.z * CTimer::GetTimeStep() + (surfaceTurnVelocity.z + surfaceMoveVelocity.z);
} else {
velocityOfSurface = curSurface->GetSpeed(m_vecOffsetFromPhysSurface);
}
// Reminder: m_moved is displacement from walking/running.
velocityChange = m_moved + velocityOfSurface - m_vecMoveSpeed;
m_fRotationCur += curSurface->m_vecTurnSpeed.z * CTimer::GetTimeStep();
m_fRotationDest += curSurface->m_vecTurnSpeed.z * CTimer::GetTimeStep();
} else if (m_nSurfaceTouched != SURFACE_STONE || m_vecDamageNormal.x == 0.0f && m_vecDamageNormal.y == 0.0f) {
velocityChange = m_moved - m_vecMoveSpeed;
} else {
// Ped got damaged by steep slope
m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.001f);
// some kind of
CVector2D reactionForce = m_vecDamageNormal * (1.0f / m_vecDamageNormal.Magnitude2D());
velocityChange = 0.02f * reactionForce + m_moved;
float reactionAndVelocityDotProd = DotProduct2D(reactionForce, velocityChange);
// they're in same direction
if (reactionAndVelocityDotProd < 0.0f) {
velocityChange -= reactionAndVelocityDotProd * reactionForce;
}
}
// Take time step into account
if (m_pCurrentPhysSurface) {
float speedChange = velocityChange.Magnitude();
float changeMult = speedChange;
if (m_nPedState != PED_DIE || !m_pCurrentPhysSurface->IsVehicle()) {
if (!m_pCurrentPhysSurface->IsVehicle() || !((CVehicle*)m_pCurrentPhysSurface)->IsBoat())
changeMult = 0.01f * CTimer::GetTimeStep();
} else {
changeMult = 0.002f * CTimer::GetTimeStep();
}
if (speedChange > changeMult) {
velocityChange = velocityChange * (changeMult / speedChange);
}
}
m_vecMoveSpeed.x += velocityChange.x;
m_vecMoveSpeed.y += velocityChange.y;
}
void
CPed::SetPedPositionInCar(void)
{
if (CReplay::IsPlayingBack())
return;
if (bChangedSeat) {
bool notYet = false;
if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LHS)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LOW_LHS)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LHS)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LOW_LHS)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SHUFFLE_RHS)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSHUFFLE_RHS)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE_L)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN_L)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_L)
|| RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_R)) {
notYet = true;
}
if (notYet) {
LineUpPedWithCar(LINE_UP_TO_CAR_START);
bChangedSeat = false;
return;
}
}
CVehicleModelInfo *vehModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(m_pMyVehicle->m_modelIndex);
CMatrix newMat(m_pMyVehicle->GetMatrix());
CVector seatPos;
if (m_pMyVehicle->pDriver == this) {
if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT)
seatPos = vehModel->m_positions[BOAT_POS_FRONTSEAT];
else
seatPos = vehModel->m_positions[CAR_POS_FRONTSEAT];
if (!m_pMyVehicle->IsBoat() && m_pMyVehicle->m_vehType != VEHICLE_TYPE_BIKE)
seatPos.x = -seatPos.x;
} else if (m_pMyVehicle->pPassengers[0] == this) {
if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT)
seatPos = vehModel->m_positions[BOAT_POS_FRONTSEAT];
else
seatPos = vehModel->m_positions[CAR_POS_FRONTSEAT];
} else if (m_pMyVehicle->pPassengers[1] == this) {
seatPos = vehModel->m_positions[CAR_POS_BACKSEAT];
seatPos.x = -seatPos.x;
} else {
if (m_pMyVehicle->pPassengers[2] == this) {
seatPos = vehModel->m_positions[CAR_POS_BACKSEAT];
} else if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) {
seatPos = vehModel->m_positions[BOAT_POS_FRONTSEAT];
} else {
seatPos = vehModel->m_positions[CAR_POS_FRONTSEAT];
}
}
newMat.GetPosition() += Multiply3x3(newMat, seatPos);
// Already done below (SetTranslate(0.0f, 0.0f, 0.0f))
// tempMat.SetUnity();
// Rear seats on vans don't face to front, so rotate them HALFPI.
if (m_pMyVehicle->bIsVan) {
CMatrix tempMat;
if (m_pMyVehicle->pPassengers[1] == this) {
m_fRotationCur = m_pMyVehicle->GetForward().Heading() - HALFPI;
tempMat.SetTranslate(0.0f, 0.0f, 0.0f);
tempMat.RotateZ(-HALFPI);
newMat = newMat * tempMat;
} else if (m_pMyVehicle->pPassengers[2] == this) {
m_fRotationCur = HALFPI + m_pMyVehicle->GetForward().Heading();
tempMat.SetTranslate(0.0f, 0.0f, 0.0f);
tempMat.RotateZ(HALFPI);
newMat = newMat * tempMat;
} else {
m_fRotationCur = m_pMyVehicle->GetForward().Heading();
}
} else {
m_fRotationCur = m_pMyVehicle->GetForward().Heading();
}
GetMatrix() = newMat;
}
static RwObject*
CloneAtomicToFrameCB(RwObject *frame, void *data)
{
RpAtomic *newAtomic = RpAtomicClone((RpAtomic*)frame);
RpAtomicSetFrame(newAtomic, (RwFrame*)data);
RpClumpAddAtomic(flyingClumpTemp, newAtomic);
CVisibilityPlugins::SetAtomicRenderCallback(newAtomic, nil);
return frame;
}
static RwFrame*
RecurseFrameChildrenToCloneCB(RwFrame *frame, void *data)
{
RwFrame *newFrame = RwFrameCreate();
RwFrameAddChild((RwFrame*)data, newFrame);
RwFrameTransform(newFrame, RwFrameGetMatrix(frame), rwCOMBINEREPLACE);
RwFrameForAllObjects(frame, CloneAtomicToFrameCB, newFrame);
RwFrameForAllChildren(frame, RecurseFrameChildrenToCloneCB, newFrame);
return newFrame;
}
CObject*
CPed::SpawnFlyingComponent(int pedNode, int8 direction)
{
if (CObject::nNoTempObjects >= NUMTEMPOBJECTS)
return nil;
CObject *obj = new CObject();
if (!obj)
return nil;
RwFrame *frame = RwFrameCreate();
RpClump *clump = RpClumpCreate();
RpClumpSetFrame(clump, frame);
RwMatrix *matrix = RwFrameGetLTM(GetNodeFrame(pedNode));
*RwFrameGetMatrix(frame) = *matrix;
flyingClumpTemp = clump;
RwFrameForAllObjects(GetNodeFrame(pedNode), CloneAtomicToFrameCB, frame);
RwFrameForAllChildren(GetNodeFrame(pedNode), RecurseFrameChildrenToCloneCB, frame);
flyingClumpTemp = nil;
switch (pedNode) {
case PED_HEAD:
// So popping head would have wheel collision. They disabled it anyway
obj->SetModelIndexNoCreate(MI_CAR_WHEEL);
break;
case PED_UPPERARML:
case PED_UPPERARMR:
obj->SetModelIndexNoCreate(MI_BODYPARTB);
obj->SetCenterOfMass(0.25f, 0.0f, 0.0f);
break;
case PED_UPPERLEGL:
case PED_UPPERLEGR:
obj->SetModelIndexNoCreate(MI_BODYPARTA);
obj->SetCenterOfMass(0.4f, 0.0f, 0.0f);
break;
default:
break;
}
obj->RefModelInfo(m_modelIndex);
obj->AttachToRwObject((RwObject*)clump);
obj->m_fMass = 15.0f;
obj->m_fTurnMass = 5.0f;
obj->m_fAirResistance = 0.99f;
obj->m_fElasticity = 0.03f;
obj->m_fBuoyancy = m_fMass*GRAVITY/0.75f;
obj->ObjectCreatedBy = TEMP_OBJECT;
obj->bIsStatic = false;
obj->bIsPickup = false;
obj->m_nSpecialCollisionResponseCases = COLLRESPONSE_SPLIT_MODEL;
// life time - the more objects the are, the shorter this one will live
CObject::nNoTempObjects++;
if (CObject::nNoTempObjects > 20)
obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 12000;
else if (CObject::nNoTempObjects > 10)
obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 30000;
else
obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 60000;
CVector localForcePos, forceDir;
if (direction == 2) {
obj->m_vecMoveSpeed = 0.03f * GetForward();
obj->m_vecMoveSpeed.z = (CGeneral::GetRandomNumber() & 0x3F) * 0.001f;
obj->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
localForcePos = CVector(0.0f, 0.0f, 0.0f);
forceDir = GetForward();
} else {
obj->m_vecMoveSpeed = -0.03f * GetForward();
obj->m_vecMoveSpeed.z = (CGeneral::GetRandomNumber() & 0x3F) * 0.001f;
obj->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
localForcePos = CVector(0.0f, 0.0f, 0.0f);
forceDir = -GetForward();
}
obj->ApplyTurnForce(forceDir, localForcePos);
CWorld::Add(obj);
return obj;
}
void
CPed::WarpPedIntoCar(CVehicle *car)
{
bInVehicle = true;
m_pMyVehicle = car;
m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
m_carInObjective = car;
m_carInObjective->RegisterReference((CEntity **) &m_carInObjective);
m_nPedState = PED_DRIVING;
bUsesCollision = false;
bIsInTheAir = false;
m_ped_flagI4 = true;
if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
car->SetDriver(this);
car->pDriver->RegisterReference((CEntity **) &car->pDriver);
} else if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
for (int i = 0; i < 4; i++) {
if (!car->pPassengers[i]) {
car->pPassengers[i] = this;
car->pPassengers[i]->RegisterReference((CEntity **) &car->pPassengers[i]);
break;
}
}
} else
return;
if (IsPlayer()) {
car->m_status = STATUS_PLAYER;
AudioManager.PlayerJustGotInCar();
CCarCtrl::RegisterVehicleOfInterest(car);
} else {
car->m_status = STATUS_PHYSICS;
}
CWorld::Remove(this);
GetPosition() = car->GetPosition();
CWorld::Add(this);
if (car->bIsAmbulanceOnDuty) {
car->bIsAmbulanceOnDuty = false;
--CCarCtrl::NumAmbulancesOnDuty;
}
if (car->bIsFireTruckOnDuty) {
car->bIsFireTruckOnDuty = false;
--CCarCtrl::NumFiretrucksOnDuty;
}
if (!car->bEngineOn) {
car->bEngineOn = true;
DMAudio.PlayOneShot(car->m_audioEntityId, SOUND_CAR_ENGINE_START, 1.0f);
}
if (car->IsBoat()) {
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f);
CWeaponInfo *ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
RemoveWeaponModel(ourWeapon->m_nModelId);
} else {
// Because we can use Uzi for drive by
// RemoveWeaponWhenEnteringVehicle in VC
if (IsPlayer() && HasWeapon(WEAPONTYPE_UZI) && GetWeapon(WEAPONTYPE_UZI).m_nAmmoTotal > 0) {
if (m_storedWeapon == WEAPONTYPE_UNIDENTIFIED)
m_storedWeapon = GetWeapon()->m_eWeaponType;
SetCurrentWeapon(WEAPONTYPE_UZI);
} else {
CWeaponInfo *ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
RemoveWeaponModel(ourWeapon->m_nModelId);
}
if (car->bLowVehicle)
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_LSIT, 100.0f);
else
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
}
StopNonPartialAnims();
if (car->bIsBus)
bRenderPedInCar = false;
bChangedSeat = true;
}
class CPed_ : public CPed class CPed_ : public CPed
{ {
public: public:
@ -16430,4 +16775,6 @@ STARTPATCHES
InjectHook(0x4E5870, &CPed::ServiceTalking, PATCH_JUMP); InjectHook(0x4E5870, &CPed::ServiceTalking, PATCH_JUMP);
InjectHook(0x4E7780, &CPed::StartFightDefend, PATCH_JUMP); InjectHook(0x4E7780, &CPed::StartFightDefend, PATCH_JUMP);
InjectHook(0x4D8F30, &CPed::UpdateFromLeader, PATCH_JUMP); InjectHook(0x4D8F30, &CPed::UpdateFromLeader, PATCH_JUMP);
InjectHook(0x4D4970, &CPed::SetPedPositionInCar, PATCH_JUMP);
InjectHook(0x4D7D20, &CPed::WarpPedIntoCar, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

@ -15,6 +15,7 @@
struct CPathNode; struct CPathNode;
class CAccident; class CAccident;
class CObject;
struct CPedAudioData struct CPedAudioData
{ {
@ -362,7 +363,7 @@ public:
uint8 bShakeFist : 1; // test shake hand at look entity uint8 bShakeFist : 1; // test shake hand at look entity
uint8 bNoCriticalHits : 1; // if set, limbs won't came off uint8 bNoCriticalHits : 1; // if set, limbs won't came off
uint8 m_ped_flagI4 : 1; // seems like related with cars uint8 m_ped_flagI4 : 1; // we've been put to car by script? - related with cars
uint8 bHasAlreadyBeenRecorded : 1; uint8 bHasAlreadyBeenRecorded : 1;
uint8 bFallenDown : 1; uint8 bFallenDown : 1;
#ifdef VC_PED_PORTS #ifdef VC_PED_PORTS
@ -430,7 +431,7 @@ public:
float m_headingRate; float m_headingRate;
uint16 m_vehEnterType; // TODO: this is more like a door, not a type uint16 m_vehEnterType; // TODO: this is more like a door, not a type
int16 m_walkAroundType; int16 m_walkAroundType;
CEntity *m_pCurrentPhysSurface; CPhysical *m_pCurrentPhysSurface;
CVector m_vecOffsetFromPhysSurface; CVector m_vecOffsetFromPhysSurface;
CEntity *m_pCurSurface; CEntity *m_pCurSurface;
CVector m_vecSeekPos; CVector m_vecSeekPos;
@ -532,7 +533,6 @@ public:
void SetDead(void); void SetDead(void);
void ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer); void ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer);
void RemoveBodyPart(PedNode nodeId, int8 direction); void RemoveBodyPart(PedNode nodeId, int8 direction);
void SpawnFlyingComponent(int, int8);
bool OurPedCanSeeThisOne(CEntity *target); bool OurPedCanSeeThisOne(CEntity *target);
void Avoid(void); void Avoid(void);
void Attack(void); void Attack(void);
@ -670,7 +670,6 @@ public:
void ProcessBuoyancy(void); void ProcessBuoyancy(void);
void ServiceTalking(void); void ServiceTalking(void);
void SetJump(void); void SetJump(void);
void UpdatePosition(void);
void WanderPath(void); void WanderPath(void);
void ReactToPointGun(CEntity*); void ReactToPointGun(CEntity*);
void SeekCar(void); void SeekCar(void);
@ -767,6 +766,8 @@ public:
void WanderRange(void); void WanderRange(void);
void SetFollowRoute(int16, int16); void SetFollowRoute(int16, int16);
void SeekBoatPosition(void); void SeekBoatPosition(void);
void UpdatePosition(void);
CObject *SpawnFlyingComponent(int, int8);
#ifdef VC_PED_PORTS #ifdef VC_PED_PORTS
bool CanPedJumpThis(CEntity*, CVector*); bool CanPedJumpThis(CEntity*, CVector*);
#else #else
@ -796,9 +797,12 @@ public:
static CPedAudioData (&CommentWaitTime)[38]; static CPedAudioData (&CommentWaitTime)[38];
#ifndef MASTER #ifndef MASTER
static bool bUnusedFightThingOnPlayer;
static bool bPopHeadsOnHeadshot;
// Mobile things
static void SwitchDebugDisplay(void); static void SwitchDebugDisplay(void);
void DebugRenderOnePedText(void); void DebugRenderOnePedText(void);
static bool bUnusedFightThingOnPlayer;
#endif #endif
}; };

View File

@ -2474,8 +2474,8 @@ CAutomobile::TankControl(void)
int lifeSpan = 250; int lifeSpan = 250;
if(m_vecMoveSpeed.Magnitude() > 0.08f){ if(m_vecMoveSpeed.Magnitude() > 0.08f){
lifeSpan = 125; lifeSpan = 125;
flashPos.x += 0.5f*m_vecMoveSpeed.x; flashPos.x += 5.0f*m_vecMoveSpeed.x;
flashPos.y += 0.5f*m_vecMoveSpeed.y; flashPos.y += 5.0f*m_vecMoveSpeed.y;
} }
CParticle::AddParticle(PARTICLE_GUNFLASH, flashPos, nullDir, nil, 0.4f, black, 0, 0, 0, lifeSpan); CParticle::AddParticle(PARTICLE_GUNFLASH, flashPos, nullDir, nil, 0.4f, black, 0, 0, 0, lifeSpan);
flashPos += 0.3f*shotDir; flashPos += 0.3f*shotDir;
@ -4210,7 +4210,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
if(atomic == nil) if(atomic == nil)
return nil; return nil;
obj = new CObject; obj = new CObject();
if(obj == nil) if(obj == nil)
return nil; return nil;