mirror of
https://github.com/GTAmodding/re3.git
synced 2024-12-26 03:05:40 +00:00
Merge pull request #195 from erorcun/erorcun
AnimViewer messages, Particle fix, Peds
This commit is contained in:
commit
ed9ab6c55f
11 changed files with 595 additions and 15 deletions
|
@ -34,6 +34,8 @@
|
|||
#include "Timecycle.h"
|
||||
#include "RpAnimBlend.h"
|
||||
#include "Shadows.h"
|
||||
#include "Radar.h"
|
||||
#include "Hud.h"
|
||||
|
||||
int CAnimViewer::animTxdSlot = 0;
|
||||
CEntity *CAnimViewer::pTarget = nil;
|
||||
|
@ -70,6 +72,7 @@ CAnimViewer::Initialise(void) {
|
|||
}
|
||||
|
||||
gbModelViewer = true;
|
||||
CHud::m_Wants_To_Draw_Hud = false;
|
||||
|
||||
ThePaths.Init();
|
||||
ThePaths.AllocatePathFindInfoMem(4500);
|
||||
|
@ -90,6 +93,8 @@ CAnimViewer::Initialise(void) {
|
|||
CStreaming::RequestSpecialModel(MI_PLAYER, "player", STREAMFLAGS_DONT_REMOVE);
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
CRenderer::Init();
|
||||
CRadar::Initialise();
|
||||
CRadar::LoadTextures();
|
||||
CVehicleModelInfo::LoadVehicleColours();
|
||||
CAnimManager::LoadAnimFiles();
|
||||
CWorld::PlayerInFocus = 0;
|
||||
|
@ -297,10 +302,15 @@ CAnimViewer::Update(void)
|
|||
|
||||
if (pad->NewState.LeftShoulder1 && !pad->OldState.LeftShoulder1) {
|
||||
nextModelId = LastPedModelId(modelId);
|
||||
AsciiToUnicode("Switched to peds", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
} else {
|
||||
// Start in mobile
|
||||
if (pad->NewState.Square && !pad->OldState.Square)
|
||||
if (pad->NewState.Square && !pad->OldState.Square) {
|
||||
CVehicleModelInfo::LoadVehicleColours();
|
||||
AsciiToUnicode("Carcols.dat reloaded", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -309,12 +319,18 @@ CAnimViewer::Update(void)
|
|||
// Triangle in mobile
|
||||
if (pad->NewState.Square && !pad->OldState.Square) {
|
||||
reloadIFP = 1;
|
||||
AsciiToUnicode("IFP reloaded", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->NewState.Cross && !pad->OldState.Cross) {
|
||||
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
|
||||
AsciiToUnicode("Animation restarted", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->NewState.Circle && !pad->OldState.Circle) {
|
||||
PlayAnimation(pTarget->GetClump(), animGroup, ANIM_IDLE_STANCE);
|
||||
AsciiToUnicode("Idle animation playing", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->NewState.DPadUp && pad->OldState.DPadUp == 0) {
|
||||
animId--;
|
||||
|
@ -323,19 +339,33 @@ CAnimViewer::Update(void)
|
|||
}
|
||||
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
|
||||
|
||||
sprintf(gString, "Current anim: %d", animId);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->NewState.DPadDown && !pad->OldState.DPadDown) {
|
||||
animId = (animId == (NUM_ANIMS - 1) ? 0 : animId + 1);
|
||||
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
|
||||
|
||||
sprintf(gString, "Current anim: %d", animId);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else {
|
||||
if (pad->NewState.Start && !pad->OldState.Start) {
|
||||
|
||||
} else {
|
||||
if (pad->NewState.LeftShoulder1 && !pad->OldState.LeftShoulder1) {
|
||||
nextModelId = LastVehicleModelId(modelId);
|
||||
AsciiToUnicode("Switched to vehicles", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
} else {
|
||||
// if (CPad::GetPad(1)->NewState.LeftShoulder2)
|
||||
// CPedModelInfo::AnimatePedColModelSkinned(CModelInfo::ms_modelInfoPtrs[(pTarget + 96)], pTarget->GetClump()));
|
||||
// Originally it was GetPad(1)->LeftShoulder2
|
||||
if (pad->NewState.Triangle) {
|
||||
CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(pTarget->m_modelIndex))->GetHitColModel(), RpClumpGetFrame(pTarget->GetClump()));
|
||||
AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString);
|
||||
CMessages::AddMessage(gUString, 100, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -344,8 +374,17 @@ CAnimViewer::Update(void)
|
|||
|
||||
if (pad->NewState.DPadLeft && pad->OldState.DPadLeft == 0) {
|
||||
nextModelId = FindMeAModelID(modelId, -1);
|
||||
|
||||
sprintf(gString, "Current model ID: %d", nextModelId);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->NewState.DPadRight && pad->OldState.DPadRight == 0) {
|
||||
nextModelId = FindMeAModelID(modelId, 1);
|
||||
|
||||
sprintf(gString, "Current model ID: %d", nextModelId);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
}
|
||||
// There were extra codes here to let us change model id by 50, but xbox CPad struct is different, so I couldn't port.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "Stats.h"
|
||||
|
||||
int32 &CStats::DaysPassed = *(int32*)0x8F2BB8;
|
||||
int32 &CStats::HeadShots = *(int32*)0x8F647C;
|
||||
int32 &CStats::HeadsPopped = *(int32*)0x8F647C;
|
||||
bool& CStats::CommercialPassed = *(bool*)0x8F4334;
|
||||
bool& CStats::IndustrialPassed = *(bool*)0x8E2A68;
|
||||
int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
|
||||
|
|
|
@ -4,7 +4,7 @@ class CStats
|
|||
{
|
||||
public:
|
||||
static int32 &DaysPassed;
|
||||
static int32 &HeadShots;
|
||||
static int32 &HeadsPopped;
|
||||
static bool& CommercialPassed;
|
||||
static bool& IndustrialPassed;
|
||||
static int32 &NumberKillFrenziesPassed;
|
||||
|
|
|
@ -297,7 +297,11 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
|
|||
if (((CPed*)e)->UseGroundColModel())
|
||||
colmodel = &CTempColModels::ms_colModelPedGroundHit;
|
||||
else
|
||||
#ifdef ANIMATE_PED_COL_MODEL
|
||||
colmodel = CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()))->GetHitColModel(), RpClumpGetFrame(e->GetClump()));
|
||||
#else
|
||||
colmodel = ((CPedModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()))->GetHitColModel();
|
||||
#endif
|
||||
}else
|
||||
colmodel = nil;
|
||||
}else if(e->bUsesCollision)
|
||||
|
|
|
@ -130,3 +130,4 @@ enum Config {
|
|||
#define ASPECT_RATIO_SCALE
|
||||
#define USE_DEBUG_SCRIPT_LOADER
|
||||
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
|
||||
#define ANIMATE_PED_COL_MODEL
|
||||
|
|
|
@ -121,9 +121,12 @@ TheModelViewer(void)
|
|||
CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
|
||||
255);
|
||||
|
||||
CSprite2d::InitPerFrame();
|
||||
CFont::InitPerFrame();
|
||||
DefinedState();
|
||||
CVisibilityPlugins::InitAlphaEntityList();
|
||||
CAnimViewer::Render();
|
||||
Render2dStuff();
|
||||
DoRWStuffEndOfFrame();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -189,6 +189,45 @@ CPedModelInfo::CreateHitColModel(void)
|
|||
m_hitColModel = colmodel;
|
||||
}
|
||||
|
||||
CColModel*
|
||||
CPedModelInfo::AnimatePedColModel(CColModel* colmodel, RwFrame* frame)
|
||||
{
|
||||
RwObjectNameAssociation nameAssoc;
|
||||
RwObjectIdAssociation idAssoc;
|
||||
RwMatrix* mat = RwMatrixCreate();
|
||||
CColSphere* spheres = colmodel->spheres;
|
||||
|
||||
for (int i = 0; i < NUMPEDINFONODES; i++) {
|
||||
RwFrame* f = nil;
|
||||
if (m_pColNodeInfos[i].name) {
|
||||
nameAssoc.name = m_pColNodeInfos[i].name;
|
||||
nameAssoc.frame = nil;
|
||||
RwFrameForAllChildren(frame, FindFrameFromNameCB, &nameAssoc);
|
||||
f = nameAssoc.frame;
|
||||
}
|
||||
else {
|
||||
idAssoc.id = m_pColNodeInfos[i].pedNode;
|
||||
idAssoc.frame = nil;
|
||||
RwFrameForAllChildren(frame, FindFrameFromIdCB, &idAssoc);
|
||||
f = idAssoc.frame;
|
||||
}
|
||||
if (f) {
|
||||
RwMatrixCopy(mat, RwFrameGetMatrix(f));
|
||||
|
||||
for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) {
|
||||
RwMatrixTransform(mat, &f->modelling, rwCOMBINEPOSTCONCAT);
|
||||
if (RwFrameGetParent(f) == frame)
|
||||
break;
|
||||
}
|
||||
|
||||
spheres[i].center.x = mat->pos.x + m_pColNodeInfos[i].x;
|
||||
spheres[i].center.y = mat->pos.y + 0.0f;
|
||||
spheres[i].center.z = mat->pos.z + m_pColNodeInfos[i].z;
|
||||
}
|
||||
}
|
||||
|
||||
return colmodel;
|
||||
}
|
||||
|
||||
class CPedModelInfo_ : public CPedModelInfo
|
||||
{
|
||||
|
|
|
@ -39,5 +39,6 @@ public:
|
|||
void SetLowDetailClump(RpClump*);
|
||||
void CreateHitColModel(void);
|
||||
CColModel *GetHitColModel(void) { return m_hitColModel; }
|
||||
static CColModel *AnimatePedColModel(CColModel* colmodel, RwFrame* frame);
|
||||
};
|
||||
static_assert(sizeof(CPedModelInfo) == 0x54, "CPedModelInfo: error");
|
||||
|
|
|
@ -442,13 +442,13 @@ void CParticleObject::UpdateClose(void)
|
|||
{
|
||||
this->m_nFrameCounter = 0;
|
||||
|
||||
int32 randVal; // BUG: unitialised can be used ??!!
|
||||
int32 randVal;
|
||||
if ( this->m_nCreationChance != 0 )
|
||||
randVal = CGeneral::GetRandomNumber() % this->m_nCreationChance;
|
||||
|
||||
if ( randVal != 0 && this->m_nCreationChance > 0
|
||||
|| randVal == 0 && (this->m_nCreationChance & 128) != 0
|
||||
|| this->m_nCreationChance == 0 )
|
||||
if ( this->m_nCreationChance == 0
|
||||
|| randVal == 0 && this->m_nCreationChance < 0
|
||||
|| randVal != 0 && this->m_nCreationChance > 0)
|
||||
{
|
||||
switch ( this->m_Type )
|
||||
{
|
||||
|
|
496
src/peds/Ped.cpp
496
src/peds/Ped.cpp
|
@ -39,7 +39,6 @@
|
|||
#include "Font.h"
|
||||
#include "Text.h"
|
||||
|
||||
WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); }
|
||||
WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); }
|
||||
WRAPPER void CPed::SetPedPositionInCar(void) { EAXJMP(0x4D4970); }
|
||||
WRAPPER void CPed::ProcessControl(void) { EAXJMP(0x4C8910); }
|
||||
|
@ -782,7 +781,7 @@ CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
|
|||
);
|
||||
|
||||
if (!CPed::IsPlayer() || evenOnPlayer) {
|
||||
++CStats::HeadShots;
|
||||
++CStats::HeadsPopped;
|
||||
|
||||
// BUG: This condition will always return true.
|
||||
if (m_nPedState != PED_PASSENGER || m_nPedState != PED_TAXI_PASSENGER) {
|
||||
|
@ -4367,7 +4366,7 @@ CPed::SetAttack(CEntity* victim)
|
|||
bIsAttacking = false;
|
||||
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, curWeapon->m_AnimToPlay, 8.0f);
|
||||
animAssoc->SetRun();
|
||||
if (animAssoc->currentTime != animAssoc->hierarchy->totalLength)
|
||||
if (animAssoc->currentTime == animAssoc->hierarchy->totalLength)
|
||||
animAssoc->SetCurrentTime(0.0f);
|
||||
|
||||
animAssoc->SetFinishCallback(FinishedAttackCB, this);
|
||||
|
@ -4668,12 +4667,19 @@ CPed::FightStrike(CVector &touchedNodePos)
|
|||
|
||||
// He can beat us
|
||||
if (sq(maxDistanceToBeBeaten) > potentialAttackDistance.MagnitudeSqr()) {
|
||||
ourCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->GetHitColModel();
|
||||
|
||||
if (nearPed->m_nPedState == PED_FALL
|
||||
|| nearPed->m_nPedState == PED_DEAD || nearPed->m_nPedState == PED_DIE
|
||||
|| !nearPed->IsPedHeadAbovePos(-0.3f)) {
|
||||
ourCol = &CTempColModels::ms_colModelPedGroundHit;
|
||||
} else {
|
||||
#ifdef ANIMATE_PED_COL_MODEL
|
||||
ourCol = CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->GetHitColModel(), RpClumpGetFrame(GetClump()));
|
||||
#else
|
||||
ourCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->GetHitColModel();
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < ourCol->numSpheres; j++) {
|
||||
attackDistance = nearPed->GetPosition() + ourCol->spheres[j].center;
|
||||
attackDistance -= touchedNodePos;
|
||||
|
@ -7723,6 +7729,484 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPed::InvestigateEvent(void)
|
||||
{
|
||||
CAnimBlendAssociation *animAssoc;
|
||||
AnimationId animToPlay;
|
||||
AssocGroupId animGroup;
|
||||
|
||||
if (m_nWaitState == WAITSTATE_TURN180)
|
||||
return;
|
||||
|
||||
if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
|
||||
|
||||
if (m_standardTimer) {
|
||||
if (m_eventType < EVENT_ASSAULT_NASTYWEAPON)
|
||||
SetWaitState(WAITSTATE_TURN180, nil);
|
||||
|
||||
m_standardTimer = 0;
|
||||
} else {
|
||||
ClearInvestigateEvent();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CVector2D vecDist = m_eventOrThreat - GetPosition();
|
||||
float distSqr = vecDist.MagnitudeSqr();
|
||||
if (sq(m_distanceToCountSeekDone) >= distSqr) {
|
||||
|
||||
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(vecDist.x, vecDist.y, 0.0f, 0.0f);
|
||||
SetMoveState(PEDMOVE_STILL);
|
||||
|
||||
switch (m_eventType) {
|
||||
case EVENT_DEAD_PED:
|
||||
case EVENT_HIT_AND_RUN:
|
||||
case EVENT_HIT_AND_RUN_COP:
|
||||
|
||||
if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
|
||||
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
|
||||
|
||||
if (animAssoc) {
|
||||
animAssoc->blendDelta = -8.0f;
|
||||
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||
if (m_pEventEntity)
|
||||
SetLookFlag(m_pEventEntity, 1);
|
||||
|
||||
SetLookTimer(CGeneral::GetRandomNumberInRange(1500, 4000));
|
||||
|
||||
} else if (CGeneral::GetRandomNumber() & 3) {
|
||||
ClearLookFlag();
|
||||
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ROAD_CROSS, 4.0f);
|
||||
|
||||
SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
|
||||
Say(SOUND_PED_CHAT_EVENT);
|
||||
|
||||
} else {
|
||||
ClearInvestigateEvent();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_FIRE:
|
||||
case EVENT_EXPLOSION:
|
||||
|
||||
if (m_ped_flagD1 && CTimer::GetTimeInMilliseconds() > m_lookTimer) {
|
||||
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CAM);
|
||||
if (!animAssoc)
|
||||
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
|
||||
|
||||
if (animAssoc && animAssoc->animId == ANIM_IDLE_CAM) {
|
||||
CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 14.0f);
|
||||
SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
|
||||
|
||||
} else if (CGeneral::GetRandomNumber() & 3) {
|
||||
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_CAM, 4.0f);
|
||||
SetLookTimer(CGeneral::GetRandomNumberInRange(2500, 5000));
|
||||
Say(SOUND_PED_CHAT_EVENT);
|
||||
|
||||
} else {
|
||||
m_standardTimer = 0;
|
||||
}
|
||||
|
||||
} else if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
|
||||
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
|
||||
if (!animAssoc)
|
||||
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
|
||||
|
||||
if (!animAssoc)
|
||||
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
|
||||
|
||||
if (animAssoc && animAssoc->animId == ANIM_IDLE_STANCE) {
|
||||
if (CGeneral::GetRandomNumber() & 1)
|
||||
animToPlay = ANIM_IDLE_HBHB;
|
||||
else
|
||||
animToPlay = ANIM_XPRESS_SCRATCH;
|
||||
|
||||
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
|
||||
SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
|
||||
|
||||
} else if (animAssoc && animAssoc->animId == ANIM_IDLE_HBHB) {
|
||||
animAssoc->blendDelta = -8.0f;
|
||||
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||
if (CGeneral::GetRandomNumber() & 1) {
|
||||
animToPlay = ANIM_IDLE_STANCE;
|
||||
animGroup = m_animGroup;
|
||||
} else {
|
||||
animToPlay = ANIM_XPRESS_SCRATCH;
|
||||
animGroup = ASSOCGRP_STD;
|
||||
}
|
||||
|
||||
CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f);
|
||||
SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
|
||||
|
||||
} else {
|
||||
if (CGeneral::GetRandomNumber() & 1) {
|
||||
animToPlay = ANIM_IDLE_STANCE;
|
||||
animGroup = m_animGroup;
|
||||
} else {
|
||||
animToPlay = ANIM_IDLE_HBHB;
|
||||
animGroup = ASSOCGRP_STD;
|
||||
}
|
||||
|
||||
CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f);
|
||||
SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
|
||||
}
|
||||
Say(SOUND_PED_CHAT_EVENT);
|
||||
}
|
||||
break;
|
||||
case EVENT_ASSAULT_NASTYWEAPON_POLICE:
|
||||
case EVENT_ATM:
|
||||
|
||||
m_fRotationDest = m_fAngleToEvent;
|
||||
if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
|
||||
|
||||
if (m_lookTimer) {
|
||||
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
|
||||
|
||||
if (animAssoc) {
|
||||
animAssoc->blendDelta = -8.0f;
|
||||
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||
if (m_eventType == EVENT_ASSAULT_NASTYWEAPON_POLICE)
|
||||
animToPlay = ANIM_IDLE_CHAT;
|
||||
else
|
||||
animToPlay = ANIM_XPRESS_SCRATCH;
|
||||
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay,4.0f);
|
||||
SetLookTimer(CGeneral::GetRandomNumberInRange(2000, 5000));
|
||||
|
||||
} else {
|
||||
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
|
||||
if (animAssoc) {
|
||||
animAssoc->blendDelta = -8.0f;
|
||||
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||
ClearInvestigateEvent();
|
||||
} else {
|
||||
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
|
||||
if (animAssoc) {
|
||||
animAssoc->blendDelta = -8.0f;
|
||||
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||
}
|
||||
ClearInvestigateEvent();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ROAD_CROSS, 4.0f);
|
||||
SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
m_vecSeekPos.x = m_eventOrThreat.x;
|
||||
m_vecSeekPos.y = m_eventOrThreat.y;
|
||||
m_vecSeekPos.z = GetPosition().z;
|
||||
Seek();
|
||||
|
||||
if (m_eventType < EVENT_ASSAULT_NASTYWEAPON_POLICE) {
|
||||
if (sq(5.0f + m_distanceToCountSeekDone) < distSqr) {
|
||||
SetMoveState(PEDMOVE_RUN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (m_eventType <= EVENT_EXPLOSION || m_eventType >= EVENT_ATM) {
|
||||
SetMoveState(PEDMOVE_WALK);
|
||||
return;
|
||||
}
|
||||
if (distSqr > 1.44f) {
|
||||
SetMoveState(PEDMOVE_WALK);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_numNearPeds; i++) {
|
||||
if ((m_eventOrThreat - m_nearPeds[i]->GetPosition()).MagnitudeSqr() < 0.16f) {
|
||||
SetMoveState(PEDMOVE_STILL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SetMoveState(PEDMOVE_WALK);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CPed::IsPedDoingDriveByShooting(void)
|
||||
{
|
||||
if (this == FindPlayerPed() && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) {
|
||||
|
||||
if (TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CPed::IsPedShootable(void)
|
||||
{
|
||||
return m_nPedState <= PED_STATES_NO_ST;
|
||||
}
|
||||
|
||||
bool
|
||||
CPed::IsRoomToBeCarJacked(void)
|
||||
{
|
||||
if (!m_pMyVehicle)
|
||||
return false;
|
||||
|
||||
CVector2D offset;
|
||||
if (m_pMyVehicle->bLowVehicle || m_nPedType == PEDTYPE_COP) {
|
||||
offset = vecPedDraggedOutCarAnimOffset;
|
||||
} else {
|
||||
offset = vecPedQuickDraggedOutCarAnimOffset;
|
||||
}
|
||||
|
||||
CVector doorPos(offset.x, offset.y, 0.0f);
|
||||
if (m_pMyVehicle->IsRoomForPedToLeaveCar(CAR_DOOR_LF, &doorPos)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CPed::KillPedWithCar(CVehicle* car, float impulse)
|
||||
{
|
||||
CVehicleModelInfo* vehModel;
|
||||
CColModel* vehColModel;
|
||||
uint8 damageDir;
|
||||
PedNode nodeToDamage;
|
||||
eWeaponType killMethod;
|
||||
|
||||
if (m_nPedState == PED_FALL || m_nPedState == PED_DIE) {
|
||||
if (!this->m_pCollidingEntity || car->m_status == STATUS_PLAYER)
|
||||
this->m_pCollidingEntity = car;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_nPedState == PED_DEAD)
|
||||
return;
|
||||
|
||||
if (m_pCurSurface) {
|
||||
if (m_pCurSurface->IsVehicle() && (((CVehicle*)m_pCurSurface)->m_vehType == VEHICLE_TYPE_BOAT || IsPlayer()))
|
||||
return;
|
||||
}
|
||||
CVector distVec = GetPosition() - car->GetPosition();
|
||||
|
||||
if ((impulse > 12.0f || car->m_modelIndex == MI_TRAIN) && !IsPlayer()) {
|
||||
nodeToDamage = PED_TORSO;
|
||||
killMethod = WEAPONTYPE_RAMMEDBYCAR;
|
||||
uint8 randVal = CGeneral::GetRandomNumber() & 3;
|
||||
|
||||
if (car == FindPlayerVehicle()) {
|
||||
float carSpeed = car->m_vecMoveSpeed.Magnitude();
|
||||
uint8 shakeFreq;
|
||||
if (100.0f * carSpeed * 2000.0f / car->m_fMass + 80.0f <= 250.0f) {
|
||||
shakeFreq = 100.0f * carSpeed * 2000.0f / car->m_fMass + 80.0f;
|
||||
} else {
|
||||
shakeFreq = 250.0f;
|
||||
}
|
||||
CPad::GetPad(0)->StartShake(40000 / shakeFreq, shakeFreq);
|
||||
}
|
||||
bIsStanding = false;
|
||||
damageDir = CPed::GetLocalDirection(-m_vecMoveSpeed);
|
||||
vehModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(car->m_modelIndex);
|
||||
vehColModel = vehModel->GetColModel();
|
||||
float carRightAndDistDotProd = DotProduct(distVec, car->GetRight());
|
||||
|
||||
if (car->m_modelIndex == MI_TRAIN) {
|
||||
killMethod = WEAPONTYPE_RUNOVERBYCAR;
|
||||
nodeToDamage = PED_HEAD;
|
||||
m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
|
||||
m_vecMoveSpeed.z = 0.0;
|
||||
if (damageDir == 1 || damageDir == 3)
|
||||
damageDir = 2;
|
||||
if (CGame::nastyGame)
|
||||
DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLATTER, 0.0f);
|
||||
|
||||
// Car doesn't look to us
|
||||
} else if (DotProduct(car->m_vecMoveSpeed, car->GetForward()) >= 0.0f){
|
||||
|
||||
if (0.99f * vehColModel->boundingBox.max.x < Abs(carRightAndDistDotProd)) {
|
||||
|
||||
// We're at the right of the car
|
||||
if (carRightAndDistDotProd <= 0.0f)
|
||||
nodeToDamage = PED_UPPERARML;
|
||||
else
|
||||
nodeToDamage = PED_UPPERARMR;
|
||||
|
||||
if (fabs(DotProduct(distVec, car->GetForward())) < 0.85f * vehColModel->boundingBox.max.y) {
|
||||
killMethod = WEAPONTYPE_RUNOVERBYCAR;
|
||||
m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
|
||||
m_vecMoveSpeed.z = 0.0;
|
||||
if (damageDir == 1 || damageDir == 3)
|
||||
damageDir = 2;
|
||||
if (CGame::nastyGame)
|
||||
DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLATTER, 0.0f);
|
||||
|
||||
}
|
||||
} else {
|
||||
float carFrontAndDistDotProd = DotProduct(distVec, car->GetForward());
|
||||
|
||||
// carFrontAndDistDotProd <= 0.0 car looks to us
|
||||
if ((carFrontAndDistDotProd <= 0.1 || randVal == 1) && randVal != 0) {
|
||||
killMethod = WEAPONTYPE_RUNOVERBYCAR;
|
||||
nodeToDamage = PED_HEAD;
|
||||
m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
|
||||
m_vecMoveSpeed.z = 0.0;
|
||||
if (damageDir == 1 || damageDir == 3)
|
||||
damageDir = 2;
|
||||
|
||||
if (CGame::nastyGame)
|
||||
DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLATTER, 0.0f);
|
||||
|
||||
} else {
|
||||
nodeToDamage = PED_MID;
|
||||
float vehColMaxY = vehColModel->boundingBox.max.y;
|
||||
float vehColMinY = vehColModel->boundingBox.min.y;
|
||||
float vehColMaxZ = vehColModel->boundingBox.max.z;
|
||||
float carFrontZ = car->GetForward().z;
|
||||
|
||||
// Col. Z of where?
|
||||
float carColZ;
|
||||
|
||||
// TODO: Figure out what these codes do
|
||||
float unk1, unk2;
|
||||
|
||||
if (carFrontZ < -0.2f) {
|
||||
carColZ = (car->GetMatrix() * CVector(0.0f, vehColMinY, vehColMaxZ)).z;
|
||||
unk1 = vehColMaxY - vehColMinY;
|
||||
|
||||
} else if (carFrontZ > 0.1f) {
|
||||
carColZ = (car->GetMatrix() * CVector(0.0f, vehColMaxY, vehColMaxZ)).z;
|
||||
float colZDist = carColZ - GetPosition().z;
|
||||
if (colZDist > 0.0f) {
|
||||
GetPosition().z += 0.5f * colZDist;
|
||||
carColZ += colZDist * 0.25f;
|
||||
}
|
||||
unk1 = vehColMaxY;
|
||||
|
||||
} else {
|
||||
carColZ = (car->GetMatrix() * CVector(0.0f, vehColMaxY, vehColMaxZ)).z;
|
||||
unk1 = vehColMaxY;
|
||||
}
|
||||
|
||||
unk2 = (carColZ - GetPosition().z) / (unk1 / car->m_vecMoveSpeed.Magnitude());
|
||||
float moveForce = ((CGeneral::GetRandomNumber() % 256) * 0.002 + 1.5) * unk2;
|
||||
|
||||
// After this point, distVec isn't distVec anymore.
|
||||
distVec = car->m_vecMoveSpeed;
|
||||
distVec.Normalise();
|
||||
distVec *= 0.2 * moveForce;
|
||||
|
||||
if (damageDir != 1 && damageDir != 3)
|
||||
distVec.z += moveForce;
|
||||
else
|
||||
distVec.z += 1.5f * moveForce;
|
||||
|
||||
m_vecMoveSpeed = distVec;
|
||||
damageDir += 2;
|
||||
if (damageDir > 3)
|
||||
damageDir = damageDir - 4;
|
||||
|
||||
if (car->m_vehType == VEHICLE_TYPE_CAR) {
|
||||
CObject *bonnet = ((CAutomobile*)car)->RemoveBonnetInPedCollision();
|
||||
|
||||
if (bonnet) {
|
||||
if (rand() & 1) {
|
||||
bonnet->m_vecMoveSpeed += Multiply3x3(car->GetMatrix(), CVector(0.1f, 0.0f, 0.5f));
|
||||
} else {
|
||||
bonnet->m_vecMoveSpeed += Multiply3x3(car->GetMatrix(), CVector(-0.1f, 0.0f, 0.5f));
|
||||
}
|
||||
CVector forceDir = car->GetUp() * 10.0f;
|
||||
bonnet->ApplyTurnForce(forceDir, car->GetForward());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (car->pDriver) {
|
||||
CEventList::RegisterEvent((m_nPedType == PEDTYPE_COP ? EVENT_HIT_AND_RUN_COP : EVENT_HIT_AND_RUN), EVENT_ENTITY_PED, this, car->pDriver, 1000);
|
||||
}
|
||||
|
||||
ePedPieceTypes pieceToDamage;
|
||||
switch (nodeToDamage) {
|
||||
case PED_HEAD:
|
||||
pieceToDamage = PEDPIECE_HEAD;
|
||||
break;
|
||||
case PED_UPPERARML:
|
||||
pieceToDamage = PEDPIECE_LEFTARM;
|
||||
break;
|
||||
case PED_UPPERARMR:
|
||||
pieceToDamage = PEDPIECE_RIGHTARM;
|
||||
break;
|
||||
default:
|
||||
pieceToDamage = PEDPIECE_MID;
|
||||
break;
|
||||
}
|
||||
CPed::InflictDamage(car, killMethod, 1000.0f, pieceToDamage, damageDir);
|
||||
|
||||
if ((m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
|
||||
&& bIsPedDieAnimPlaying
|
||||
&& !m_pCollidingEntity) {
|
||||
m_pCollidingEntity = car;
|
||||
}
|
||||
if (nodeToDamage == PED_MID)
|
||||
m_ped_flagH1 = true;
|
||||
else
|
||||
m_ped_flagH1 = false;
|
||||
|
||||
distVec.Normalise();
|
||||
car->ApplyMoveForce(distVec * -100.0f);
|
||||
|
||||
} else if (m_vecDamageNormal.z < -0.8f && impulse > 3.0f
|
||||
|| impulse > 6.0f && (!IsPlayer() || impulse > 10.0f)) {
|
||||
|
||||
bIsStanding = false;
|
||||
uint8 fallDirection = GetLocalDirection(-car->m_vecMoveSpeed);
|
||||
float damage;
|
||||
if (IsPlayer() && car->m_modelIndex == MI_TRAIN)
|
||||
damage = 150.0f;
|
||||
else
|
||||
damage = 30.0f;
|
||||
|
||||
CPed::InflictDamage(car, WEAPONTYPE_RAMMEDBYCAR, damage, PEDPIECE_TORSO, fallDirection);
|
||||
CPed::SetFall(1000, (AnimationId)(fallDirection + 25), true);
|
||||
|
||||
// float ok
|
||||
if ((m_nPedState == PED_FALL || m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
|
||||
&& !m_pCollidingEntity
|
||||
&& (!IsPlayer() || m_ped_flagD2 || car->m_modelIndex == MI_TRAIN || m_vecDamageNormal.z < -0.8f)) {
|
||||
|
||||
m_pCollidingEntity = car;
|
||||
}
|
||||
|
||||
m_ped_flagH1 = false;
|
||||
if (car->m_modelIndex != MI_TRAIN && !m_ped_flagD2) {
|
||||
m_vecMoveSpeed = car->m_vecMoveSpeed * 0.75f;
|
||||
}
|
||||
m_vecMoveSpeed.z = 0.0f;
|
||||
distVec.Normalise();
|
||||
car->ApplyMoveForce(distVec * -60.0f);
|
||||
}
|
||||
|
||||
Say(SOUND_PED_DEFEND);
|
||||
#ifdef FIX_BUGS
|
||||
// Killing gang members with car wasn't triggering a fight, until now... Taken from VC.
|
||||
if (IsGangMember()) {
|
||||
CPed *driver = car->pDriver;
|
||||
if (driver && driver->IsPlayer()) {
|
||||
RegisterThreatWithGangPeds(driver);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CPed::Look(void)
|
||||
{
|
||||
// UNUSED: This is a perfectly empty function.
|
||||
}
|
||||
|
||||
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); }
|
||||
|
@ -7901,4 +8385,8 @@ STARTPATCHES
|
|||
InjectHook(0x4D0D10, &CPed::InTheAir, PATCH_JUMP);
|
||||
InjectHook(0x4C5270, &CPed::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x4D0E40, &CPed::SetLanding, PATCH_JUMP);
|
||||
InjectHook(0x4E9B50, &CPed::InvestigateEvent, PATCH_JUMP);
|
||||
InjectHook(0x564BB0, &CPed::IsPedDoingDriveByShooting, PATCH_JUMP);
|
||||
InjectHook(0x4E4D90, &CPed::IsRoomToBeCarJacked, PATCH_JUMP);
|
||||
InjectHook(0x4EC430, &CPed::KillPedWithCar, PATCH_JUMP);
|
||||
ENDPATCHES
|
|
@ -618,6 +618,9 @@ public:
|
|||
void Idle(void);
|
||||
void InTheAir(void);
|
||||
void SetLanding(void);
|
||||
void InvestigateEvent(void);
|
||||
bool IsPedDoingDriveByShooting(void);
|
||||
bool IsRoomToBeCarJacked(void);
|
||||
|
||||
// Static methods
|
||||
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
|
||||
|
@ -681,6 +684,8 @@ public:
|
|||
void EnterTrain(void);
|
||||
void ExitTrain(void);
|
||||
void Fall(void);
|
||||
bool IsPedShootable(void);
|
||||
void Look(void);
|
||||
|
||||
bool HasWeapon(uint8 weaponType) { return m_weapons[weaponType].m_eWeaponType == weaponType; }
|
||||
CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; }
|
||||
|
|
Loading…
Reference in a new issue