More peds

This commit is contained in:
eray orçunus 2019-08-13 01:30:31 +03:00
parent c3c9b1c40e
commit e5d089db88
6 changed files with 456 additions and 16 deletions

View File

@ -33,6 +33,7 @@
#include "Pickups.h"
#include "Train.h"
#include "TrafficLights.h"
#include "PedRoutes.h"
WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); }
WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); }
@ -65,15 +66,18 @@ CColPoint &aTempPedColPts = *(CColPoint*)0x62DB14;
// TODO: CommentWaitTime should be hardcoded into exe, and it isn't reversed yet.
CPedAudioData (&CPed::CommentWaitTime)[38] = *(CPedAudioData(*)[38]) * (uintptr*)0x5F94C4;
uint16 nPlayerInComboMove; // 0x95CC58
uint16 nPlayerInComboMove;
FightMove (&tFightMoves)[24] = * (FightMove(*)[24]) * (uintptr*)0x5F9844;
uint16 &CPed::nThreatReactionRangeMultiplier = *(uint16*)0x5F8C98;
CVector &vecPedCarDoorAnimOffset = *(CVector*)0x62E030;
CVector &vecPedCarDoorLoAnimOffset = *(CVector*)0x62E03C;
CVector &vecPedVanRearDoorAnimOffset = *(CVector*)0x62E048;
CVector vecPedCarDoorAnimOffset;
CVector vecPedCarDoorLoAnimOffset;
CVector vecPedVanRearDoorAnimOffset;
CVector &vecPedQuickDraggedOutCarAnimOffset = *(CVector*)0x62E06C;
CVector &vecPedDraggedOutCarAnimOffset = *(CVector*)0x62E060;
CVector &vecPedTrainDoorAnimOffset = *(CVector*)0x62E054;
CVector2D &CPed::ms_vec2DFleePosition = *(CVector2D*)0x6EDF70;
@ -373,8 +377,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_pLastPathNode = nil;
m_pNextPathNode = nil;
m_routeLastPoint = -1;
m_routePoints = 0;
m_routePos = 0;
m_routeStartPoint = 0;
m_routePointsPassed = 0;
m_routeType = 0;
m_bodyPartBleeding = -1;
@ -4066,8 +4070,7 @@ CPed::GrantAmmo(eWeaponType weaponType, uint32 ammo)
{
if (HasWeapon(weaponType)) {
GetWeapon(weaponType).m_nAmmoTotal += ammo;
}
else {
} else {
GetWeapon(weaponType).Initialise(weaponType, ammo);
m_maxWeaponTypeAllowed++;
}
@ -7262,6 +7265,403 @@ CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen)
}
}
bool
CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen)
{
CVector rfPos, lrPos, rrPos;
bool canEnter = false;
CVehicleModelInfo *vehModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(veh->m_modelIndex);
if (veh->m_modelIndex > MI_RHINO || veh->m_modelIndex != MI_BUS) {
CVector2D rfPosDist(999.0f, 999.0f);
CVector2D lrPosDist(999.0f, 999.0f);
CVector2D rrPosDist(999.0f, 999.0f);
if (!veh->pPassengers[0]
&& !(veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF)
&& veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, nil)) {
rfPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF);
canEnter = true;
rfPosDist = rfPos - GetPosition();
}
if (vehModel->m_numDoors == 4) {
if (!veh->pPassengers[1]
&& !(veh->m_nGettingInFlags & CAR_DOOR_FLAG_LR)
&& veh->IsRoomForPedToLeaveCar(CAR_DOOR_LR, nil)) {
lrPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_LR);
canEnter = true;
lrPosDist = lrPos - GetPosition();
}
if (!veh->pPassengers[2]
&& !(veh->m_nGettingInFlags & CAR_DOOR_FLAG_RR)
&& veh->IsRoomForPedToLeaveCar(CAR_DOOR_RR, nil)) {
rrPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RR);
canEnter = true;
rrPosDist = rrPos - GetPosition();
}
// When the door we should enter is blocked by some object.
if (!canEnter)
veh->ShufflePassengersToMakeSpace();
}
CVector2D nextToCompare = rfPosDist;
posToOpen = rfPos;
m_vehEnterType = CAR_DOOR_RF;
if (lrPosDist.MagnitudeSqr() < nextToCompare.MagnitudeSqr()) {
m_vehEnterType = CAR_DOOR_LR;
posToOpen = lrPos;
nextToCompare = lrPosDist;
}
if (rrPosDist.MagnitudeSqr() < nextToCompare.MagnitudeSqr()) {
m_vehEnterType = CAR_DOOR_RR;
posToOpen = rrPos;
}
return canEnter;
} else {
m_vehEnterType = CAR_DOOR_RF;
posToOpen = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF);
return true;
}
}
int
CPed::GetNextPointOnRoute(void)
{
int16 nextPoint = m_routePointsBeingPassed + m_routePointsPassed + m_routeStartPoint;
// Route is complete
if (nextPoint < 0 || nextPoint > 200 || m_routeLastPoint != CRouteNode::GetRouteThisPointIsOn(nextPoint)) {
switch (m_routeType) {
case PEDROUTE_STOP_WHEN_DONE:
nextPoint = -1;
break;
case PEDROUTE_GO_BACKWARD_WHEN_DONE:
m_routePointsBeingPassed = -m_routePointsBeingPassed;
nextPoint = m_routePointsBeingPassed + m_routePointsPassed + m_routeStartPoint;
break;
case PEDROUTE_GO_TO_START_WHEN_DONE:
m_routePointsPassed = -1;
nextPoint = m_routePointsBeingPassed + m_routePointsPassed + m_routeStartPoint;
break;
default:
break;
}
}
return nextPoint;
}
// TODO: enum
uint8
CPed::GetPedRadioCategory(uint32 modelIndex)
{
switch (modelIndex) {
case MI_MALE01:
case MI_FEMALE03:
case MI_PROSTITUTE2:
case MI_WORKER1:
case MI_MOD_MAN:
case MI_MOD_WOM:
case MI_ST_WOM:
case MI_FAN_WOM:
return 3;
case MI_TAXI_D:
case MI_PIMP:
case MI_MALE02:
case MI_FEMALE02:
case MI_FATFEMALE01:
case MI_FATFEMALE02:
case MI_DOCKER1:
case MI_WORKER2:
case MI_FAN_MAN2:
return 9;
case MI_GANG01:
case MI_GANG02:
case MI_SCUM_MAN:
case MI_SCUM_WOM:
case MI_HOS_WOM:
case MI_CONST1:
return 1;
case MI_GANG03:
case MI_GANG04:
case MI_GANG07:
case MI_GANG08:
case MI_CT_MAN2:
case MI_CT_WOM2:
case MI_B_MAN3:
case MI_SHOPPER3:
return 4;
case MI_GANG05:
case MI_GANG06:
case MI_GANG11:
case MI_GANG12:
case MI_CRIMINAL02:
case MI_B_WOM2:
case MI_ST_MAN:
case MI_HOS_MAN:
return 5;
case MI_FATMALE01:
case MI_LI_MAN2:
case MI_SHOPPER1:
case MI_CAS_MAN:
return 6;
case MI_PROSTITUTE:
case MI_P_WOM2:
case MI_LI_WOM2:
case MI_B_WOM3:
case MI_CAS_WOM:
return 2;
case MI_P_WOM1:
case MI_DOCKER2:
case MI_STUD_MAN:
return 7;
case MI_CT_MAN1:
case MI_CT_WOM1:
case MI_LI_MAN1:
case MI_LI_WOM1:
case MI_B_MAN1:
case MI_B_MAN2:
case MI_B_WOM1:
case MI_SHOPPER2:
case MI_STUD_WOM:
return 8;
default:
return 0;
}
}
// Some kind of VC leftover I think
int
CPed::GetWeaponSlot(eWeaponType weaponType)
{
if (HasWeapon(weaponType))
return weaponType;
else
return -1;
}
void
CPed::GoToNearestDoor(CVehicle *veh)
{
CVector posToOpen;
GetNearestDoor(veh, posToOpen);
SetSeek(posToOpen, 0.5f);
SetMoveState(PEDMOVE_RUN);
}
bool
CPed::HaveReachedNextPointOnRoute(float distToCountReached)
{
if ((m_nextRoutePointPos - GetPosition()).Magnitude2D() >= distToCountReached)
return false;
m_routePointsPassed += m_routePointsBeingPassed;
return true;
}
void
CPed::Idle(void)
{
CVehicle *veh = m_pMyVehicle;
if (veh && veh->m_nGettingOutFlags && m_vehEnterType) {
if (veh->m_nGettingOutFlags & GetCarDoorFlag(m_vehEnterType)) {
if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
CVector doorPos = GetPositionToOpenCarDoor(veh, m_vehEnterType);
CVector doorDist = GetPosition() - doorPos;
if (doorDist.MagnitudeSqr() < 0.25f) {
SetMoveState(PEDMOVE_WALK);
return;
}
}
}
}
CAnimBlendAssociation *armedIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_ARMED);
CAnimBlendAssociation* unarmedIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
int waitTime;
if (m_nMoveState == PEDMOVE_STILL) {
eWeaponType curWeapon = GetWeapon()->m_eWeaponType;
if (!armedIdleAssoc ||
CTimer::GetTimeInMilliseconds() <= m_nWaitTimer && curWeapon != WEAPONTYPE_UNARMED && curWeapon != WEAPONTYPE_MOLOTOV && curWeapon != WEAPONTYPE_GRENADE) {
if ((!GetWeapon()->IsType2Handed() || curWeapon == WEAPONTYPE_SHOTGUN) && curWeapon != WEAPONTYPE_BASEBALLBAT
|| !unarmedIdleAssoc || unarmedIdleAssoc->blendAmount <= 0.95f || m_nWaitState != WAITSTATE_FALSE || CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) {
m_moved = CVector2D(0.0f, 0.0f);
return;
}
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_ARMED, 3.0f);
waitTime = CGeneral::GetRandomNumberInRange(4000, 7500);
} else {
armedIdleAssoc->blendDelta = -2.0f;
armedIdleAssoc->flags |= ASSOC_DELETEFADEDOUT;
waitTime = CGeneral::GetRandomNumberInRange(3000, 8500);
}
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + waitTime;
} else {
if (armedIdleAssoc) {
armedIdleAssoc->blendDelta = -8.0f;
armedIdleAssoc->flags |= ASSOC_DELETEFADEDOUT;
m_nWaitTimer = 0;
}
if (!IsPlayer())
SetMoveState(PEDMOVE_STILL);
}
m_moved = CVector2D(0.0f, 0.0f);
}
void
CPed::InTheAir(void)
{
CColPoint foundCol;
CEntity *foundEnt;
CVector ourPos = GetPosition();
CVector bitBelow = GetPosition();
bitBelow.z -= 4.04f;
if (m_vecMoveSpeed.z < 0.0f && !bIsPedDieAnimPlaying) {
if (m_nPedState != PED_DIE && m_nPedState != PED_DEAD) {
if (CWorld::ProcessLineOfSight(ourPos, bitBelow, foundCol, foundEnt, true, true, false, true, false, false, false)) {
if (GetPosition().z - foundCol.point.z < 1.3f)
SetLanding();
} else {
if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL)) {
if (m_vecMoveSpeed.z < -0.1f)
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_FALL, 4.0f);
}
}
}
}
}
void
CPed::SetLanding(void)
{
if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
return;
CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL);
CAnimBlendAssociation *landAssoc;
RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
if (fallAssoc) {
landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_COLLAPSE);
DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_COLLAPSE, 1.0f);
if (IsPlayer())
Say(SOUND_PED_LAND);
} else {
landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND);
DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_LAND, 1.0f);
}
landAssoc->SetFinishCallback(PedLandCB, this);
bIsInTheAir = false;
bIsLanding = true;
}
void
CPed::Initialise(void)
{
debug("Initialising CPed...\n");
CPedType::Initialise();
LoadFightData();
SetAnimOffsetForEnterOrExitVehicle();
debug("CPed ready\n");
}
void
CPed::SetAnimOffsetForEnterOrExitVehicle(void)
{
// FIX: If there were no translations on enter anims, there were overflows all over this function.
CAnimBlendHierarchy *enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_JACKED_LHS)->hierarchy;
CAnimBlendSequence *seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
if (!seq->HasTranslation())
vecPedDraggedOutCarAnimOffset = CVector(0.0f, 0.0f, 0.0f);
else {
KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
vecPedDraggedOutCarAnimOffset = lastFrame->translation;
}
}
enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_GETIN_LHS)->hierarchy;
seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
if (!seq->HasTranslation())
vecPedCarDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f);
else {
KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
vecPedCarDoorAnimOffset = lastFrame->translation;
}
}
enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_LHS)->hierarchy;
seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
if (!seq->HasTranslation())
vecPedCarDoorLoAnimOffset = CVector(0.0f, 0.0f, 0.0f);
else {
KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
vecPedCarDoorLoAnimOffset = lastFrame->translation;
}
}
enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_QJACKED)->hierarchy;
seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
if (!seq->HasTranslation())
vecPedQuickDraggedOutCarAnimOffset = CVector(0.0f, 0.0f, 0.0f);
else {
KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
vecPedQuickDraggedOutCarAnimOffset = lastFrame->translation;
}
}
enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_VAN_GETIN_L)->hierarchy;
seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
if (!seq->HasTranslation())
vecPedVanRearDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f);
else {
KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
vecPedVanRearDoorAnimOffset = lastFrame->translation;
}
}
enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_TRAIN_GETOUT)->hierarchy;
seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
if (!seq->HasTranslation())
vecPedTrainDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f);
else {
KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
vecPedTrainDoorAnimOffset = lastFrame->translation;
}
}
}
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); }
@ -7389,7 +7789,6 @@ STARTPATCHES
InjectHook(0x4D09B0, &CPed::SetFall, PATCH_JUMP);
InjectHook(0x4E6220, &CPed::SetAttack, PATCH_JUMP);
InjectHook(0x4E7530, &CPed::StartFightAttack, PATCH_JUMP);
InjectHook(0x4E9870, &CPed::LoadFightData, PATCH_JUMP);
InjectHook(0x4E8EC0, &CPed::FightStrike, PATCH_JUMP);
InjectHook(0x4CCE20, &CPed::GetLocalDirection, PATCH_JUMP);
InjectHook(0x4E8E20, &CPed::PlayHitSound, PATCH_JUMP);
@ -7431,4 +7830,14 @@ STARTPATCHES
InjectHook(0x4D1ED0, &CPed::Flee, PATCH_JUMP);
InjectHook(0x4E1CF0, &CPed::GetNearestDoor, PATCH_JUMP);
InjectHook(0x4DF420, &CPed::GetFormationPosition, PATCH_JUMP);
InjectHook(0x4E1F30, &CPed::GetNearestPassengerDoor, PATCH_JUMP);
InjectHook(0x4D0690, &CPed::Idle, PATCH_JUMP);
InjectHook(0x4DD720, &CPed::GetNextPointOnRoute, PATCH_JUMP);
InjectHook(0x4D7B50, &CPed::GetPedRadioCategory, PATCH_JUMP);
InjectHook(0x4CFA40, &CPed::GetWeaponSlot, PATCH_JUMP);
InjectHook(0x4E2220, &CPed::GoToNearestDoor, PATCH_JUMP);
InjectHook(0x4DD7B0, &CPed::HaveReachedNextPointOnRoute, PATCH_JUMP);
InjectHook(0x4D0D10, &CPed::InTheAir, PATCH_JUMP);
InjectHook(0x4C5270, &CPed::Initialise, PATCH_JUMP);
InjectHook(0x4D0E40, &CPed::SetLanding, PATCH_JUMP);
ENDPATCHES

