diff options
Diffstat (limited to 'src/entities/Ped.cpp')
-rw-r--r-- | src/entities/Ped.cpp | 2949 |
1 files changed, 0 insertions, 2949 deletions
diff --git a/src/entities/Ped.cpp b/src/entities/Ped.cpp deleted file mode 100644 index 055ea3fb..00000000 --- a/src/entities/Ped.cpp +++ /dev/null @@ -1,2949 +0,0 @@ -#include "common.h" -#include "patcher.h" -#include "main.h" -#include "Pools.h" -#include "Particle.h" -#include "Stats.h" -#include "World.h" -#include "DMAudio.h" -#include "RpAnimBlend.h" -#include "Ped.h" -#include "PlayerPed.h" -#include "General.h" -#include "VisibilityPlugins.h" -#include "AudioManager.h" -#include "HandlingMgr.h" -#include "Replay.h" -#include "PedPlacement.h" -#include "Shadows.h" -#include "Weather.h" -#include "CullZones.h" -#include "Population.h" -#include "Renderer.h" -#include "Lights.h" -#include "PointLights.h" -#include "Pad.h" - -WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); } -WRAPPER void CPed::Say(uint16 audio) { EAXJMP(0x4E5A10); } -WRAPPER void CPed::SetDie(AnimationId anim, float arg1, float arg2) { EAXJMP(0x4D37D0); } -WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); } -WRAPPER void CPed::RestorePreviousState(void) { EAXJMP(0x4C5E30); } -WRAPPER void CPed::ClearAttack(void) { EAXJMP(0x4E6790); } -WRAPPER void CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *dragAssoc, void *arg) { EAXJMP(0x4E2480); } -WRAPPER void CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation *dragAssoc, void *arg) { EAXJMP(0x4E2920); } -WRAPPER void CPed::SetPedPositionInCar(void) { EAXJMP(0x4D4970); } -WRAPPER void CPed::ProcessControl(void) { EAXJMP(0x4C8910); } -WRAPPER void CPed::PreRender(void) { EAXJMP(0x4CFDD0); } -WRAPPER void CPed::Render(void) { EAXJMP(0x4D03F0); } -WRAPPER int32 CPed::ProcessEntityCollision(CEntity*, CColPoint*) { EAXJMP(0x4CBB30); } -WRAPPER void CPed::SetMoveAnim(void) { EAXJMP(0x4C5A40); } -WRAPPER void CPed::SetFollowRoute(int16, int16) { EAXJMP(0x4DD690); } -WRAPPER void CPed::SetDuck(uint32) { EAXJMP(0x4E4920); } -WRAPPER void CPed::RegisterThreatWithGangPeds(CEntity*) { EAXJMP(0x4E3870); } - -bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44; -bool &CPed::bPedCheat2 = *(bool*)0x95CD5A; -bool &CPed::bPedCheat3 = *(bool*)0x95CD59; - -uint16 &CPed::distanceMultToCountPedNear = *(uint16*)0x5F8C98; - -CVector &CPed::offsetToOpenRegularCarDoor = *(CVector*)0x62E030; -CVector &CPed::offsetToOpenLowCarDoor = *(CVector*)0x62E03C; -CVector &CPed::offsetToOpenVanDoor = *(CVector*)0x62E048; - -void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); } -void *CPed::operator new(size_t sz, int handle) { return CPools::GetPedPool()->New(handle); } -void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); } -void CPed::operator delete(void *p, int handle) { CPools::GetPedPool()->Delete((CPed*)p); } - -CPed::~CPed(void) -{ - CWorld::Remove(this); - CRadar::ClearBlipForEntity(BLIP_CHAR, CPools::GetPedPool()->GetIndex(this)); - if (bInVehicle && m_pMyVehicle){ - uint8 door_flag = GetVehEnterExitFlag(m_vehEnterType); - if (m_pMyVehicle->pDriver == this) - m_pMyVehicle->pDriver = nil; - else { - for (int i = 0; i < m_pMyVehicle->m_nNumMaxPassengers; i++) { - if (m_pMyVehicle->pPassengers[i] == this) - m_pMyVehicle->pPassengers[i] = nil; - } - } - if (m_nPedState == PED_EXIT_CAR || m_nPedState == PED_DRAG_FROM_CAR) - m_pMyVehicle->m_nGettingOutFlags &= ~door_flag; - bInVehicle = false; - m_pMyVehicle = nil; - }else if (m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK){ - QuitEnteringCar(); - } - if (m_pFire) - m_pFire->Extinguish(); - CPopulation::UpdatePedCount(m_nPedType, true); - DMAudio.DestroyEntity(m_audioEntityId); -} - -void -CPed::FlagToDestroyWhenNextProcessed(void) -{ - bRemoveFromWorld = true; - if (!bInVehicle || !m_pMyVehicle) - return; - if (m_pMyVehicle->pDriver == this){ - m_pMyVehicle->pDriver = nil; - if (IsPlayer() && m_pMyVehicle->m_status != STATUS_WRECKED) - m_pMyVehicle->m_status = STATUS_ABANDONED; - }else{ - m_pMyVehicle->RemovePassenger(this); - } - bInVehicle = false; - m_pMyVehicle = nil; - if (CharCreatedBy == MISSION_CHAR) - m_nPedState = PED_DEAD; - else - m_nPedState = PED_NONE; - m_pVehicleAnim = nil; -} - -static char ObjectiveText[34][28] = { - "No Obj", - "Wait on Foot", - "Flee on Foot Till Safe", - "Guard Spot", - "Guard Area", - "Wait in Car", - "Wait in Car then Getout", - "Kill Char on Foot", - "Kill Char Any Means", - "Flee Char on Foot Till Safe", - "Flee Char on Foot Always", - "GoTo Char on Foot", - "Follow Char in Formation", - "Leave Car", - "Enter Car as Passenger", - "Enter Car as Driver", - "Follow Car in Car", - "Fire at Obj from Vehicle", - "Destroy Obj", - "Destroy Car", - "GoTo Area Any Means", - "GoTo Area on Foot", - "Run to Area", - "GoTo Area in Car", - "Follow Car on Foot Woffset", - "Guard Attack", - "Set Leader", - "Follow Route", - "Solicit", - "Take Taxi", - "Catch Train", - "Buy IceCream", - "Steal Any Car", - "Mug Char", -}; - -static char StateText[56][18] = { - "None", // 1 - "Idle", - "Look Entity", - "Look Heading", - "Wander Range", - "Wander Path", - "Seek Pos", - "Seek Entity", - "Flee Pos", - "Flee Entity", - "Pursue", - "Follow Path", - "Sniper Mode", - "Rocket Mode", - "Dummy", - "Pause", - "Attack", - "Fight", - "Face Phone", - "Make Call", - "Chat", - "Mug", - "AimGun", - "AI Control", - "Seek Car", - "Seek InBoat", - "Follow Route", - "C.P.R.", - "Solicit", - "Buy IceCream", - "Investigate", - "Step away", - "STATES_NO_AI", - "On Fire", - "Jump", - "Fall", - "GetUp", - "Stagger", - "Dive away", - "STATES_NO_ST", - "Enter Train", - "Exit Train", - "Arrest Plyr", - "Driving", - "Passenger", - "Taxi Passngr", - "Open Door", - "Die", - "Dead", - "CarJack", - "Drag fm Car", - "Enter Car", - "Steal Car", - "Exit Car", - "Hands Up", - "Arrested", -}; - -static char PersonalityTypeText[32][18] = { - "Player", - "Cop", - "Medic", - "Fireman", - "Gang 1", - "Gang 2", - "Gang 3", - "Gang 4", - "Gang 5", - "Gang 6", - "Gang 7", - "Street Guy", - "Suit Guy", - "Sensible Guy", - "Geek Guy", - "Old Guy", - "Tough Guy", - "Street Girl", - "Suit Girl", - "Sensible Girl", - "Geek Girl", - "Old Girl", - "Tough Girl", - "Tramp", - "Tourist", - "Prostitute", - "Criminal", - "Busker", - "Taxi Driver", - "Psycho", - "Steward", - "Sports Fan", -}; - -static char WaitStateText[21][16] = { - "No Wait", - "Traffic Lights", - "Pause CrossRoad", - "Look CrossRoad", - "Look Ped", - "Look Shop", - "Look Accident", - "FaceOff Gang", - "Double Back", - "Hit Wall", - "Turn 180deg", - "Surprised", - "Ped Stuck", - "Look About", - "Play Duck", - "Play Cower", - "Play Taxi", - "Play HandsUp", - "Play HandsCower", - "Play Chat", - "Finish Flee", -}; - -CPed::CPed(uint32 pedType) : m_pedIK(this) -{ - m_type = ENTITY_TYPE_PED; - bPedPhysics = true; - bUseCollisionRecords = true; - - m_vecAnimMoveDelta.x = 0.0; - m_vecAnimMoveDelta.y = 0.0; - m_fHealth = 100.0f; - m_fArmour = 0.0f; - m_nPedType = pedType; - field_520 = 0; - m_talkTimer = 0; - m_talkTypeLast = 167; - m_talkType = 167; - m_objective = OBJECTIVE_NONE; - m_prevObjective = OBJECTIVE_NONE; - CharCreatedBy = RANDOM_CHAR; - m_leader = nil; - m_pedInObjective = nil; - m_carInObjective = nil; - bInVehicle = 0; - m_pMyVehicle = nil; - m_pVehicleAnim = nil; - m_vecOffsetSeek.x = 0.0; - m_vecOffsetSeek.y = 0.0; - m_vecOffsetSeek.z = 0.0; - m_pedFormation = 0; - m_lastThreatTimer = 0; - m_nPedStateTimer = 0; - m_actionX = 0; - m_actionY = 0; - m_phoneTalkTimer = 0; - m_stateUnused = 0; - m_leaveCarTimer = 0; - m_getUpTimer = 0; - m_attackTimer = 0; - m_timerUnused = 0; - m_lookTimer = 0; - m_standardTimer = 0; - m_lastHitTime = 0; - m_hitRecoverTimer = 0; - field_4E8 = 0; - m_moved = CVector2D(0.0f, 0.0f); - m_fRotationCur = 0.0f; - m_headingRate = 15.0f; - m_fRotationDest = 0.0f; - m_vehEnterType = VEHICLE_ENTER_FRONT_LEFT; - m_walkAroundType = 0; - m_pCurrentPhysSurface = nil; - m_vecOffsetFromPhysSurface = CVector(0.0f, 0.0f, 0.0f); - m_pSeekTarget = nil; - m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f); - m_wepSkills = 0; - field_318 = 1.0f; - field_31C = 0; - m_phoneId = -1; - m_lastAccident = 0; - m_fleeFrom = nil; - m_fleeFromPosX = 0; - m_fleeFromPosY = 0; - m_fleeTimer = 0; - m_vecSeekPosEx = CVector(0.0f, 0.0f, 0.0f); - m_seekExAngle = 0.0f; - m_nWaitState = WAITSTATE_FALSE; - m_nWaitTimer = 0; - m_pCollidingEntity = nil; - m_nPedState = PED_IDLE; - m_nLastPedState = PED_NONE; - m_nMoveState = PEDMOVE_STILL; - m_nStoredActionState = 0; - m_pFire = nil; - m_pPointGunAt = nil; - m_pLookTarget = nil; - m_fLookDirection = 0.0f; - m_pCurSurface = nil; - m_targetUnused = nil; - m_nPathNodes = 0; - m_nCurPathNode = 0; - m_nPathState = 0; - m_pNextPathNode = nil; - m_pLastPathNode = nil; - m_routeLastPoint = -1; - m_routePoints = 0; - m_routePos = 0; - m_routeType = 0; - m_bodyPartBleeding = -1; - - m_fMass = 70.0f; - m_fTurnMass = 100.0f; - m_fAirResistance = 0.4f / m_fMass; - m_fElasticity = 0.05f; - - bIsStanding = false; - m_ped_flagA2 = false; - m_ped_flagA4 = false; - bIsPointingGunAt = false; - bIsLooking = false; - m_ped_flagA20 = false; - bIsRestoringLook = false; - bIsAimingGun = false; - - bIsRestoringGun = false; - bCanPointGunAtTarget = false; - bIsTalking = false; - bIsInTheAir = false; - bIsLanding = false; - m_ped_flagB20 = false; - m_ped_flagB40 = false; - m_ped_flagB80 = false; - - m_ped_flagC1 = false; - bRespondsToThreats = true; - m_ped_flagC4 = true; - m_ped_flagC8 = false; - m_ped_flagC10 = false; - m_ped_flagC20 = false; - m_ped_flagC40 = false; - m_ped_flagC80 = false; - - m_ped_flagD1 = false; - m_ped_flagD2 = false; - m_ped_flagD4 = false; - m_ped_flagD8 = false; - m_ped_flagD10 = false; - m_ped_flagD20 = false; - m_ped_flagD40 = false; - m_ped_flagD80 = false; - - m_ped_flagE1 = false; - m_ped_flagE2 = false; - bNotAllowedToDuck = false; - bCrouchWhenShooting = false; - bIsDucking = false; - m_ped_flagE20 = false; - bDoBloodyFootprints = false; - m_ped_flagE80 = false; - - m_ped_flagF1 = false; - m_ped_flagF2 = false; - m_ped_flagF4 = false; - m_ped_flagF8 = false; - m_ped_flagF10 = false; - m_ped_flagF20 = false; - m_ped_flagF40 = false; - m_ped_flagF80 = false; - - m_ped_flagG1 = false; - m_ped_flagG2 = true; - m_ped_flagG4 = false; - m_ped_flagG8 = false; - m_ped_flagG10 = false; - m_ped_flagG20 = false; - m_ped_flagG40 = false; - m_ped_flagG80 = false; - - m_ped_flagH1 = false; - m_ped_flagH2 = false; - m_ped_flagH4 = false; - m_ped_flagH8 = false; - m_ped_flagH10 = false; - m_ped_flagH20 = false; - m_ped_flagH40 = false; - m_ped_flagH80 = false; - - m_ped_flagI1 = false; - m_ped_flagI2 = false; - m_ped_flagI4 = false; - bRecordedForReplay = false; - m_ped_flagI10 = false; -#ifdef KANGAROO_CHEAT - m_ped_flagI80 = false; -#endif - - if ((CGeneral::GetRandomNumber() & 3) == 0) - m_ped_flagD1 = true; - - m_audioEntityId = DMAudio.CreateEntity(0, this); - DMAudio.SetEntityStatus(m_audioEntityId, 1); - m_fearFlags = CPedType::GetThreats(m_nPedType); - m_threatEntity = nil; - m_eventOrThread = CVector2D(0.0f, 0.0f); - m_pEventEntity = nil; - m_fAngleToEvent = 0.0f; - m_numNearPeds = 0; - - for (int i = 0; i < 10; i++) - { - m_nearPeds[i] = nil; - if (i < 8) { - m_pPathNodesStates[i] = nil; - } - } - m_maxWeaponTypeAllowed = 0; - m_currentWeapon = 0; - m_storedWeapon = NO_STORED_WEAPON; - - for(int i = 0; i < NUM_PED_WEAPONTYPES; i++) - { - CWeapon &weapon = GetWeapon(i); - weapon.m_eWeaponType = WEAPONTYPE_UNARMED; - weapon.m_eWeaponState = WEAPONSTATE_READY; - weapon.m_nAmmoInClip = 0; - weapon.m_nAmmoTotal = 0; - weapon.m_nTimer = 0; - } - - m_lastHitState = 0; - GiveWeapon(WEAPONTYPE_UNARMED, 0); - m_wepAccuracy = 60; - m_lastWepDam = -1; - m_collPoly.valid = false; - m_fCollisionSpeed = 0.0f; - m_wepModelID = -1; - CPopulation::UpdatePedCount(m_nPedType, false); -} - -uint32 -CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo) -{ - CWeapon &weapon = GetWeapon(weaponType); - - if (HasWeapon(weaponType)) { - if (weapon.m_nAmmoTotal + ammo > 99999) - weapon.m_nAmmoTotal = 99999; - else - weapon.m_nAmmoTotal += ammo; - - weapon.Reload(); - } else { - weapon.Initialise(weaponType, ammo); - // TODO: It seems game uses this as both weapon count and max WeaponType we have, which is ofcourse erroneous. - m_maxWeaponTypeAllowed++; - } - if (weapon.m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO) - weapon.m_eWeaponState = WEAPONSTATE_READY; - - return weaponType; -} - -static RwObject* -RemoveAllModelCB(RwObject *object, void *data) -{ - RpAtomic *atomic = (RpAtomic*)object; - if (CVisibilityPlugins::GetAtomicModelInfo(atomic)) { - RpClumpRemoveAtomic(atomic->clump, atomic); - RpAtomicDestroy(atomic); - } - return object; -} - -static PedOnGroundState -CheckForPedsOnGroundToAttack(CPlayerPed *player, CPed **pedOnGround) -{ - PedOnGroundState stateToReturn; - float angleToFace; - CPed *currentPed = nil; - PedState currentPedState; - CPed *pedOnTheFloor = nil; - CPed *deadPed = nil; - CPed *pedBelow = nil; - bool foundDead = false; - bool foundOnTheFloor = false; - bool foundBelow = false; - float angleDiff; - float distance; - - if (!CGame::nastyGame) - return NO_PED; - - for (int currentPedId = 0; currentPedId < player->m_numNearPeds; currentPedId++) { - - currentPed = player->m_nearPeds[currentPedId]; - - CVector posDifference = currentPed->GetPosition() - player->GetPosition(); - distance = posDifference.Magnitude(); - - if (distance < 2.0f) { - angleToFace = CGeneral::GetRadianAngleBetweenPoints( - currentPed->GetPosition().x, currentPed->GetPosition().y, - player->GetPosition().x, player->GetPosition().y); - - angleToFace = CGeneral::LimitRadianAngle(angleToFace); - player->m_fRotationCur = CGeneral::LimitRadianAngle(player->m_fRotationCur); - - angleDiff = fabs(angleToFace - player->m_fRotationCur); - - if (angleDiff > PI) - angleDiff = 2 * PI - angleDiff; - - currentPedState = currentPed->m_nPedState; - - if (currentPedState == PED_FALL || currentPedState == PED_GETUP || currentPedState == PED_DIE || currentPedState == PED_DEAD) { - if (distance < 2.0f && angleDiff < DEGTORAD(65.0f)) { - if (currentPedState == PED_DEAD) { - foundDead = 1; - if (!deadPed) - deadPed = currentPed; - } else if (!currentPed->IsPedHeadAbovePos(-0.6f)) { - foundOnTheFloor = 1; - if (!pedOnTheFloor) - pedOnTheFloor = currentPed; - } - } - } else if ((distance >= 0.8f || angleDiff >= DEGTORAD(75.0f)) - && (distance >= 1.3f || angleDiff >= DEGTORAD(55.0f)) - && (distance >= 1.7f || angleDiff >= DEGTORAD(35.0f)) - && (distance >= 2.0f || angleDiff >= DEGTORAD(30.0f))) { - - if (angleDiff < DEGTORAD(75.0f)) { - foundBelow = 1; - if (!pedBelow) - pedBelow = currentPed; - } - } else { - foundBelow = 1; - pedBelow = currentPed; - break; - } - } - } - - if (foundOnTheFloor) { - currentPed = pedOnTheFloor; - stateToReturn = PED_ON_THE_FLOOR; - } else if (foundDead) { - currentPed = deadPed; - stateToReturn = PED_DEAD_ON_THE_FLOOR; - } else if (foundBelow) { - currentPed = pedBelow; - stateToReturn = PED_BELOW_PLAYER; - } else { - currentPed = nil; - stateToReturn = NO_PED; - } - - if (pedOnGround) - * pedOnGround = currentPed; - - return stateToReturn; -} - -bool -CPed::IsPlayer(void) -{ - return m_nPedType == PEDTYPE_PLAYER1 || m_nPedType== PEDTYPE_PLAYER2 || - m_nPedType == PEDTYPE_PLAYER3 || m_nPedType == PEDTYPE_PLAYER4; -} - -bool -CPed::UseGroundColModel(void) -{ - return m_nPedState == PED_FALL || - m_nPedState == PED_DIVE_AWAY || - m_nPedState == PED_DIE || - m_nPedState == PED_DEAD; -} - -bool -CPed::CanSetPedState(void) -{ - return m_nPedState != PED_DIE && m_nPedState != PED_ARRESTED && - m_nPedState != PED_ENTER_CAR && m_nPedState != PED_DEAD && m_nPedState != PED_CARJACK && m_nPedState != PED_STEAL_CAR; -} - -bool -CPed::IsPedInControl(void) -{ - return m_nPedState <= PED_STATES_NO_AI - && !bIsInTheAir && !bIsLanding - && m_fHealth > 0.0f; -} - -bool -CPed::CanStrafeOrMouseControl(void) -{ - return m_nPedState == PED_NONE || m_nPedState == PED_IDLE || m_nPedState == PED_FLEE_POS || m_nPedState == PED_FLEE_ENTITY || - m_nPedState == PED_ATTACK || m_nPedState == PED_FIGHT || m_nPedState == PED_AIM_GUN || m_nPedState == PED_JUMP; -} - -void -CPed::AddWeaponModel(int id) -{ - RpAtomic *atm; - - if (id != -1) { - atm = (RpAtomic*)CModelInfo::GetModelInfo(id)->CreateInstance(); - RwFrameDestroy(RpAtomicGetFrame(atm)); - RpAtomicSetFrame(atm, GetNodeFrame(PED_HANDR)); - RpClumpAddAtomic((RpClump*)m_rwObject, atm); - m_wepModelID = id; - } -} - -void -CPed::AimGun(void) -{ - RwV3d pos; - CVector vector; - - if (m_pSeekTarget) { - if (m_pSeekTarget->IsPed()) { - ((CPed*)m_pSeekTarget)->m_pedIK.GetComponentPosition(&pos, PED_TORSO); - vector.x = pos.x; - vector.y = pos.y; - vector.z = pos.z; - } else { - vector = *(m_pSeekTarget->GetPosition()); - } - Say(SOUND_PED_ATTACK); - - bCanPointGunAtTarget = m_pedIK.PointGunAtPosition(&vector); - if (m_pLookTarget != m_pSeekTarget) { - SetLookFlag(m_pSeekTarget, 1); - } - - } else { - if (IsPlayer()) { - bCanPointGunAtTarget = m_pedIK.PointGunInDirection(m_fLookDirection, ((CPlayerPed*)this)->m_fFPSMoveHeading); - } else { - bCanPointGunAtTarget = m_pedIK.PointGunInDirection(m_fLookDirection, 0.0f); - } - } -} - -void -CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer) -{ - CVector pos2 = CVector( - pos.x, - pos.y, - pos.z + 0.1f - ); - - if (!CPed::IsPlayer() || evenOnPlayer) { - ++CStats::HeadShots; - - // BUG: This condition will always return true. - if (m_nPedState != PED_PASSENGER || m_nPedState != PED_TAXI_PASSENGER) { - CPed::SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); - } - - m_ped_flagC20 = true; - m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 150; - - CParticle::AddParticle(PARTICLE_TEST, pos2, - CVector(0.0f, 0.0f, 0.0f), nil, 0.2f, 0, 0, 0, 0); - - if (CEntity::GetIsOnScreen()) { - for(int i=0; i < 32; i++) { - CParticle::AddParticle(PARTICLE_BLOOD_SMALL, - pos2, CVector(0.0f, 0.0f, 0.03f), - nil, 0.0f, 0, 0, 0, 0); - } - - for (int i = 0; i < 16; i++) { - CParticle::AddParticle(PARTICLE_DEBRIS2, - pos2, - CVector(0.0f, 0.0f, 0.01f), - nil, 0.0f, 0, 0, 0, 0); - } - } - } -} - -void -CPed::RemoveBodyPart(PedNode nodeId, int8 unk) -{ - RwFrame *frame; - RwV3d pos; - - frame = GetNodeFrame(nodeId); - if (frame) { - if (CGame::nastyGame) { - if (nodeId != PED_HEAD) - CPed::SpawnFlyingComponent(nodeId, unk); - - RecurseFrameChildrenVisibilityCB(frame, nil); - pos.x = 0.0f; - pos.y = 0.0f; - pos.z = 0.0f; - - for (frame = RwFrameGetParent(frame); frame; frame = RwFrameGetParent(frame)) - RwV3dTransformPoints(&pos, &pos, 1, RwFrameGetMatrix(frame)); - - if (CEntity::GetIsOnScreen()) { - CParticle::AddParticle(PARTICLE_TEST, pos, - CVector(0.0f, 0.0f, 0.0f), - nil, 0.2f, 0, 0, 0, 0); - - for (int i = 0; i < 16; i++) { - CParticle::AddParticle(PARTICLE_BLOOD_SMALL, - pos, - CVector(0.0f, 0.0f, 0.03f), - nil, 0.0f, 0, 0, 0, 0); - } - } - m_ped_flagC20 = true; - m_bodyPartBleeding = nodeId; - } - } else { - printf("Trying to remove ped component"); - } -} - -RwObject* -CPed::SetPedAtomicVisibilityCB(RwObject *object, void *data) -{ - if (data == nil) - RpAtomicSetFlags(object, 0); - return object; -} - -RwFrame* -CPed::RecurseFrameChildrenVisibilityCB(RwFrame *frame, void *data) -{ - RwFrameForAllObjects(frame, SetPedAtomicVisibilityCB, data); - RwFrameForAllChildren(frame, RecurseFrameChildrenVisibilityCB, nil); - return frame; -} - -void -CPed::SetLookFlag(CEntity *target, bool unknown) -{ - if (m_lookTimer < CTimer::GetTimeInMilliseconds()) { - bIsLooking = true; - bIsRestoringLook = false; - m_pLookTarget = target; - m_pLookTarget->RegisterReference((CEntity**)&m_pLookTarget); - m_fLookDirection = 999999.0f; - m_lookTimer = 0; - m_ped_flagA20 = unknown; - if (m_nPedState != PED_DRIVING) { - m_pedIK.m_flags &= ~CPedIK::FLAG_2; - } - } -} - -void -CPed::SetLookFlag(float direction, bool unknown) -{ - if (m_lookTimer < CTimer::GetTimeInMilliseconds()) { - bIsLooking = true; - bIsRestoringLook = false; - m_pLookTarget = nil; - m_fLookDirection = direction; - m_lookTimer = 0; - m_ped_flagA20 = unknown; - if (m_nPedState != PED_DRIVING) { - m_pedIK.m_flags &= ~CPedIK::FLAG_2; - } - } -} - -void -CPed::SetLookTimer(int time) -{ - if (CTimer::GetTimeInMilliseconds() > m_lookTimer) { - m_lookTimer = CTimer::GetTimeInMilliseconds() + time; - } -} - -bool -CPed::OurPedCanSeeThisOne(CEntity *target) -{ - CColPoint colpoint; - CEntity *ent; - - CVector2D dist = CVector2D(target->GetPosition()) - CVector2D(this->GetPosition()); - - // Check if target is behind ped - if (DotProduct2D(dist, CVector2D(this->GetForward())) < 0.0f) - return false; - - // Check if target is too far away - if (dist.Magnitude() >= 40.0f) - return false; - - // Check line of sight from head - CVector headPos = this->GetPosition(); - headPos.z += 1.0f; - return !CWorld::ProcessLineOfSight(headPos, target->GetPosition(), colpoint, ent, true, false, false, false, false, false); -} - -void -CPed::Avoid(void) -{ - CPed *nearestPed; - - if(m_pedStats->m_temper > m_pedStats->m_fear && m_pedStats->m_temper > 50) - return; - - if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) { - - if (m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL) { - nearestPed = m_nearPeds[0]; - - if (nearestPed && nearestPed->m_nPedState != PED_DEAD && nearestPed != m_pSeekTarget && nearestPed != m_pedInObjective) { - - // Check if this ped wants to avoid the nearest one - if (CPedType::GetAvoid(this->m_nPedType) & CPedType::GetFlag(nearestPed->m_nPedType)) { - - // Further codes checks whether the distance between us and ped will be equal or below 1.0, if we walk up to him by 1.25 meters. - // If so, we want to avoid it, so we turn our body 45 degree and look to somewhere else. - - // Game converts from radians to degress and back again here, doesn't make much sense - CVector2D forward(-sin(m_fRotationCur), cos(m_fRotationCur)); - forward.Normalise(); // this is kinda pointless - - // Move forward 1.25 meters - CVector2D testPosition = CVector2D(GetPosition()) + forward*1.25f; - - // Get distance to ped we want to avoid - CVector2D distToPed = CVector2D(nearestPed->GetPosition()) - testPosition; - - if (distToPed.Magnitude() <= 1.0f && CPed::OurPedCanSeeThisOne((CEntity*)nearestPed)) { - m_nPedStateTimer = CTimer::GetTimeInMilliseconds() - + 500 + (m_randomSeed + 3 * CTimer::GetFrameCounter()) - % 1000 / 5; - - m_fRotationDest += DEGTORAD(45.0f); - if (!bIsLooking) { - CPed::SetLookFlag(nearestPed, 0); - CPed::SetLookTimer(CGeneral::GetRandomNumberInRange(500, 800)); - } - } - } - } - } - } -} - -void -CPed::ClearAimFlag(void) -{ - if (bIsAimingGun) { - bIsAimingGun = false; - bIsRestoringGun = true; - m_pedIK.m_flags &= ~CPedIK:: FLAG_4; - } - - if (CPed::IsPlayer()) - ((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0; -} - -void -CPed::ClearLookFlag(void) { - if (bIsLooking) { - bIsLooking = false; - bIsRestoringLook = true; - m_ped_flagI1 = false; - - m_pedIK.m_flags &= ~CPedIK::FLAG_2; - if (CPed::IsPlayer()) - m_lookTimer = CTimer::GetTimeInMilliseconds() + 2000; - else - m_lookTimer = CTimer::GetTimeInMilliseconds() + 4000; - - if (m_nPedState == PED_LOOK_HEADING || m_nPedState == PED_LOOK_ENTITY) { - CPed::RestorePreviousState(); - CPed::ClearLookFlag(); - } - } -} - -bool -CPed::IsPedHeadAbovePos(float zOffset) -{ - RwMatrix mat; - - CPedIK::GetWorldMatrix(GetNodeFrame(PED_HEAD), &mat); - return zOffset + GetPosition().z < RwMatrixGetPos(&mat)->z; -} - -void -CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg) -{ - CWeaponInfo *currentWeapon; - CAnimBlendAssociation *newAnim; - CPed *ped = (CPed*)arg; - - if (attackAssoc) { - switch (attackAssoc->animId) { - case ANIM_WEAPON_START_THROW: - if ((!ped->IsPlayer() || ((CPlayerPed*)ped)->field_1380) && ped->IsPlayer()) { - attackAssoc->blendDelta = -1000.0f; - newAnim = CAnimManager::AddAnimation((RpClump*)ped->m_rwObject, ASSOCGRP_STD, ANIM_WEAPON_THROWU); - } else { - attackAssoc->blendDelta = -1000.0f; - newAnim = CAnimManager::AddAnimation((RpClump*)ped->m_rwObject, ASSOCGRP_STD, ANIM_WEAPON_THROW); - } - - newAnim->SetFinishCallback(FinishedAttackCB, ped); - return; - - case ANIM_FIGHT_PPUNCH: - attackAssoc->blendDelta = -8.0f; - attackAssoc->flags |= ASSOC_DELETEFADEDOUT; - ped->ClearAttack(); - return; - - case ANIM_WEAPON_THROW: - case ANIM_WEAPON_THROWU: - if (ped->GetWeapon()->m_nAmmoTotal > 0) { - currentWeapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType); - ped->AddWeaponModel(currentWeapon->m_nModelId); - } - break; - default: - break; - } - } - - if (!ped->m_ped_flagA4) - ped->ClearAttack(); -} - -void -CPed::Attack(void) -{ - CAnimBlendAssociation *weaponAnimAssoc; - int32 weaponAnim; - float animStart; - RwFrame *frame; - eWeaponType ourWeaponType; - float weaponAnimTime; - eWeaponFire ourWeaponFire; - float animLoopEnd; - CWeaponInfo *ourWeapon; - bool lastReloadWasInFuture; - AnimationId reloadAnim; - CAnimBlendAssociation *reloadAnimAssoc; - float delayBetweenAnimAndFire; - CVector firePos; - - ourWeaponType = GetWeapon()->m_eWeaponType; - ourWeapon = CWeaponInfo::GetWeaponInfo(ourWeaponType); - ourWeaponFire = ourWeapon->m_eWeaponFire; - weaponAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ourWeapon->m_AnimToPlay); - lastReloadWasInFuture = m_ped_flagA4; - reloadAnimAssoc = nil; - reloadAnim = NUM_ANIMS; - delayBetweenAnimAndFire = ourWeapon->m_fAnimFrameFire; - weaponAnim = ourWeapon->m_AnimToPlay; - - if (weaponAnim == ANIM_WEAPON_HGUN_BODY) - reloadAnim = ANIM_HGUN_RELOAD; - else if (weaponAnim == ANIM_WEAPON_AK_BODY) - reloadAnim = ANIM_AK_RELOAD; - - if (reloadAnim != NUM_ANIMS) - reloadAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, reloadAnim); - - if (bIsDucking) - return; - - if (reloadAnimAssoc) { - if (!CPed::IsPlayer() || ((CPlayerPed*)this)->field_1380) - ClearAttack(); - - return; - } - - // BUG: We currently don't know any situation this cond. could be true. - if (CTimer::GetTimeInMilliseconds() < m_lastHitTime) - lastReloadWasInFuture = true; - - if (!weaponAnimAssoc) { - weaponAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ourWeapon->m_Anim2ToPlay); - delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire; - - // Long throw granade, molotov - if (!weaponAnimAssoc && ourWeapon->m_bThrow) { - weaponAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_WEAPON_THROWU); - delayBetweenAnimAndFire = 0.2f; - } - } - if (weaponAnimAssoc) { - animStart = ourWeapon->m_fAnimLoopStart; - weaponAnimTime = weaponAnimAssoc->currentTime; - if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) { - if (ourWeapon->m_bCanAimWithArm) - m_pedIK.m_flags |= CPedIK::FLAG_4; - else - m_pedIK.m_flags &= ~CPedIK::FLAG_4; - } - - if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) { - if (weaponAnimAssoc->speed < 1.0f) - weaponAnimAssoc->speed = 1.0f; - - } else { - firePos = ourWeapon->m_vecFireOffset; - if (ourWeaponType == WEAPONTYPE_BASEBALLBAT) { - if (weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay) - firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f; - - firePos = GetMatrix() * firePos; - } else if (ourWeaponType != WEAPONTYPE_UNARMED) { - if (weaponAnimAssoc->animId == ANIM_KICK_FLOOR) - frame = GetNodeFrame(PED_FOOTR); - else - frame = GetNodeFrame(PED_HANDR); - - for (; frame; frame = RwFrameGetParent(frame)) - RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, RwFrameGetMatrix(frame)); - } else { - firePos = GetMatrix() * firePos; - } - - GetWeapon()->Fire(this, &firePos); - - if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE) { - RemoveWeaponModel(ourWeapon->m_nModelId); - } - if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) { - SelectGunIfArmed(); - } - - if (GetWeapon()->m_eWeaponState != WEAPONSTATE_MELEE_MADECONTACT) { - // If reloading just began, start the animation - if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING && reloadAnim != NUM_ANIMS && !reloadAnimAssoc) { - CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, reloadAnim, 8.0f); - ClearLookFlag(); - ClearAimFlag(); - m_ped_flagA4 = false; - bIsPointingGunAt = false; - m_lastHitTime = CTimer::GetTimeInMilliseconds(); - return; - } - } else { - if (weaponAnimAssoc->animId == ANIM_WEAPON_BAT_V || weaponAnimAssoc->animId == ANIM_WEAPON_BAT_H) { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f); - } else if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH) { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_PUNCH_ATTACK, 0.0f); - } - - weaponAnimAssoc->speed = 0.5f; - - // BUG: We currently don't know any situation this cond. could be true. - if (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime) { - weaponAnimAssoc->callbackType = 0; - } - } - - lastReloadWasInFuture = false; - } - - if (ourWeaponType == WEAPONTYPE_SHOTGUN) { - weaponAnimTime = weaponAnimAssoc->currentTime; - firePos = ourWeapon->m_vecFireOffset; - - if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) { - for (frame = GetNodeFrame(PED_HANDR); frame; frame = RwFrameGetParent(frame)) - RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, RwFrameGetMatrix(frame)); - - CVector gunshellPos( - firePos.x - 0.6f * GetForward().x, - firePos.y - 0.6f * GetForward().y, - firePos.z - 0.15f * GetUp().z - ); - - CVector2D gunshellRot( - GetRight().x, - GetRight().y - ); - - gunshellRot.Normalise(); - GetWeapon()->AddGunshell(this, gunshellPos, gunshellRot, 0.025f); - } - } - animLoopEnd = ourWeapon->m_fAnimLoopEnd; - if (ourWeaponFire == WEAPON_FIRE_MELEE && weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay) - animLoopEnd = 3.4f/6.0f; - - weaponAnimTime = weaponAnimAssoc->currentTime; - - // Anim loop end, either start the loop again or finish the attack - if (weaponAnimTime > animLoopEnd || !weaponAnimAssoc->IsRunning() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) { - - if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd - && (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime) - && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) { - - weaponAnim = weaponAnimAssoc->animId; - if (ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(((CPlayerPed*)this), nil) < PED_ON_THE_FLOOR) { - if (weaponAnim != ourWeapon->m_Anim2ToPlay || weaponAnim == ANIM_RBLOCK_CSHOOT) { - weaponAnimAssoc->Start(ourWeapon->m_fAnimLoopStart); - } else { - CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f); - } - } else { - if (weaponAnim == ourWeapon->m_Anim2ToPlay) - weaponAnimAssoc->SetCurrentTime(0.1f); - else - CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f); - } - } else { - ClearAimFlag(); - - // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading) - if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep <= ourWeapon->m_fAnimLoopEnd) { - switch (ourWeaponType) { - case WEAPONTYPE_UZI: - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f); - break; - case WEAPONTYPE_AK47: - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f); - break; - case WEAPONTYPE_M16: - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f); - break; - default: - break; - } - } - - // Fun fact: removing this part leds to reloading flamethrower - if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) { - weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT; - weaponAnimAssoc->flags &= ~ASSOC_RUNNING; - weaponAnimAssoc->blendDelta = -4.0f; - } - } - } - if (weaponAnimAssoc->currentTime > delayBetweenAnimAndFire) - lastReloadWasInFuture = false; - - m_ped_flagA4 = lastReloadWasInFuture; - return; - } - - if (lastReloadWasInFuture) { - if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !CPed::IsPlayer() || ((CPlayerPed*)this)->field_1380) { - if (!CGame::nastyGame || ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(((CPlayerPed*)this), nil) < PED_ON_THE_FLOOR) { - weaponAnimAssoc = CAnimManager::BlendAnimation((RpClump*)m_rwObject, ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f); - } else { - weaponAnimAssoc = CAnimManager::BlendAnimation((RpClump*)m_rwObject, ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f); - } - - weaponAnimAssoc->SetFinishCallback(CPed::FinishedAttackCB, this); - weaponAnimAssoc->flags |= ASSOC_RUNNING; - - if (weaponAnimAssoc->currentTime == weaponAnimAssoc->hierarchy->totalLength) - weaponAnimAssoc->SetCurrentTime(0.0f); - - if (CPed::IsPlayer()) { - ((CPlayerPed*)this)->field_1376 = 0.0f; - ((CPlayerPed*)this)->field_1380 = false; - } - } - } - else - CPed::FinishedAttackCB(nil, this); -} - -void -CPed::RemoveWeaponModel(int modelId) -{ - // modelId is not used!! This function just removes the current weapon. - RwFrameForAllObjects(GetNodeFrame(PED_HANDR),RemoveAllModelCB,nil); - m_wepModelID = -1; -} - -void -CPed::SetCurrentWeapon(uint32 weaponType) -{ - CWeaponInfo *weaponInfo; - if (HasWeapon(weaponType)) { - weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - RemoveWeaponModel(weaponInfo->m_nModelId); - - m_currentWeapon = weaponType; - - weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - AddWeaponModel(weaponInfo->m_nModelId); - } -} - -// Only used while deciding which gun ped should switch to, if no ammo left. -bool -CPed::SelectGunIfArmed(void) -{ - for (int i = 0; i < m_maxWeaponTypeAllowed; i++) { - if (GetWeapon(i).m_nAmmoTotal > 0) { - eWeaponType weaponType = GetWeapon(i).m_eWeaponType; - if (weaponType >= WEAPONTYPE_COLT45 && weaponType != WEAPONTYPE_M16 && weaponType <= WEAPONTYPE_FLAMETHROWER) { - SetCurrentWeapon(i); - return true; - } - } - } - SetCurrentWeapon(WEAPONTYPE_UNARMED); - return false; -} - -void -CPed::Duck(void) -{ - if (CTimer::GetTimeInMilliseconds() > m_duckTimer) - ClearDuck(); -} - -void -CPed::ClearDuck(void) -{ - CAnimBlendAssociation *animAssoc; - - animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_DUCK_DOWN); - if (!animAssoc) - animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_DUCK_LOW); - - if (animAssoc) { - - if (bCrouchWhenShooting) { - - if (m_nPedState == PED_ATTACK || m_nPedState == PED_AIM_GUN) { - animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_RBLOCK_CSHOOT); - if (!animAssoc || animAssoc->blendDelta < 0.0f) { - CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ANIM_RBLOCK_CSHOOT, 4.0f); - } - } - } - } else - bIsDucking = false; -} - -void -CPed::ClearPointGunAt(void) -{ - CAnimBlendAssociation *animAssoc; - CWeaponInfo *weaponInfo; - - ClearLookFlag(); - ClearAimFlag(); - bIsPointingGunAt = false; - if (m_nPedState == PED_AIM_GUN) { - RestorePreviousState(); - weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, weaponInfo->m_AnimToPlay); - if (!animAssoc || animAssoc->blendDelta < 0.0f) { - animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, weaponInfo->m_Anim2ToPlay); - } - if (animAssoc) { - animAssoc->flags |= ASSOC_DELETEFADEDOUT; - animAssoc->blendDelta = -4.0; - } - } -} - -void -CPed::BeingDraggedFromCar(void) -{ - CAnimBlendAssociation *animAssoc; - AnimationId enterAnim; - bool dontRunAnim = false; - PedLineUpPhase lineUpType; - - if (!m_pVehicleAnim) { - CAnimManager::BlendAnimation((RpClump*) m_rwObject, m_animGroup, ANIM_IDLE_STANCE, 100.0f); - animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_CAR_SIT); - if (!animAssoc) { - animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_CAR_LSIT); - if (!animAssoc) { - animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_CAR_SITP); - if (!animAssoc) - animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_CAR_SITPLO); - } - } - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - - if (m_vehEnterType == VEHICLE_ENTER_FRONT_LEFT || m_vehEnterType == VEHICLE_ENTER_REAR_LEFT) { - if (m_ped_flagF10) { - enterAnim = ANIM_CAR_QJACKED; - } else if (m_pMyVehicle->bLowVehicle) { - enterAnim = ANIM_CAR_LJACKED_LHS; - } else { - enterAnim = ANIM_CAR_JACKED_LHS; - } - } else if (m_vehEnterType == VEHICLE_ENTER_FRONT_RIGHT || m_vehEnterType == VEHICLE_ENTER_REAR_RIGHT) { - if (m_pMyVehicle->bLowVehicle) - enterAnim = ANIM_CAR_LJACKED_RHS; - else - enterAnim = ANIM_CAR_JACKED_RHS; - } else - dontRunAnim = true; - - - if (!dontRunAnim) - m_pVehicleAnim = CAnimManager::AddAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, enterAnim); - - m_pVehicleAnim->SetFinishCallback(PedSetDraggedOutCarCB, this); - lineUpType = LINE_UP_TO_CAR_START; - } else if (m_pVehicleAnim->currentTime <= 1.4f) { - m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); - lineUpType = LINE_UP_TO_CAR_START; - } else { - lineUpType = LINE_UP_TO_CAR_2; - } - - LineUpPedWithCar(lineUpType); -} - -void -CPed::RestartNonPartialAnims(void) -{ - CAnimBlendAssociation *assoc; - - for (assoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)m_rwObject); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) { - if (!assoc->IsPartial()) - assoc->flags |= ASSOC_RUNNING; - } -} - -void -CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg) -{ - CAnimBlendAssociation *quickJackedAssoc; - CVehicle *vehicle; - CPed *ped = (CPed*)arg; - eWeaponType weaponType = ped->GetWeapon()->m_eWeaponType; - - quickJackedAssoc = RpAnimBlendClumpGetAssociation((RpClump*) ped->m_rwObject, ANIM_CAR_QJACKED); - if (ped->m_nPedState != PED_ARRESTED) { - ped->m_nLastPedState = PED_NONE; - if (dragAssoc) - dragAssoc->blendDelta = -1000.0; - } - ped->RestartNonPartialAnims(); - ped->m_pVehicleAnim = nil; - ped->m_pSeekTarget = nil; - vehicle = ped->m_pMyVehicle; - - vehicle->m_nGettingOutFlags &= ~GetVehEnterExitFlag(ped->m_vehEnterType); - - if (vehicle->pDriver == ped) { - vehicle->RemoveDriver(); - if (vehicle->m_nDoorLock == CARLOCK_COP_CAR) - vehicle->m_nDoorLock = CARLOCK_UNLOCKED; - - if (ped->m_nPedType == PEDTYPE_COP && vehicle->IsLawEnforcementVehicle()) - vehicle->ChangeLawEnforcerState(false); - } else { - for (int i = 0; i < vehicle->m_nNumMaxPassengers; i++) { - if (vehicle->pPassengers[i] == ped) { - vehicle->pPassengers[i] = nil; - vehicle->m_nNumPassengers--; - } - } - } - - ped->bInVehicle = false; - if (ped->IsPlayer()) - AudioManager.PlayerJustLeftCar(); - - if (quickJackedAssoc) { - dragAssoc->SetDeleteCallback(PedSetQuickDraggedOutCarPositionCB, ped); - } else { - dragAssoc->SetDeleteCallback(PedSetDraggedOutCarPositionCB, ped); - if (ped->CanSetPedState()) - CAnimManager::BlendAnimation((RpClump*) ped->m_rwObject, ASSOCGRP_STD, ANIM_GETUP1, 1000.0f); - } - - // Only uzi can be used on cars, so previous weapon was stored - if (ped->IsPlayer() && weaponType == WEAPONTYPE_UZI) { - if (ped->m_storedWeapon != NO_STORED_WEAPON) { - ped->SetCurrentWeapon(ped->m_storedWeapon); - ped->m_storedWeapon = NO_STORED_WEAPON; - } - } else { - ped->AddWeaponModel(CWeaponInfo::GetWeaponInfo(weaponType)->m_nModelId); - } - ped->m_nStoredActionState = 0; - ped->m_ped_flagI4 = false; -} - -void -CPed::GetLocalPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enterType, float seatPosMult) -{ - CVehicleModelInfo *vehModel; - CVector vehDoorPos; - CVector vehDoorOffset; - float seatOffset; - - vehModel = (CVehicleModelInfo*) CModelInfo::GetModelInfo(veh->m_modelIndex); - if (veh->bIsVan && (enterType == VEHICLE_ENTER_REAR_LEFT || enterType == VEHICLE_ENTER_REAR_RIGHT)) { - seatOffset = 0.0f; - vehDoorOffset = offsetToOpenVanDoor; - } else { - seatOffset = veh->m_handling->fSeatOffsetDistance * seatPosMult; - if (veh->bLowVehicle) { - vehDoorOffset = offsetToOpenLowCarDoor; - } else { - vehDoorOffset = offsetToOpenRegularCarDoor; - } - } - - switch (enterType) { - case VEHICLE_ENTER_FRONT_RIGHT: - if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) - vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_BOAT_RUDDER]; - else - vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_FRONT_SEATS]; - - vehDoorPos.x += seatOffset; - vehDoorOffset.x = -vehDoorOffset.x; - break; - - case VEHICLE_ENTER_REAR_RIGHT: - vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_REAR_SEATS]; - vehDoorPos.x += seatOffset; - vehDoorOffset.x = -vehDoorOffset.x; - break; - - case VEHICLE_ENTER_FRONT_LEFT: - if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) - vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_BOAT_RUDDER]; - else - vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_FRONT_SEATS]; - - vehDoorPos.x = -(vehDoorPos.x + seatOffset); - break; - - case VEHICLE_ENTER_REAR_LEFT: - vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_REAR_SEATS]; - vehDoorPos.x = -(vehDoorPos.x + seatOffset); - break; - - default: - if (vehModel->m_vehicleType == VEHICLE_TYPE_BOAT) - vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_BOAT_RUDDER]; - else - vehDoorPos = vehModel->m_positions[VEHICLE_DUMMY_FRONT_SEATS]; - - vehDoorOffset = CVector(0.0f, 0.0f, 0.0f); - } - *output = vehDoorPos - vehDoorOffset; -} - -// This function was mostly duplicate of GetLocalPositionToOpenCarDoor, so I've used it. -void -CPed::GetPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enterType) -{ - CVector localPos; - CVector vehDoorPos; - - GetLocalPositionToOpenCarDoor(&localPos, veh, enterType, 1.0f); - vehDoorPos = Multiply3x3(veh->GetMatrix(), localPos) + veh->GetPosition(); - -/* - // Not used. - CVector localVehDoorOffset; - - if (veh->bIsVan && (enterType == VEHICLE_ENTER_REAR_LEFT || enterType == VEHICLE_ENTER_REAR_RIGHT)) { - localVehDoorOffset = offsetToOpenVanDoor; - } else { - if (veh->bIsLow) { - localVehDoorOffset = offsetToOpenLowCarDoor; - } else { - localVehDoorOffset = offsetToOpenRegularCarDoor; - } - } - - vehDoorPosWithoutOffset = Multiply3x3(veh->GetMatrix(), localPos + localVehDoorOffset) + veh->GetPosition(); -*/ - *output = vehDoorPos; -} - -void -CPed::GetPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enterType, float offset) -{ - CVector doorPos; - CMatrix vehMat(veh->GetMatrix()); - - GetLocalPositionToOpenCarDoor(output, veh, enterType, offset); - doorPos = Multiply3x3(vehMat, *output); - - *output = *veh->GetPosition() + doorPos; -} - -void -CPed::LineUpPedWithCar(PedLineUpPhase phase) -{ - bool vehIsUpsideDown = false; - int vehAnim; - float seatPosMult = 0.0f; - float currentZ; - float adjustedTimeStep; - - if (CReplay::IsPlayingBack()) - return; - - if (!m_ped_flagC8 && phase != LINE_UP_TO_CAR_2) { - if (RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_CAR_SIT)) { - SetPedPositionInCar(); - return; - } - if (RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_CAR_LSIT)) { - SetPedPositionInCar(); - return; - } - if (RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_CAR_SITP)) { - SetPedPositionInCar(); - return; - } - if (RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_CAR_SITPLO)) { - SetPedPositionInCar(); - return; - } - m_ped_flagC8 = 1; - } - if (phase == LINE_UP_TO_CAR_START) { - m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); - } - CVehicle *veh = m_pMyVehicle; - - // Not quite right, IsUpsideDown func. checks for <= -0.9f. - // Since that function is also used in this file, doesn't this variable indicate upsidedownness?! - if (veh->GetUp().z <= -0.8f) - vehIsUpsideDown = true; - - if (m_vehEnterType == VEHICLE_ENTER_FRONT_RIGHT || m_vehEnterType == VEHICLE_ENTER_REAR_RIGHT) { - if (vehIsUpsideDown) { - m_fRotationDest = -PI + veh->GetForward().Heading(); - } else if (veh->bIsBus) { - m_fRotationDest = 0.5 * PI + veh->GetForward().Heading(); - } else { - m_fRotationDest = veh->GetForward().Heading(); - } - } else if (m_vehEnterType == VEHICLE_ENTER_FRONT_LEFT || m_vehEnterType == VEHICLE_ENTER_REAR_LEFT) { - if (vehIsUpsideDown) { - m_fRotationDest = veh->GetForward().Heading(); - } else if (veh->bIsBus) { - m_fRotationDest = -0.5 * PI + veh->GetForward().Heading(); - } else { - m_fRotationDest = veh->GetForward().Heading(); - } - } - - if (!bInVehicle) - seatPosMult = 1.0f; - - if (m_pVehicleAnim) { - vehAnim = m_pVehicleAnim->animId; - - switch (vehAnim) { - case ANIM_CAR_JACKED_RHS: - case ANIM_CAR_LJACKED_RHS: - case ANIM_CAR_JACKED_LHS: - case ANIM_CAR_LJACKED_LHS: - case ANIM_CAR_QJACKED: - case ANIM_CAR_GETOUT_LHS: - case ANIM_CAR_GETOUT_LOW_LHS: - case ANIM_CAR_GETOUT_RHS: - case ANIM_CAR_GETOUT_LOW_RHS: - case ANIM_CAR_CRAWLOUT_RHS: - case ANIM_CAR_CRAWLOUT_RHS2: - case ANIM_VAN_GETIN_L: - case ANIM_VAN_GETOUT_L: - case ANIM_VAN_GETIN: - case ANIM_VAN_GETOUT: - seatPosMult = m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength; - break; - case ANIM_CAR_QJACK: - case ANIM_CAR_GETIN_LHS: - case ANIM_CAR_GETIN_LOW_LHS: - case ANIM_CAR_GETIN_RHS: - case ANIM_CAR_GETIN_LOW_RHS: - case ANIM_DRIVE_BOAT: - seatPosMult = m_pVehicleAnim->GetTimeLeft() / m_pVehicleAnim->hierarchy->totalLength; - break; - case ANIM_CAR_CLOSEDOOR_LHS: - case ANIM_CAR_CLOSEDOOR_LOW_LHS: - case ANIM_CAR_CLOSEDOOR_RHS: - case ANIM_CAR_CLOSEDOOR_LOW_RHS: - case ANIM_CAR_SHUFFLE_RHS: - case ANIM_CAR_LSHUFFLE_RHS: - seatPosMult = 0.0f; - break; - case ANIM_CAR_CLOSE_LHS: - case ANIM_CAR_CLOSE_RHS: - case ANIM_COACH_OPEN_L: - case ANIM_COACH_OPEN_R: - case ANIM_COACH_IN_L: - case ANIM_COACH_IN_R: - case ANIM_COACH_OUT_L: - seatPosMult = 1.0f; - break; - default: - break; - } - } - - CVector neededPos; - - if (phase == LINE_UP_TO_CAR_2) { - neededPos = *GetPosition(); - } else { - GetPositionToOpenCarDoor(&neededPos, veh, m_vehEnterType, seatPosMult); - } - - CVector autoZPos = neededPos; - - if (veh->bIsInWater) { - if (veh->m_vehType == VEHICLE_TYPE_BOAT && veh->IsUpsideDown()) - autoZPos.z += 1.0f; - } else { - CPedPlacement::FindZCoorForPed(&autoZPos); - } - - if (phase == LINE_UP_TO_CAR_END || phase == LINE_UP_TO_CAR_2) { - neededPos.z = GetPosition().z; - - // Getting out - if (!veh->bIsBus || (veh->bIsBus && vehIsUpsideDown)) { - float pedZSpeedOnExit = m_vecMoveSpeed.z - 0.008f * CTimer::GetTimeStep(); - - // If we're not in ground at next step, apply animation - if (neededPos.z + pedZSpeedOnExit >= autoZPos.z) { - m_vecMoveSpeed.z = pedZSpeedOnExit; - ApplyMoveSpeed(); - // Removing below line breaks the animation - neededPos.z = GetPosition().z; - } else { - neededPos.z = autoZPos.z; - m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); - } - } - } - - if (autoZPos.z > neededPos.z) { - currentZ = GetPosition().z; - if (m_pVehicleAnim && vehAnim != ANIM_VAN_GETIN_L && vehAnim != ANIM_VAN_CLOSE_L && vehAnim != ANIM_VAN_CLOSE && vehAnim != ANIM_VAN_GETIN) { - neededPos.z = autoZPos.z; - m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); - } else if (neededPos.z <= currentZ && m_pVehicleAnim && vehAnim != ANIM_VAN_CLOSE_L && vehAnim != ANIM_VAN_CLOSE) { - adjustedTimeStep = min(m_pVehicleAnim->timeStep, 0.1f); - - // Smoothly change ped position - neededPos.z = currentZ - (currentZ - neededPos.z) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep); - } - } else { - // We may need to raise up the ped - if (phase == LINE_UP_TO_CAR_START) { - currentZ = GetPosition().z; - - if (neededPos.z > currentZ) { - - if (m_pVehicleAnim && - (vehAnim == ANIM_CAR_GETIN_RHS || vehAnim == ANIM_CAR_GETIN_LOW_RHS || vehAnim == ANIM_CAR_GETIN_LHS || vehAnim == ANIM_CAR_GETIN_LOW_LHS - || vehAnim == ANIM_CAR_QJACK || vehAnim == ANIM_VAN_GETIN_L || vehAnim == ANIM_VAN_GETIN)) { - adjustedTimeStep = min(m_pVehicleAnim->timeStep, 0.1f); - - // Smoothly change ped position - neededPos.z = (neededPos.z - currentZ) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep) + currentZ; - } else if (m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK) { - neededPos.z = max(currentZ, autoZPos.z); - } - } - } - } - - bool stillGettingInOut = false; - if (CTimer::GetTimeInMilliseconds() < m_nPedStateTimer) - stillGettingInOut = veh->m_vehType != VEHICLE_TYPE_BOAT || m_ped_flagG10; - - if (!stillGettingInOut) { - m_fRotationCur = m_fRotationDest; - } else { - float limitedAngle = CGeneral::LimitRadianAngle(m_fRotationDest); - float timeUntilStateChange = (m_nPedStateTimer - CTimer::GetTimeInMilliseconds())/600.0f; - - m_vecOffsetSeek.z = 0.0; - if (timeUntilStateChange <= 0.0f) { - m_vecOffsetSeek.x = 0.0; - m_vecOffsetSeek.y = 0.0; - } else { - neededPos -= timeUntilStateChange * m_vecOffsetSeek; - } - - if (limitedAngle > PI + m_fRotationCur) { - limitedAngle -= 2 * PI; - } else if (limitedAngle < m_fRotationCur - PI) { - limitedAngle += 2 * PI; - } - m_fRotationCur -= (m_fRotationCur - limitedAngle) * (1.0f - timeUntilStateChange); - } - - if (seatPosMult > 0.2f || vehIsUpsideDown) { - GetPosition() = neededPos; - - GetMatrix().SetRotate(0.0f, 0.0f, m_fRotationCur); - - // It will be all 0 after rotate. - GetPosition() = neededPos; - } else { - CVector output; - CMatrix vehDoorMat(veh->GetMatrix()); - - GetLocalPositionToOpenCarDoor(&output, veh, m_vehEnterType, 0.0f); - *vehDoorMat.GetPosition() += Multiply3x3(vehDoorMat, output); - GetMatrix() = vehDoorMat; - } - -} - -static void -particleProduceFootDust(CPed *ped, CVector *pos, float size, int times) -{ - switch (ped->m_nLastCollType) - { - case 1: // somewhere hard - case 3: // soft dirt - case 5: // pavement - case 18:// sand - for (int i = 0; i < times; ++i) { - CVector adjustedPos = *pos; - adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); - adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); - CParticle::AddParticle(PARTICLE_PEDFOOT_DUST, adjustedPos, CVector(0.0f, 0.0f, 0.0f), nil, size, CRGBA(0, 0, 0, 0), 0, 0, 0, 0); - } - break; - default: - break; - } -} - -static void -particleProduceFootSplash(CPed *ped, CVector *pos, float size, int times) -{ - for (int i = 0; i < times; i++) { - CVector adjustedPos = *pos; - adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); - adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); - - CVector direction = ped->GetForward() * -0.05f; - CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, adjustedPos, direction, nil, size, CRGBA(32, 32, 32, 32), 0, 0, CGeneral::GetRandomNumberInRange(0, 1), 200); - } -} - -void -CPed::PlayFootSteps(void) -{ - if (bDoBloodyFootprints) { - if (m_bloodyFootprintCount > 0 && m_bloodyFootprintCount < 300) { - m_bloodyFootprintCount--; - - if (m_bloodyFootprintCount == 0) - bDoBloodyFootprints = false; - } - } - - if (!bIsStanding) - return; - - CAnimBlendAssociation *assoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)m_rwObject); - CAnimBlendAssociation *walkRunAssoc = nil; - float walkRunAssocBlend = 0.0f, idleAssocBlend = 0.0f; - - for (; assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) { - if (assoc->flags & ASSOC_FLAG80) { - walkRunAssoc = assoc; - walkRunAssocBlend += assoc->blendAmount; - } else if ((assoc->flags & ASSOC_FLAG200) == 0) { - idleAssocBlend += assoc->blendAmount; - } - } - - if (walkRunAssoc && walkRunAssocBlend > 0.5f && idleAssocBlend < 1.0f) { - float stepStart = 1 / 15.0f; - float stepEnd = walkRunAssoc->hierarchy->totalLength / 2.0f + stepStart; - float currentTime = walkRunAssoc->currentTime; - int stepPart = 0; - - if (currentTime >= stepStart && currentTime - walkRunAssoc->timeStep < stepStart) - stepPart = 1; - else if (currentTime >= stepEnd && currentTime - walkRunAssoc->timeStep < stepEnd) - stepPart = 2; - - if (stepPart != 0) { - DMAudio.PlayOneShot(m_audioEntityId, stepPart == 1 ? SOUND_STEP_START : SOUND_STEP_END, 1.0f); - CVector footPos(0.0f, 0.0f, 0.0f); - - for (RwFrame *frame = GetNodeFrame(stepPart == 1 ? PED_FOOTL : PED_FOOTR); frame; frame = RwFrameGetParent(frame)) - RwV3dTransformPoints(footPos, footPos, 1, RwFrameGetMatrix(frame)); - - CVector forward = GetForward(); - - footPos.z -= 0.1f; - footPos += 0.2f * forward; - - if (bDoBloodyFootprints) { - CVector2D top(forward * 0.26f); - CVector2D right(GetRight() * 0.14f); - - CShadows::AddPermanentShadow(1, gpBloodPoolTex, &footPos, - top.x, top.y, - right.x, right.y, - 255, 255, 0, 0, 4.0f, 3000.0f, 1.0f); - - if (m_bloodyFootprintCount <= 20) { - m_bloodyFootprintCount = 0; - bDoBloodyFootprints = false; - } else { - m_bloodyFootprintCount -= 20; - } - } - if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) { - if(IsPlayer()) - particleProduceFootDust(this, &footPos, 0.0f, 4); - } else if(stepPart == 2) { - particleProduceFootSplash(this, &footPos, 0.15f, 4); - } - } - } - - if (m_nLastCollType == 19) { // Water - float pedSpeed = CVector2D(m_vecMoveSpeed).Magnitude(); - if (pedSpeed > 0.03f && CTimer::GetFrameCounter() % 2 == 0 && pedSpeed > 0.13f) { - float particleSize = pedSpeed * 2.0f; - - if (particleSize < 0.25f) - particleSize = 0.25f; - - if (particleSize > 0.75f) - particleSize = 0.75f; - - CVector particlePos = GetPosition() + GetForward() * 0.3f; - particlePos.z -= 1.2f; - - CVector particleDir = m_vecMoveSpeed * 0.75f; - - particleDir.z = CGeneral::GetRandomNumberInRange(0.01f, 0.03f); - CParticle::AddParticle(PARTICLE_PED_SPLASH, particlePos, particleDir, nil, 0.8f * particleSize, CRGBA(155,155,185,128), 0, 0, 0, 0); - - particleDir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.05f); - CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, particlePos, particleDir, nil, particleSize, CRGBA(255,255,255,255), 0, 0, 0, 0); - } - } -} - -bool -CPed::IsPointerValid(void) -{ - int8 pedIndex = CPools::GetPedPool()->GetIndex(this) >> 8; - if (pedIndex < 0 || pedIndex >= NUMPEDS) - return false; - - if (m_entryInfoList.first || FindPlayerPed() == this) - return true; - - return false; -} - -// Some kind of binary sort -void -CPed::SortPeds(CPed **list, int min, int max) -{ - if (min >= max) - return; - - CVector leftDiff, rightDiff; - CVector middleDiff = GetPosition() - list[(max + min) / 2]->GetPosition(); - float middleDist = middleDiff.Magnitude(); - - int left = max; - int right; - for(right = min; right <= left; ){ - // Those 1.0s are to make sure loop always run for first time. - for (float rightDist = middleDist-1.0f; middleDist > rightDist; right++) { - rightDiff = GetPosition() - list[right]->GetPosition(); - rightDist = rightDiff.Magnitude(); - } - right--; - - for (float leftDist = middleDist+1.0f; middleDist < leftDist; left--) { - leftDiff = GetPosition() - list[left]->GetPosition(); - leftDist = leftDiff.Magnitude(); - } - left++; - - if (right <= left) { - CPed *ped = list[right]; - list[right] = list[left]; - list[left] = ped; - right++; - left--; - } - } - SortPeds(list, min, left); - SortPeds(list, right, max); -} - -void -CPed::BuildPedLists(void) -{ - static CPed *unsortedNearPeds[10]; - uint16 nextNearPedSlot = 0; - - if ((CTimer::GetFrameCounter() + m_randomSeed) & 15) { - - for(int i = 0; i < 10; ) { - if (m_nearPeds[i]) { - if (m_nearPeds[i]->IsPointerValid()) { - float distSqr = (GetPosition() - m_nearPeds[i]->GetPosition()).MagnitudeSqr2D(); - if (distSqr < 900.0f) { - i++; - continue; - } - } - - // If we arrive here, the ped we're checking isn't "near", so we should remove it. - for (int j = i; j < 9; j++) { - m_nearPeds[j] = m_nearPeds[j + 1]; - m_nearPeds[j + 1] = nil; - } - // Above loop won't work when it's 9, so we need to empty slot 9. - m_nearPeds[9] = nil; - m_numNearPeds--; - } else - i++; - } - } else { - CVector centre = CEntity::GetBoundCentre(); - CRect rect( - (centre.x - 20.0f) * 0.025f + 50.0f, - (centre.y - 20.0f) * 0.025f + 50.0f, - (centre.x + 20.0f) * 0.025f + 50.0f, - (centre.y + 20.0f) * 0.025f + 50.0f); - - for(int y = rect.top; y <= rect.bottom; y++) { - for(int x = rect.left; x <= rect.right; x++) { - for (CPtrNode *pedPtrNode = CWorld::GetSector(x,y)->m_lists[ENTITYLIST_PEDS].first; pedPtrNode; pedPtrNode = pedPtrNode->next) { - CPed *ped = (CPed*)pedPtrNode->item; - if (ped != this && !ped->bInVehicle) { - float dist = (ped->GetPosition() - GetPosition()).Magnitude2D(); - if (distanceMultToCountPedNear * 30.0f > dist) - { - unsortedNearPeds[nextNearPedSlot] = ped; - nextNearPedSlot++; - } - } - } - } - } - unsortedNearPeds[nextNearPedSlot] = nil; - SortPeds(unsortedNearPeds, 0, nextNearPedSlot - 1); - for (m_numNearPeds = 0; m_numNearPeds < 10; m_numNearPeds++) { - CPed *ped = unsortedNearPeds[m_numNearPeds]; - if (!ped) - break; - - m_nearPeds[m_numNearPeds] = ped; - } - for (int pedToClear = m_numNearPeds; pedToClear < 10; pedToClear++) - m_nearPeds[pedToClear] = nil; - } -} - -void -CPed::SetPedStats(ePedStats pedStat) -{ - m_pedStats = CPedStats::ms_apPedStats[pedStat]; -} - -void -CPed::SetModelIndex(uint32 mi) -{ - CEntity::SetModelIndex(mi); - RpAnimBlendClumpInit((RpClump*) m_rwObject); - RpAnimBlendClumpFillFrameArray((RpClump*) m_rwObject, m_pFrames); - CPedModelInfo *modelInfo = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); - SetPedStats((ePedStats) modelInfo->m_pedStatType); - m_headingRate = m_pedStats->m_headingChangeRate; - m_animGroup = (AssocGroupId) modelInfo->m_animGroup; - CAnimManager::AddAnimation((RpClump*) m_rwObject, m_animGroup, ANIM_IDLE_STANCE); - - // This is a mistake by R*, velocity is CVector, whereas m_vecAnimMoveDelta is CVector2D. - (*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity = (CVector*) &m_vecAnimMoveDelta; -} - -void -CPed::RemoveLighting(bool reset) -{ - CRenderer::RemoveVehiclePedLights(this, reset); -} - -bool -CPed::SetupLighting(void) -{ - ActivateDirectional(); - SetAmbientColoursForPedsCarsAndObjects(); - if (bRenderScorched) { - WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f); - } else { - // Note that this lightMult is only affected by LIGHT_DARKEN. If there's no LIGHT_DARKEN, it will be 1.0. - float lightMult = CPointLights::GenerateLightsAffectingObject(&GetPosition()); - if (!bHasBlip && lightMult != 1.0f) { - SetAmbientAndDirectionalColours(lightMult); - return true; - } - } - return false; -} - -void -CPed::Teleport(CVector pos) -{ - CWorld::Remove(this); - GetPosition() = pos; - bIsStanding = false; - m_nPedStateTimer = 0; - m_actionX = 0.0f; - m_actionY = 0.0f; - m_pDamageEntity = nil; - CWorld::Add(this); -} - -void -CPed::CalculateNewOrientation(void) -{ - if (CReplay::IsPlayingBack() || !IsPedInControl()) - return; - - CVector pos = *GetPosition(); - - GetMatrix().SetRotate(0.0f, 0.0f, m_fRotationCur); - - // Because SetRotate makes pos. all 0 - GetPosition() = pos; -} - -float -CPed::WorkOutHeadingForMovingFirstPerson(float offset) -{ - if (!IsPlayer()) - return 0.0f; - - CPad *pad0 = CPad::GetPad(0); - float leftRight = pad0->GetPedWalkLeftRight(); - float upDown = pad0->GetPedWalkUpDown(); - float &angle = ((CPlayerPed*)this)->m_fWalkAngle; - - if (upDown != 0.0f) { - angle = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown); - } else { - if (leftRight < 0.0f) - angle = 0.5 * PI; - else if (leftRight > 0.0f) - angle = -0.5 * PI; - } - - return CGeneral::LimitRadianAngle(offset + angle); -} - -void -CPed::CalculateNewVelocity(void) -{ - if (IsPedInControl()) { - float headAmount = DEGTORAD(m_headingRate) * CTimer::GetTimeStep(); - m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur); - float limitedRotDest = CGeneral::LimitRadianAngle(m_fRotationDest); - - if (m_fRotationCur - PI > limitedRotDest) { - limitedRotDest += 2 * PI; - } else if(PI + m_fRotationCur < limitedRotDest) { - limitedRotDest -= 2 * PI; - } - - if (IsPlayer() && m_nPedState == PED_ATTACK) - headAmount /= 4.0f; - - float neededTurn = limitedRotDest - m_fRotationCur; - if (neededTurn <= headAmount) { - if (neededTurn > (-headAmount)) - m_fRotationCur += neededTurn; - else - m_fRotationCur -= headAmount; - } else { - m_fRotationCur += headAmount; - } - } - - CVector2D forward(sin(m_fRotationCur), cos(m_fRotationCur)); - - m_moved.x = CrossProduct2D(m_vecAnimMoveDelta, forward); // (m_vecAnimMoveDelta.x * cos(m_fRotationCur)) + -sin(m_fRotationCur) * m_vecAnimMoveDelta.y; - m_moved.y = DotProduct2D(m_vecAnimMoveDelta, forward); // m_vecAnimMoveDelta.y* cos(m_fRotationCur) + (m_vecAnimMoveDelta.x * sin(m_fRotationCur)); - - if (CTimer::GetTimeStep() >= 0.01f) { - m_moved = m_moved * (1 / CTimer::GetTimeStep()); - } else { - m_moved = m_moved * (1 / 100.0f); - } - - if ((!TheCamera.Cams[TheCamera.ActiveCam].GetWeaponFirstPersonOn() && !TheCamera.Cams[0].Using3rdPersonMouseCam()) - || FindPlayerPed() != this || !CanStrafeOrMouseControl()) - return; - - float walkAngle = WorkOutHeadingForMovingFirstPerson(m_fRotationCur); - float pedSpeed = m_moved.Magnitude(); - float localWalkAngle = CGeneral::LimitRadianAngle(walkAngle - m_fRotationCur); - - if (localWalkAngle < -0.5 * PI) { - localWalkAngle += PI; - } else if (localWalkAngle > 0.5 * PI) { - localWalkAngle -= PI; - } - - // Interestingly this part is responsible for diagonal walking. - if (localWalkAngle > -DEGTORAD(50.0f) && localWalkAngle < DEGTORAD(50.0f)) { - TheCamera.Cams[TheCamera.ActiveCam].m_fPlayerVelocity = pedSpeed; - m_moved = CVector2D(-sin(walkAngle), cos(walkAngle)) * pedSpeed; - } - - CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_IDLE_STANCE); - CAnimBlendAssociation* fightAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_FIGHT_IDLE); - - if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc) { - LimbOrientation newUpperLegs; - newUpperLegs.phi = localWalkAngle; - - if (newUpperLegs.phi < -DEGTORAD(100.0f)) { - newUpperLegs.phi += PI; - } else if (newUpperLegs.phi > DEGTORAD(100.0f)) { - newUpperLegs.phi -= PI; - } - - if (newUpperLegs.phi > -DEGTORAD(50.0f) && newUpperLegs.phi < DEGTORAD(50.0f)) { - newUpperLegs.theta = 0.0f; - m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGL], &newUpperLegs, false); - m_pedIK.RotateTorso(m_pFrames[PED_UPPERLEGR], &newUpperLegs, false); - } - } -} - -bool -CPed::CanBeDeleted(void) -{ - if (this->bInVehicle) - return false; - - switch (CharCreatedBy) { - case RANDOM_CHAR: - return true; - case MISSION_CHAR: - return false; - default: - return true; - } -} - -bool -CPed::CanPedDriveOff(void) -{ - if (m_nPedState != PED_DRIVING || m_lookTimer > CTimer::GetTimeInMilliseconds()) - return false; - - for (int i = 0; i < m_numNearPeds; i++) { - CPed *ped = m_nearPeds[i]; - if (ped->m_nPedType == m_nPedType && ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && ped->m_carInObjective == m_carInObjective) { - m_lookTimer = CTimer::GetTimeInMilliseconds() + 1000; - return false; - } - } - return true; -} - -// I couldn't find where it is used. -bool -CPed::CanPedJumpThis(int32 unused) -{ - CVector2D forward(-sin(m_fRotationCur), cos(m_fRotationCur)); - CVector pos = GetPosition(); - // wat? - CVector forwardPos( - forward.x + pos.x, - forward.y + pos.y, - pos.z); - return CWorld::GetIsLineOfSightClear(pos, forwardPos, true, false, false, true, false, false, false); -} - -bool -CPed::CanPedReturnToState(void) -{ - return m_nPedState <= PED_STATES_NO_AI && m_nPedState != PED_AIM_GUN && m_nPedState != PED_ATTACK && - m_nPedState != PED_FIGHT && m_nPedState != PED_STEP_AWAY && m_nPedState != PED_SNIPER_MODE && m_nPedState != PED_LOOK_ENTITY; -} - -bool -CPed::CanSeeEntity(CEntity *entity, float threshold) -{ - float neededAngle = CGeneral::GetRadianAngleBetweenPoints( - entity->GetPosition().x, - entity->GetPosition().x, - GetPosition().x, - GetPosition().y); - - if (neededAngle < 0.0f) - neededAngle += 2 * PI; - else if (neededAngle > 2 * PI) - neededAngle -= 2 * PI; - - float ourAngle = m_fRotationCur; - if (ourAngle < 0.0f) - ourAngle += 2 * PI; - else if (ourAngle > 2 * PI) - ourAngle -= 2 * PI; - - float neededTurn = fabs(neededAngle - ourAngle); - - return neededTurn < threshold || 2 * PI - threshold < neededTurn; -} - -bool -CPed::IsTemporaryObjective(eObjective objective) -{ - return objective == OBJECTIVE_LEAVE_VEHICLE || objective == OBJECTIVE_SET_LEADER || - objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER; -} - -void -CPed::SetMoveState(eMoveState state) -{ - m_nMoveState = state; -} - -void -CPed::SetObjectiveTimer(int time) -{ - if (time == 0) { - m_objectiveTimer = 0; - } else if (CTimer::GetTimeInMilliseconds() > m_objectiveTimer) { - m_objectiveTimer = CTimer::GetTimeInMilliseconds() + time; - } -} - -void -CPed::ForceStoredObjective(eObjective objective) -{ - if (objective != OBJECTIVE_ENTER_CAR_AS_DRIVER && objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) { - m_prevObjective = m_objective; - return; - } - - switch (m_objective) - { - case OBJECTIVE_FLEE_TILL_SAFE: - case OBJECTIVE_KILL_CHAR_ON_FOOT: - case OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE: - case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS: - case OBJECTIVE_GOTO_CHAR_ON_FOOT: - case OBJECTIVE_ENTER_CAR_AS_PASSENGER: - case OBJECTIVE_ENTER_CAR_AS_DRIVER: - case OBJECTIVE_GOTO_AREA_ON_FOOT: - case OBJECTIVE_RUN_TO_AREA: - return; - default: - m_prevObjective = m_objective; - } -} - -void -CPed::SetStoredObjective(void) -{ - if (m_objective == m_prevObjective) - return; - - switch (m_objective) - { - case OBJECTIVE_FLEE_TILL_SAFE: - case OBJECTIVE_KILL_CHAR_ON_FOOT: - case OBJECTIVE_KILL_CHAR_ANY_MEANS: - case OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE: - case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS: - case OBJECTIVE_GOTO_CHAR_ON_FOOT: - case OBJECTIVE_FOLLOW_PED_IN_FORMATION: - case OBJECTIVE_LEAVE_VEHICLE: - case OBJECTIVE_ENTER_CAR_AS_PASSENGER: - case OBJECTIVE_ENTER_CAR_AS_DRIVER: - case OBJECTIVE_GOTO_AREA_ON_FOOT: - case OBJECTIVE_RUN_TO_AREA: - return; - default: - m_prevObjective = m_objective; - } -} - -void -CPed::RestorePreviousObjective(void) -{ - if (m_objective == OBJECTIVE_NONE) - return; - - if (m_objective != OBJECTIVE_LEAVE_VEHICLE && m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) - m_pedInObjective = nil; - - if (m_objective == OBJECTIVE_WAIT_IN_CAR_THEN_GETOUT) { - m_objective = OBJECTIVE_NONE; - if (m_pMyVehicle) - SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle); - - } else { - m_objective = m_prevObjective; - m_prevObjective = OBJECTIVE_NONE; - } - m_ped_flagD40 = false; -} - -void -CPed::SetLeader(CEntity *leader) -{ - m_leader = (CPed*)leader; - - if(m_leader) - m_leader->RegisterReference((CEntity **)&m_leader); -} - -void -CPed::SetObjective(eObjective newObj, void *entity) -{ - if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD) - return; - - if (m_prevObjective == newObj) { - // Why? - if (m_prevObjective != OBJECTIVE_NONE) - return; - } - - if (entity == this) - return; - - SetObjectiveTimer(0); - if (m_objective == newObj) { - switch (newObj) { - case OBJECTIVE_KILL_CHAR_ON_FOOT: - case OBJECTIVE_KILL_CHAR_ANY_MEANS: - case OBJECTIVE_GOTO_CHAR_ON_FOOT: - case OBJECTIVE_FOLLOW_PED_IN_FORMATION: - case OBJECTIVE_GOTO_AREA_ANY_MEANS: - case OBJECTIVE_FIGHT_CHAR: - if (m_pedInObjective == entity) - return; - - break; - case OBJECTIVE_LEAVE_VEHICLE: - case OBJECTIVE_FLEE_CAR: - return; - case OBJECTIVE_ENTER_CAR_AS_PASSENGER: - case OBJECTIVE_ENTER_CAR_AS_DRIVER: - case OBJECTIVE_DESTROY_CAR: - case OBJECTIVE_SOLICIT: - case OBJECTIVE_BUY_ICE_CREAM: - if (m_carInObjective == entity) - return; - - break; - case OBJECTIVE_SET_LEADER: - if (m_leader == entity) - return; - - break; - default: - break; - } - } else { - if (newObj == OBJECTIVE_LEAVE_VEHICLE && !bInVehicle) - return; - } - - m_ped_flagD40 = false; - if (!IsTemporaryObjective(m_objective) || IsTemporaryObjective(newObj)) { - if (m_objective != newObj) { - if (IsTemporaryObjective(newObj)) - ForceStoredObjective(newObj); - else - SetStoredObjective(); - } - m_objective = newObj; - } else { - m_prevObjective = newObj; - } - - switch (newObj) { - case OBJECTIVE_WAIT_IN_CAR_THEN_GETOUT: - - // In this special case, entity parameter isn't CEntity, but int. - SetObjectiveTimer((int)entity); - return; - case OBJECTIVE_KILL_CHAR_ON_FOOT: - case OBJECTIVE_KILL_CHAR_ANY_MEANS: - case OBJECTIVE_MUG_CHAR: - m_pLastPathNode = nil; - m_ped_flagD20 = false; - m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f); - m_pedInObjective = (CPed*)entity; - m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective); - m_pLookTarget = (CEntity*)entity; - m_pLookTarget->RegisterReference((CEntity**)&m_pLookTarget); - return; - case OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE: - case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS: - case OBJECTIVE_GOTO_CHAR_ON_FOOT: - case OBJECTIVE_FIGHT_CHAR: - m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f); - m_pedInObjective = (CPed*)entity; - m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective); - return; - case OBJECTIVE_FOLLOW_PED_IN_FORMATION: - m_pedInObjective = (CPed*)entity; - m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective); - m_pedFormation = 1; - return; - case OBJECTIVE_LEAVE_VEHICLE: - case OBJECTIVE_FLEE_CAR: - m_carInObjective = (CVehicle*)entity; - m_carInObjective->RegisterReference((CEntity **)&m_carInObjective); - if (!m_carInObjective->bIsBus || m_leaveCarTimer) - return; - break; - case OBJECTIVE_ENTER_CAR_AS_PASSENGER: - case OBJECTIVE_ENTER_CAR_AS_DRIVER: - if (m_nMoveState == PEDMOVE_STILL) - SetMoveState(PEDMOVE_RUN); - - if (((CVehicle*)entity)->m_vehType == VEHICLE_TYPE_BOAT && !IsPlayer()) { - RestorePreviousObjective(); - return; - } - // fall through - case OBJECTIVE_DESTROY_CAR: - case OBJECTIVE_SOLICIT: - case OBJECTIVE_BUY_ICE_CREAM: - m_carInObjective = (CVehicle*)entity; - m_carInObjective->RegisterReference((CEntity**)&m_carInObjective); - m_pSeekTarget = m_carInObjective; - m_pSeekTarget->RegisterReference((CEntity**)&m_pSeekTarget); - m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f); - if (newObj == OBJECTIVE_SOLICIT) { - m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 10000; - } else if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == MISSION_CHAR && - (m_carInObjective->m_status == STATUS_PLAYER_DISABLED || CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls)) { - SetObjectiveTimer(14000); - } else { - m_objectiveTimer = 0; - } - return; - case OBJECTIVE_SET_LEADER: - SetLeader((CEntity*)entity); - RestorePreviousObjective(); - return; - default: - return; - } - for (int i=0; i < m_carInObjective->m_nNumMaxPassengers; i++) { - if (m_carInObjective->pPassengers[i] == this) { - m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 1200 * i; - return; - } - } -} - -void -CPed::SetIdle(void) -{ - if (m_nPedState != PED_IDLE && m_nPedState != PED_MUG && m_nPedState != PED_FLEE_ENTITY) { - m_nPedState = PED_IDLE; - SetMoveState(PEDMOVE_STILL); - } - if (m_nWaitState == WAITSTATE_FALSE) { - m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2000, 4000); - } -} - -void -CPed::SetObjective(eObjective newObj) -{ - if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD) - return; - - if (newObj == OBJECTIVE_NONE) { - if ((m_objective == OBJECTIVE_LEAVE_VEHICLE || m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) - && IsPedInControl()) { - - m_ped_flagG8 = true; - return; - } - // Unused code from assembly... - /* - else if(m_objective == OBJECTIVE_FLEE_CAR) { - - } else { - - } - */ - m_objective = newObj; - m_prevObjective = OBJECTIVE_NONE; - } else if (m_prevObjective != newObj || m_prevObjective == OBJECTIVE_NONE) { - SetObjectiveTimer(0); - - if (m_objective == newObj) - return; - - if (IsTemporaryObjective(m_objective)) { - m_prevObjective = newObj; - } else { - if (m_objective != newObj) - SetStoredObjective(); - - m_objective = newObj; - } - m_ped_flagD40 = false; - - switch (newObj) { - case OBJECTIVE_NONE: - m_prevObjective = OBJECTIVE_NONE; - break; - case OBJECTIVE_HAIL_TAXI: - m_nWaitTimer = 0; - SetIdle(); - SetMoveState(PEDMOVE_STILL); - break; - default: - break; - } - } -} - -// Only used in 01E1: SET_CHAR_OBJ_FOLLOW_ROUTE opcode -// IDA fails very badly in here, puts a fake loop and ignores SetFollowRoute call... -void -CPed::SetObjective(eObjective newObj, int16 routePoint, int16 routeType) -{ - if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD) - return; - - if (m_prevObjective == newObj && m_prevObjective != OBJECTIVE_NONE) - return; - - SetObjectiveTimer(0); - - if (m_objective == newObj && newObj == OBJECTIVE_FOLLOW_ROUTE && m_routeLastPoint == routePoint && m_routeType == routeType) - return; - - m_ped_flagD40 = false; - if (IsTemporaryObjective(m_objective)) { - m_prevObjective = newObj; - } else { - if (m_objective != newObj) - SetStoredObjective(); - - m_objective = newObj; - } - - if (newObj == OBJECTIVE_FOLLOW_ROUTE) { - SetFollowRoute(routePoint, routeType); - } -} - -void -CPed::ClearChat(void) -{ - CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_IDLE_CHAT); - if (animAssoc) { - animAssoc->blendDelta = -8.0f; - animAssoc->flags |= ASSOC_DELETEFADEDOUT; - } - bIsTalking = false; - ClearLookFlag(); - RestorePreviousState(); -} - -bool -CPed::IsGangMember(void) -{ - return m_nPedType >= PEDTYPE_GANG1 && m_nPedType <= PEDTYPE_GANG9; -} - -void -CPed::InformMyGangOfAttack(CEntity *attacker) -{ - CPed *attackerPed; - - if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) - return; - - if (attacker->IsPed()) { - attackerPed = (CPed*)attacker; - } else { - if (!attacker->IsVehicle()) - return; - - attackerPed = ((CVehicle*)attacker)->pDriver; - if (!attackerPed) - return; - } - - if (attackerPed->m_nPedType == PEDTYPE_COP) - return; - - for (int i = 0; i < m_numNearPeds; i++) { - CPed *nearPed = m_nearPeds[i]; - if (nearPed && nearPed != this) { - CPed *leader = nearPed->m_leader; - if (leader && leader == this && nearPed->m_pedStats->m_fear < nearPed->m_pedStats->m_temper) - { - nearPed->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, attackerPed); - nearPed->SetObjectiveTimer(30000); - } - } - } -} - -void -CPed::QuitEnteringCar(void) -{ - CAnimBlendAssociation *animAssoc = m_pVehicleAnim; - CVehicle *veh = m_pMyVehicle; - if (animAssoc) - animAssoc->blendDelta = -1000.0f; - - RestartNonPartialAnims(); - - if (!RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_IDLE_STANCE)) - CAnimManager::BlendAnimation((RpClump*) m_rwObject, m_animGroup, ANIM_IDLE_STANCE, 100.0f); - - if (veh) { - if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_nPedState == PED_CARJACK) - veh->m_veh_flagC10 = false; - - if (veh->m_nNumGettingIn != 0) - veh->m_nNumGettingIn--; - - veh->m_nGettingInFlags = GetVehEnterExitFlag(m_vehEnterType); - } - - bUsesCollision = true; - - if (IsPlayer() && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) { - if (IsPlayer() && m_storedWeapon != NO_STORED_WEAPON) { - SetCurrentWeapon(m_storedWeapon); - m_storedWeapon = NO_STORED_WEAPON; - } - } else { - CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); - AddWeaponModel(curWeapon->m_nModelId); - } - if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD) { - animAssoc = m_pVehicleAnim; - if (animAssoc) { - animAssoc->blendDelta = -4.0; - animAssoc->flags |= ASSOC_FADEOUTWHENDONE; - animAssoc = m_pVehicleAnim; - animAssoc->flags &= ~ASSOC_RUNNING; - } - } else - SetIdle(); - - m_pVehicleAnim = nil; - - if (veh) { - if (veh->m_autoPilot.m_nCruiseSpeed == 0) - veh->m_autoPilot.m_nCruiseSpeed = 17; - } -} - -void -CPed::ReactToAttack(CEntity *attacker) -{ - if (IsPlayer() && attacker->IsPed()) { - InformMyGangOfAttack(attacker); - SetLookFlag(attacker, 1); - SetLookTimer(700); - return; - } - - if (IsPedInControl() && (CharCreatedBy != MISSION_CHAR || bRespondsToThreats)) { - CPed *ourLeader = m_leader; - if (ourLeader != attacker && (!ourLeader || FindPlayerPed() != ourLeader) - && attacker->IsPed()) { - - CPed *attackerPed = (CPed*)attacker; - if (bNotAllowedToDuck) { - if (!attackerPed->GetWeapon()->IsTypeMelee()) { - field_4E8 = CTimer::GetTimeInMilliseconds(); - return; - } - } else if (bCrouchWhenShooting || m_ped_flagE1) { - SetDuck(CGeneral::GetRandomNumberInRange(1000,3000)); - return; - } - - if (m_pedStats->m_fear <= 100 - attackerPed->m_pedStats->m_temper) { - if (m_pedStats != attackerPed->m_pedStats) { - if (IsGangMember() || m_nPedType == PEDTYPE_EMERGENCY || m_nPedType == PEDTYPE_FIREMAN) { - RegisterThreatWithGangPeds(attackerPed); - } - if (!attackerPed->GetWeapon()->IsTypeMelee() && GetWeapon()->IsTypeMelee()) { - SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, attacker); - SetMoveState(PEDMOVE_RUN); - } else { - SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, attacker); - SetObjectiveTimer(20000); - } - } - } else { - SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, attackerPed); - SetMoveState(PEDMOVE_RUN); - if (attackerPed->GetWeapon()->IsTypeMelee()) - Say(SOUND_PED_FLEE_RUN); - } - } - } -} - -bool -CPed::TurnBody(void) -{ - float lookDir; - bool doneSmoothly = true; - - if (m_pLookTarget) { - CVector &lookPos = m_pLookTarget->GetPosition(); - - lookDir = CGeneral::GetRadianAngleBetweenPoints( - lookPos.x, - lookPos.y, - GetPosition().x, - GetPosition().y); - } else - lookDir = m_fLookDirection; - - float limitedLookDir = CGeneral::LimitRadianAngle(lookDir); - float currentRot = m_fRotationCur; - - if (currentRot - PI > limitedLookDir) - limitedLookDir += 2 * PI; - else if (PI + currentRot < limitedLookDir) - limitedLookDir -= 2 * PI; - - float neededTurn = currentRot - limitedLookDir; - m_fRotationDest = limitedLookDir; - - if (fabs(neededTurn) > 0.05f) { - doneSmoothly = false; - currentRot -= neededTurn * 0.2f; - } - - m_fRotationCur = currentRot; - m_fLookDirection = limitedLookDir; - return doneSmoothly; -} - -void -CPed::Chat(void) -{ - if (bIsLooking && TurnBody()) - ClearLookFlag(); - - if (!m_pLookTarget || !m_pLookTarget->IsPed()) { - ClearChat(); - return; - } - - CPed *partner = (CPed*) m_pLookTarget; - - if (partner->m_nPedState != PED_CHAT) { - ClearChat(); - if (partner->m_pedInObjective) { - if (partner->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || - partner->m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE) - ReactToAttack(partner->m_pedInObjective); - } - return; - } - if (bIsTalking) { - if (CGeneral::GetRandomNumber() < 512) { - CAnimBlendAssociation *chatAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_IDLE_CHAT); - if (chatAssoc) { - chatAssoc->blendDelta = -4.0f; - chatAssoc->flags |= ASSOC_FADEOUTWHENDONE; - } - bIsTalking = false; - } else - Say(SOUND_PED_CHAT); - - } else if (!RpAnimBlendClumpGetFirstAssociation((RpClump*)m_rwObject, ASSOC_FLAG100)) { - - if (CGeneral::GetRandomNumber() < 20) { - CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f); - } - if (!bIsTalking) { - CAnimBlendAssociation *chatAssoc = CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ANIM_IDLE_CHAT, 4.0f); - float chatTime = CGeneral::GetRandomNumberInRange(0.0f, 3.0f); - chatAssoc->SetCurrentTime(chatTime); - - bIsTalking = true; - Say(SOUND_PED_CHAT); - } - } - if (m_standardTimer && CTimer::GetTimeInMilliseconds() > m_standardTimer) { - ClearChat(); - m_standardTimer = CTimer::GetTimeInMilliseconds() + 30000; - } -} - -WRAPPER void CPed::PedGetupCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE810); } -WRAPPER void CPed::PedStaggerCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8D0); } -WRAPPER void CPed::PedEvadeCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D36E0); } -WRAPPER void CPed::FinishDieAnimCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D3950); } -WRAPPER void CPed::FinishedWaitCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D6520); } -WRAPPER void CPed::FinishLaunchCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D7490); } -WRAPPER void CPed::FinishHitHeadCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D7A80); } -WRAPPER void CPed::PedAnimGetInCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4DEC80); } -WRAPPER void CPed::PedAnimDoorOpenCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4DE500); } -WRAPPER void CPed::PedAnimPullPedOutCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4DEAF0); } -WRAPPER void CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4DF1B0); } -WRAPPER void CPed::SetInCarCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CF220); } -WRAPPER void CPed::PedSetOutCarCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8F0); } -WRAPPER void CPed::PedAnimAlignCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4DE130); } -WRAPPER void CPed::PedAnimStepOutCarCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4DF5C0); } -WRAPPER void CPed::PedSetInTrainCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4E3290); } -WRAPPER void CPed::PedSetOutTrainCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4E36E0); } -WRAPPER void CPed::FinishFightMoveCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4E9830); } -WRAPPER void CPed::PedAnimDoorCloseRollingCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4E4B90); } -WRAPPER void CPed::FinishJumpCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D7A50); } -WRAPPER void CPed::PedLandCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8A0); } -WRAPPER void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4C6580); } -WRAPPER void CPed::RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D6550); } - -STARTPATCHES - InjectHook(0x4C41C0, &CPed::ctor, PATCH_JUMP); - InjectHook(0x4C50D0, &CPed::dtor, PATCH_JUMP); - InjectHook(0x4CF8F0, &CPed::AddWeaponModel, PATCH_JUMP); - InjectHook(0x4C6AA0, &CPed::AimGun, PATCH_JUMP); - InjectHook(0x4EB470, &CPed::ApplyHeadShot, PATCH_JUMP); - InjectHook(0x4EAEE0, &CPed::RemoveBodyPart, PATCH_JUMP); - InjectHook(0x4C6460, (void (CPed::*)(CEntity*, bool)) &CPed::SetLookFlag, PATCH_JUMP); - InjectHook(0x4C63E0, (void (CPed::*)(float, bool)) &CPed::SetLookFlag, PATCH_JUMP); - InjectHook(0x4D12E0, &CPed::SetLookTimer, PATCH_JUMP); - InjectHook(0x4C5700, &CPed::OurPedCanSeeThisOne, PATCH_JUMP); - InjectHook(0x4D2BB0, &CPed::Avoid, PATCH_JUMP); - InjectHook(0x4C6A50, &CPed::ClearAimFlag, PATCH_JUMP); - InjectHook(0x4C64F0, &CPed::ClearLookFlag, PATCH_JUMP); - InjectHook(0x4EB670, &CPed::IsPedHeadAbovePos, PATCH_JUMP); - InjectHook(0x4E68A0, &CPed::FinishedAttackCB, PATCH_JUMP); - InjectHook(0x4E5BD0, &CheckForPedsOnGroundToAttack, PATCH_JUMP); - InjectHook(0x4E6BA0, &CPed::Attack, PATCH_JUMP); - InjectHook(0x4CF980, &CPed::RemoveWeaponModel, PATCH_JUMP); - InjectHook(0x4CFA60, &CPed::SetCurrentWeapon, PATCH_JUMP); - InjectHook(0x4E4A10, &CPed::Duck, PATCH_JUMP); - InjectHook(0x4E4A30, &CPed::ClearDuck, PATCH_JUMP); - InjectHook(0x4E6180, &CPed::ClearPointGunAt, PATCH_JUMP); - InjectHook(0x4E07D0, &CPed::BeingDraggedFromCar, PATCH_JUMP); - InjectHook(0x4CF000, &CPed::PedSetDraggedOutCarCB, PATCH_JUMP); - InjectHook(0x4C5D80, &CPed::RestartNonPartialAnims, PATCH_JUMP); - InjectHook(0x4E4730, &CPed::GetLocalPositionToOpenCarDoor, PATCH_JUMP); - InjectHook(0x4E4660, (void (*)(CVector*, CVehicle*, uint32, float)) CPed::GetPositionToOpenCarDoor, PATCH_JUMP); - InjectHook(0x4E1A30, (void (*)(CVector*, CVehicle*, uint32)) CPed::GetPositionToOpenCarDoor, PATCH_JUMP); - InjectHook(0x4DF940, &CPed::LineUpPedWithCar, PATCH_JUMP); - InjectHook(0x4CC6C0, &CPed::PlayFootSteps, PATCH_JUMP); - InjectHook(0x4C5350, &CPed::BuildPedLists, PATCH_JUMP); - InjectHook(0x4CF9B0, &CPed::GiveWeapon, PATCH_JUMP); - InjectHook(0x4C52A0, &CPed::SetModelIndex_, PATCH_JUMP); - InjectHook(0x4D6570, &CPed::FlagToDestroyWhenNextProcessed_, PATCH_JUMP); - InjectHook(0x4A7D30, &CPed::SetupLighting_, PATCH_JUMP); - InjectHook(0x4A7DC0, &CPed::RemoveLighting_, PATCH_JUMP); - InjectHook(0x4D3E70, &CPed::Teleport_, PATCH_JUMP); - InjectHook(0x4C7EA0, &CPed::CalculateNewOrientation, PATCH_JUMP); - InjectHook(0x4C78F0, &CPed::WorkOutHeadingForMovingFirstPerson, PATCH_JUMP); - InjectHook(0x4C73F0, &CPed::CalculateNewVelocity, PATCH_JUMP); - InjectHook(0x4D72F0, &CPed::CanPedJumpThis, PATCH_JUMP); - InjectHook(0x4DD820, &CPed::CanSeeEntity, PATCH_JUMP); - InjectHook(0x4D9460, &CPed::RestorePreviousObjective, PATCH_JUMP); - InjectHook(0x4D82C0, (void (CPed::*)(eObjective)) &CPed::SetObjective, PATCH_JUMP); - InjectHook(0x4D83E0, (void (CPed::*)(eObjective, void*)) &CPed::SetObjective, PATCH_JUMP); - InjectHook(0x4D89A0, (void (CPed::*)(eObjective, int16, int16)) &CPed::SetObjective, PATCH_JUMP); - InjectHook(0x4DDEC0, &CPed::ReactToAttack, PATCH_JUMP); - InjectHook(0x4D0600, &CPed::SetIdle, PATCH_JUMP); - InjectHook(0x4E0E00, &CPed::QuitEnteringCar, PATCH_JUMP); - InjectHook(0x4E4AD0, &CPed::InformMyGangOfAttack, PATCH_JUMP); - InjectHook(0x4D3C80, &CPed::ClearChat, PATCH_JUMP); - InjectHook(0x4D1390, &CPed::TurnBody, PATCH_JUMP); - InjectHook(0x4D3AC0, &CPed::Chat, PATCH_JUMP); -ENDPATCHES |