From e9cafe340a16c489c5f6874066b9836d70bd0091 Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 23 Jul 2019 16:39:30 +0200 Subject: [PATCH] bit more CAutomobile --- src/animation/AnimBlendAssociation.h | 2 + src/control/Population.h | 1 + src/core/re3.cpp | 12 ++ src/entities/Entity.h | 9 ++ src/vehicles/Automobile.cpp | 195 +++++++++++++++++++++++++-- src/vehicles/Automobile.h | 6 +- src/vehicles/Vehicle.h | 4 +- src/weapons/Weapon.cpp | 2 + src/weapons/Weapon.h | 6 +- 9 files changed, 219 insertions(+), 18 deletions(-) diff --git a/src/animation/AnimBlendAssociation.h b/src/animation/AnimBlendAssociation.h index a7e127f7..cd61636f 100644 --- a/src/animation/AnimBlendAssociation.h +++ b/src/animation/AnimBlendAssociation.h @@ -77,6 +77,8 @@ public: void UpdateTime(float timeDelta, float relSpeed); bool UpdateBlend(float timeDelta); + void SetRun(void) { flags |= ASSOC_RUNNING; } + inline float GetTimeLeft() { return hierarchy->totalLength - currentTime; } static CAnimBlendAssociation *FromLink(CAnimBlendLink *l) { diff --git a/src/control/Population.h b/src/control/Population.h index cfa9508f..e067562a 100644 --- a/src/control/Population.h +++ b/src/control/Population.h @@ -2,6 +2,7 @@ class CPed; class CVehicle; +enum eLevelName; struct PedGroup { diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 67b9095e..851baeaf 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -158,6 +158,17 @@ ToggleComedy(void) veh->bComedyControls = !veh->bComedyControls; } +static void +PlaceOnRoad(void) +{ + CVehicle *veh = FindPlayerVehicle(); + if(veh == nil) + return; + + if(veh->IsCar()) + ((CAutomobile*)veh)->PlaceOnRoadProperly(); +} + static const char *carnames[] = { "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "patriot", "firetruk", "trash", "stretch", "manana", "infernus", "blista", "pony", "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "kuruma", "bobcat", "mrwhoop", "bfinject", "corpse", "police", "enforcer", @@ -241,6 +252,7 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Debug", "Fix Car", FixCar); DebugMenuAddCmd("Debug", "Toggle Comedy Controls", ToggleComedy); + DebugMenuAddCmd("Debug", "Place Car on Road", PlaceOnRoad); DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil); DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil); diff --git a/src/entities/Entity.h b/src/entities/Entity.h index ff43903f..e975fb13 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -117,6 +117,15 @@ public: bool IsObject(void) { return m_type == ENTITY_TYPE_OBJECT; } bool IsDummy(void) { return m_type == ENTITY_TYPE_DUMMY; } + RpAtomic *GetAtomic(void) { + assert(RwObjectGetType(m_rwObject) == rpATOMIC); + return (RpAtomic*)m_rwObject; + } + RpClump *GetClump(void) { + assert(RwObjectGetType(m_rwObject) == rpCLUMP); + return (RpClump*)m_rwObject; + } + void GetBoundCentre(CVector &out); CVector GetBoundCentre(void) { CVector v; GetBoundCentre(v); return v; } float GetBoundRadius(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; } diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 46116536..fb42e6e6 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -23,6 +23,8 @@ #include "CarAI.h" #include "Garages.h" #include "PathFind.h" +#include "AnimManager.h" +#include "RpAnimBlend.h" #include "Ped.h" #include "PlayerPed.h" #include "Object.h" @@ -161,8 +163,8 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) m_fCarGunLR = 0.0f; m_fCarGunUD = 0.05f; m_fWindScreenRotation = 0.0f; - m_weaponThingA = 0.0f; - m_weaponThingB = m_weaponThingA; + m_weaponDoorTimerLeft = 0.0f; + m_weaponDoorTimerRight = m_weaponDoorTimerLeft; if(GetModelIndex() == MI_DODO){ RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0); @@ -193,7 +195,6 @@ CAutomobile::SetModelIndex(uint32 id) CVector vecDAMAGE_ENGINE_POS_SMALL(-0.1f, -0.1f, 0.0f); CVector vecDAMAGE_ENGINE_POS_BIG(-0.5f, -0.3f, 0.0f); -//WRAPPER void CAutomobile::ProcessControl(void) { EAXJMP(0x531470); } void CAutomobile::ProcessControl(void) { @@ -1178,6 +1179,10 @@ CAutomobile::ProcessControl(void) m_vecTurnSpeed.z = 0.0f; } } + +// TEMP +if(pDriver) + pDriver->m_fHealth = 100.0f; } void @@ -1431,21 +1436,185 @@ CAutomobile::ProcessBuoyancy(void) { EAXJMP(0x5308D0); } -WRAPPER void +void CAutomobile::DoDriveByShootings(void) -{ EAXJMP(0x564000); +{ + CAnimBlendAssociation *anim; + CWeapon *weapon = pDriver->GetWeapon(); + if(weapon->m_eWeaponType != WEAPONTYPE_UZI) + return; + + weapon->Update(pDriver->m_audioEntityId); + + bool lookingLeft = false; + bool lookingRight = false; + if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1){ + if(CPad::GetPad(0)->GetLookLeft()) + lookingLeft = true; + if(CPad::GetPad(0)->GetLookRight()) + lookingRight = true; + }else{ + if(TheCamera.Cams[TheCamera.ActiveCam].LookingLeft) + lookingLeft = true; + if(TheCamera.Cams[TheCamera.ActiveCam].LookingRight) + lookingRight = true; + } + + if(lookingLeft || lookingRight){ + if(lookingLeft){ + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R); + if(anim) + anim->blendDelta = -1000.0f; + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L); + if(anim == nil || anim->blendDelta < 0.0f) + CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_L); + else + anim->SetRun(); + }else if(pDriver->m_pMyVehicle->pPassengers[0] == nil || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIRSTPERSON){ + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L); + if(anim) + anim->blendDelta = -1000.0f; + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R); + if(anim == nil || anim->blendDelta < 0.0f) + CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_R); + else + anim->SetRun(); + } + + if(CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer){ + weapon->FireFromCar(this, lookingLeft); + weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70; + } + }else{ + weapon->Reload(); + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L); + if(anim) + anim->blendDelta = -1000.0f; + anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R); + if(anim) + anim->blendDelta = -1000.0f; + } + + // TODO: what is this? + if(!lookingLeft && m_weaponDoorTimerLeft > 0.0f){ + m_weaponDoorTimerLeft = max(m_weaponDoorTimerLeft - CTimer::GetTimeStep()*0.1f, 0.0f); + ProcessOpenDoor(CAR_DOOR_LF, NUM_ANIMS, m_weaponDoorTimerLeft); + } + if(!lookingRight && m_weaponDoorTimerRight > 0.0f){ + m_weaponDoorTimerRight = max(m_weaponDoorTimerRight - CTimer::GetTimeStep()*0.1f, 0.0f); + ProcessOpenDoor(CAR_DOOR_RF, NUM_ANIMS, m_weaponDoorTimerRight); + } } -WRAPPER int32 +int32 CAutomobile::RcbanditCheckHitWheels(void) -{ EAXJMP(0x53C990); +{ + int x, xmin, xmax; + int y, ymin, ymax; + + xmin = CWorld::GetSectorIndexX(GetPosition().x - 2.0f); + if(xmin < 0) xmin = 0; + xmax = CWorld::GetSectorIndexX(GetPosition().x + 2.0f); + if(xmax > NUMSECTORS_X-1) xmax = NUMSECTORS_X-1; + ymin = CWorld::GetSectorIndexX(GetPosition().y - 2.0f); + if(ymin < 0) ymin = 0; + ymax = CWorld::GetSectorIndexX(GetPosition().y + 2.0f); + if(ymax > NUMSECTORS_Y-1) ymax = NUMSECTORS_X-1; + + CWorld::AdvanceCurrentScanCode(); + + for(y = ymin; y <= ymax; y++) + for(x = xmin; x <= xmax; x++){ + CSector *s = CWorld::GetSector(x, y); + if(RcbanditCheck1CarWheels(s->m_lists[ENTITYLIST_VEHICLES]) || + RcbanditCheck1CarWheels(s->m_lists[ENTITYLIST_VEHICLES_OVERLAP])) + return 1; + } + return 0; +} + +int32 +CAutomobile::RcbanditCheck1CarWheels(CPtrList &list) +{ + static CMatrix matW2B; + int i; + CPtrNode *node; + CAutomobile *car; + CColModel *colModel = GetColModel(); + CVehicleModelInfo *mi; + + for(node = list.first; node; node = node->next){ + car = (CAutomobile*)node->item; + if(this != car && car->IsCar() && car->m_scanCode != CWorld::GetCurrentScanCode()){ + car->m_scanCode = CWorld::GetCurrentScanCode(); + + if(Abs(this->GetPosition().x - car->GetPosition().x) < 10.0f && + Abs(this->GetPosition().y - car->GetPosition().y) < 10.0f){ + mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(car->GetModelIndex()); + + for(i = 0; i < 4; i++){ + if(car->m_aSuspensionSpringRatioPrev[i] < 1.0f || car->m_status == STATUS_SIMPLE){ + CVector wheelPos; + CColSphere sph; + mi->GetWheelPosn(i, wheelPos); + matW2B = Invert(GetMatrix()); + sph.center = matW2B * (car->GetMatrix() * wheelPos); + sph.radius = mi->m_wheelScale*0.25f; + if(CCollision::TestSphereBox(sph, colModel->boundingBox)) + return 1; + } + } + } + } + } + return 0; +} + +void +CAutomobile::PlaceOnRoadProperly(void) +{ + CColPoint point; + CEntity *entity; + CColModel *colModel = GetColModel(); + float lenFwd, lenBack; + float frontZ, rearZ; + + lenFwd = colModel->boundingBox.max.y; + lenBack = -colModel->boundingBox.min.y; + + CVector front(GetPosition().x + GetForward().x*lenFwd, + GetPosition().y + GetForward().y*lenFwd, + GetPosition().z + 5.0f); + if(CWorld::ProcessVerticalLine(front, GetPosition().z - 5.0f, point, entity, + true, false, false, false, false, false, nil)){ + frontZ = point.point.z; + m_pCurGroundEntity = entity; + }else{ + frontZ = field_21C; + } + + CVector rear(GetPosition().x - GetForward().x*lenBack, + GetPosition().y - GetForward().y*lenBack, + GetPosition().z + 5.0f); + if(CWorld::ProcessVerticalLine(rear, GetPosition().z - 5.0f, point, entity, + true, false, false, false, false, false, nil)){ + rearZ = point.point.z; + m_pCurGroundEntity = entity; + }else{ + rearZ = field_220; + } + + float len = lenFwd + lenBack; + float angle = Atan((frontZ - rearZ)/len); + float c = Cos(angle); + float s = Sin(angle); + + GetRight() = CVector((front.y - rear.y)/len, -(front.x - rear.x)/len, 0.0f); + GetForward() = CVector(-c*GetRight().y, c*GetRight().x, s); + GetUp() = CrossProduct(GetRight(), GetForward()); + GetPosition() = CVector((front.x + rear.x)/2.0f, (front.y + rear.y)/2.0f, (frontZ + rearZ)/2.0f + GetHeightAboveRoad()); } -#if 0 -WRAPPER void -CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece) -{ EAXJMP(0x52F390); } -#else void CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece) { @@ -1686,7 +1855,6 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece) } } } -#endif void CAutomobile::dmgDrawCarCollidingParticles(const CVector &pos, float amount) @@ -2715,6 +2883,7 @@ STARTPATCHES InjectHook(0x53C0E0, &CAutomobile_::BurstTyre_, PATCH_JUMP); InjectHook(0x437690, &CAutomobile_::GetHeightAboveRoad_, PATCH_JUMP); InjectHook(0x53C450, &CAutomobile_::PlayCarHorn_, PATCH_JUMP); + InjectHook(0x53E090, &CAutomobile::PlaceOnRoadProperly, PATCH_JUMP); InjectHook(0x52F030, &CAutomobile::dmgDrawCarCollidingParticles, PATCH_JUMP); InjectHook(0x5353A0, &CAutomobile::ResetSuspension, PATCH_JUMP); InjectHook(0x52D210, &CAutomobile::SetupSuspensionLines, PATCH_JUMP); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 15b7ef0f..1a103777 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -67,8 +67,8 @@ public: CPhysical *m_aGroundPhysical[4]; // physicals touching wheels CVector m_aGroundOffset[4]; // from ground object to colpoint CEntity *m_pSetOnFireEntity; - float m_weaponThingA; // TODO - float m_weaponThingB; // TODO + float m_weaponDoorTimerLeft; // still don't know what exactly this is + float m_weaponDoorTimerRight; float m_fCarGunLR; float m_fCarGunUD; float m_fWindScreenRotation; @@ -119,6 +119,8 @@ public: void ProcessBuoyancy(void); void DoDriveByShootings(void); int32 RcbanditCheckHitWheels(void); + int32 RcbanditCheck1CarWheels(CPtrList &list); + void PlaceOnRoadProperly(void); void dmgDrawCarCollidingParticles(const CVector &pos, float amount); void PlayHornIfNecessary(void); void ResetSuspension(void); diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 4668ba7a..38d411cd 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -210,8 +210,8 @@ public: int16 field_214; int16 m_nBombTimer; // goes down with each frame CEntity *m_pBlowUpEntity; - float field_21C; - float field_220; + float field_21C; // front Z? + float field_220; // rear Z? eCarLock m_nDoorLock; int8 m_nLastWeaponDamage; // see eWeaponType, -1 if no damage int8 m_nRadioStation; diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index cd63544f..0fc89637 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -5,7 +5,9 @@ #include "WeaponInfo.h" WRAPPER bool CWeapon::Fire(CEntity*, CVector*) { EAXJMP(0x55C380); } +WRAPPER void CWeapon::FireFromCar(CAutomobile *car, bool left) { EAXJMP(0x55C940); } WRAPPER void CWeapon::AddGunshell(CEntity*, CVector const&, CVector2D const&, float) { EAXJMP(0x55F770); } +WRAPPER void CWeapon::Update(int32 audioEntity) { EAXJMP(0x563A10); } void CWeapon::Initialise(eWeaponType type, int ammo) diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h index fc1d9988..71fe1f45 100644 --- a/src/weapons/Weapon.h +++ b/src/weapons/Weapon.h @@ -1,5 +1,4 @@ #pragma once -#include "Entity.h" enum eWeaponType { @@ -46,6 +45,9 @@ enum eWeaponState WEAPONSTATE_MELEE_MADECONTACT }; +class CEntity; +class CAutomobile; + class CWeapon { public: @@ -61,8 +63,10 @@ public: } void Initialise(eWeaponType type, int ammo); + void Update(int32 audioEntity); void Reload(void); bool Fire(CEntity*, CVector*); + void FireFromCar(CAutomobile *car, bool left); void AddGunshell(CEntity*, CVector const&, CVector2D const&, float); bool IsTypeMelee(void); bool IsType2Handed(void);