View File

@ -29,6 +29,13 @@ enum
ENDFIGHT_FAST
};
enum PedRouteType
{
PEDROUTE_STOP_WHEN_DONE = 1,
PEDROUTE_GO_BACKWARD_WHEN_DONE,
PEDROUTE_GO_TO_START_WHEN_DONE
};
struct FightMove
{
AnimationId animId;
@ -335,9 +342,7 @@ public:
eObjective m_prevObjective;
CPed *m_pedInObjective;
CVehicle *m_carInObjective;
uint32 field_174;
uint32 field_178;
uint32 field_17C;
CVector m_nextRoutePointPos;
CPed *m_leader;
uint32 m_pedFormation;
uint32 m_fearFlags;
@ -375,10 +380,10 @@ public:
float m_fHealth;
float m_fArmour;
int16 m_routeLastPoint;
uint16 m_routePoints;
int16 m_routePos;
uint16 m_routeStartPoint;
int16 m_routePointsPassed;
int16 m_routeType;
int16 m_routeCurDir;
int16 m_routePointsBeingPassed;
uint16 field_2D2;
CVector2D m_moved;
float m_fRotationCur;
@ -567,7 +572,6 @@ public:
void SetEvasiveDive(CPhysical*, uint8);
void SetAttack(CEntity*);
void StartFightAttack(uint8);
void LoadFightData(void);
void SetWaitState(eWaitState, void*);
bool FightStrike(CVector&);
int GetLocalDirection(CVector2D&);
@ -605,11 +609,23 @@ public:
void FollowPath(void);
CVector GetFormationPosition(void);
void GetNearestDoor(CVehicle*, CVector&);
bool GetNearestPassengerDoor(CVehicle*, CVector&);
int GetNextPointOnRoute(void);
uint8 GetPedRadioCategory(uint32);
int GetWeaponSlot(eWeaponType);
void GoToNearestDoor(CVehicle*);
bool HaveReachedNextPointOnRoute(float a2);
void Idle(void);
void InTheAir(void);
void SetLanding(void);
// Static methods
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
static CVector GetPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatPosMult);
static CVector GetPositionToOpenCarDoor(CVehicle* veh, uint32 component);
static void Initialise(void);
static void SetAnimOffsetForEnterOrExitVehicle(void);
static void LoadFightData(void);
// Callbacks
static RwObject *SetPedAtomicVisibilityCB(RwObject *object, void *data);

6
src/peds/PedRoutes.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "common.h"
#include "patcher.h"
#include "main.h"
#include "PedRoutes.h"
WRAPPER int16 CRouteNode::GetRouteThisPointIsOn(int16) { EAXJMP(0x4EE7A0); }

7
src/peds/PedRoutes.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
class CRouteNode
{
public:
static int16 GetRouteThisPointIsOn(int16 point);
};

View File

@ -30,6 +30,7 @@ void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehicleP
void CVehicle::operator delete(void *p, size_t sz) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
void CVehicle::operator delete(void *p, int handle) { CPools::GetVehiclePool()->Delete((CVehicle*)p); }
WRAPPER bool CVehicle::ShufflePassengersToMakeSpace(void) { EAXJMP(0x5528A0); }
// or Weapon.cpp?
WRAPPER void FireOneInstantHitRound(CVector *shotSource, CVector *shotTarget, int32 damage) { EAXJMP(0x563B00); }

View File

@ -266,6 +266,7 @@ public:
void RemoveDriver(void);
void ProcessCarAlarm(void);
bool IsSphereTouchingVehicle(float sx, float sy, float sz, float radius);
bool ShufflePassengersToMakeSpace(void);
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }