From 3bb607f9cbc3d26a1b312f61f86ce3f42ef82a94 Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 25 Jul 2019 16:33:37 +0200 Subject: implemented CAutomobile::TankControl --- src/core/Explosion.h | 12 ++++- src/core/PlayerInfo.h | 8 ++-- src/core/re3.cpp | 2 + src/vehicles/Automobile.cpp | 110 ++++++++++++++++++++++++++++++++++++++++++-- src/weapons/Weapon.cpp | 1 + src/weapons/Weapon.h | 2 + 6 files changed, 125 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/core/Explosion.h b/src/core/Explosion.h index 69508490..93d60ab3 100644 --- a/src/core/Explosion.h +++ b/src/core/Explosion.h @@ -4,8 +4,16 @@ class CEntity; enum eExplosionType { - EXPLOSION_3 = 3, - EXPLOSION_4 + EXPLOSION_GRENADE, + EXPLOSION_MOLOTOV, + EXPLOSION_ROCKET, + EXPLOSION_CAR, + EXPLOSION_CAR_QUICK, + EXPLOSION_HELI, + EXPLOSION_MINE, + EXPLOSION_BARREL, + EXPLOSION_TANK_GRENADE, + EXPLOSION_HELI_BOMB }; class CExplosion diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index d8128424..9327b9a0 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -45,10 +45,10 @@ public: int8 field_225; int8 field_226; int8 field_227; - int32 m_nTimeLostRemoteCar; - int32 m_nTimeLastHealthLoss; - int32 m_nTimeLastArmourLoss; - int32 field_240; + uint32 m_nTimeLostRemoteCar; + uint32 m_nTimeLastHealthLoss; + uint32 m_nTimeLastArmourLoss; + uint32 m_nTimeTankShotGun; int32 m_nUpsideDownCounter; int32 field_248; int16 m_nTrafficMultiplier; diff --git a/src/core/re3.cpp b/src/core/re3.cpp index a0032bc6..6566a282 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -296,6 +296,8 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); }); DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); }); DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); }); + DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); }); + DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); }); DebugMenuAddCmd("Debug", "Fix Car", FixCar); diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index bc0c8593..0c4d0ff9 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -1421,9 +1421,111 @@ CAutomobile::FireTruckControl(void) { EAXJMP(0x522590); } -WRAPPER void +void CAutomobile::TankControl(void) -{ EAXJMP(0x53D530); +{ + int i; + + // These coords are 1 unit higher then they should be relative to model center + CVector turrentBase(0.0f, -1.394f, 2.296f); + CVector gunEnd(0.0f, 1.813f, 2.979f); + CVector baseToEnd = gunEnd - turrentBase; + + if(this != FindPlayerVehicle()) + return; + if(CWorld::Players[CWorld::PlayerInFocus].m_WBState != WBSTATE_PLAYING) + return; + + // Rotate turret + float prevAngle = m_fCarGunLR; + m_fCarGunLR -= CPad::GetPad(0)->GetCarGunLeftRight() * 0.00015f * CTimer::GetTimeStep(); + if(m_fCarGunLR < 0.0f) + m_fCarGunLR += TWOPI; + if(m_fCarGunLR > TWOPI) + m_fCarGunLR -= TWOPI; + if(m_fCarGunLR != prevAngle) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_TANK_TURRET_ROTATE, Abs(m_fCarGunLR - prevAngle)); + + // Shoot + if(CPad::GetPad(0)->CarGunJustDown() && + CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeTankShotGun + 800){ + CWorld::Players[CWorld::PlayerInFocus].m_nTimeTankShotGun = CTimer::GetTimeInMilliseconds(); + + // more like -sin(angle), cos(angle), i.e. rotated (0,1,0) + CVector turretDir = CVector(Sin(-m_fCarGunLR), Cos(-m_fCarGunLR), 0.0f); + turretDir = Multiply3x3(GetMatrix(), turretDir); + + float c = Cos(m_fCarGunLR); + float s = Sin(m_fCarGunLR); + CVector rotatedEnd( + c*baseToEnd.x - s*baseToEnd.y, + s*baseToEnd.x + c*baseToEnd.y, + baseToEnd.z - 1.0f); // correct offset here + rotatedEnd += turrentBase; + + CVector point1 = GetMatrix() * rotatedEnd; + CVector point2 = point1 + 60.0f*turretDir; + m_vecMoveSpeed -= 0.06f*turretDir; + m_vecMoveSpeed.z += 0.05f; + + CWeapon::DoTankDoomAiming(FindPlayerVehicle(), FindPlayerPed(), &point1, &point2); + CColPoint colpoint; + CEntity *entity = nil; + CWorld::ProcessLineOfSight(point1, point2, colpoint, entity, true, true, true, true, true, true, false); + if(entity) + point2 = colpoint.point - 0.04f*(colpoint.point - point1); + + CExplosion::AddExplosion(nil, FindPlayerPed(), EXPLOSION_TANK_GRENADE, point2, 0); + + // Add particles on the way to the explosion; + float shotDist = (point2 - point1).Magnitude(); + int n = shotDist/4.0f; + RwRGBA black = { 0, 0, 0, 0 }; + for(i = 0; i < n; i++){ + float f = (float)i/n; + CParticle::AddParticle(PARTICLE_HELI_DUST, + point1 + f*(point2 - point1), + CVector(0.0f, 0.0f, 0.0f), + nil, 0.1f, black); + } + + // More particles + CVector shotDir = point2 - point1; + shotDir.Normalise(); + for(i = 0; i < 15; i++){ + float f = i/15.0f; + CParticle::AddParticle(PARTICLE_GUNSMOKE2, point1, + shotDir*CGeneral::GetRandomNumberInRange(0.3f, 1.0f)*f, + nil, CGeneral::GetRandomNumberInRange(0.5f, 1.0f)*f, black); + } + + // And some gun flashes near the gun + CVector flashPos = point1; + CVector nullDir(0.0f, 0.0f, 0.0f); + int lifeSpan = 250; + if(m_vecMoveSpeed.Magnitude() > 0.08f){ + lifeSpan = 125; + flashPos.x += 0.5f*m_vecMoveSpeed.x; + flashPos.y += 0.5f*m_vecMoveSpeed.y; + } + CParticle::AddParticle(PARTICLE_GUNFLASH, flashPos, nullDir, nil, 0.4f, black, 0, 0, 0, lifeSpan); + flashPos += 0.3f*shotDir; + CParticle::AddParticle(PARTICLE_GUNFLASH, flashPos, nullDir, nil, 0.2f, black, 0, 0, 0, lifeSpan); + flashPos += 0.1f*shotDir; + CParticle::AddParticle(PARTICLE_GUNFLASH, flashPos, nullDir, nil, 0.15f, black, 0, 0, 0, lifeSpan); + } + + // Actually update turret node + if(m_aCarNodes[CAR_WINDSCREEN]){ + CMatrix mat; + CVector pos; + + mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WINDSCREEN])); + pos = mat.GetPosition(); + mat.SetRotateZ(m_fCarGunLR); + mat.Translate(pos); + mat.UpdateRW(); + } } WRAPPER void @@ -2313,9 +2415,9 @@ CAutomobile::BlowUpCar(CEntity *culprit) gFireManager.StartFire(this, culprit, 0.8f, 1); // TODO CDarkel::RegisterCarBlownUpByPlayer(this); if(GetModelIndex() == MI_RCBANDIT) - CExplosion::AddExplosion(this, culprit, EXPLOSION_4, GetPosition(), 0); // TODO + CExplosion::AddExplosion(this, culprit, EXPLOSION_CAR_QUICK, GetPosition(), 0); else - CExplosion::AddExplosion(this, culprit, EXPLOSION_3, GetPosition(), 0); // TODO + CExplosion::AddExplosion(this, culprit, EXPLOSION_CAR, GetPosition(), 0); } bool diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 0fc89637..056c584a 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -8,6 +8,7 @@ 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); } +WRAPPER void CWeapon::DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end) { EAXJMP(0x563200); } void CWeapon::Initialise(eWeaponType type, int ammo) diff --git a/src/weapons/Weapon.h b/src/weapons/Weapon.h index 71fe1f45..71c1f344 100644 --- a/src/weapons/Weapon.h +++ b/src/weapons/Weapon.h @@ -70,5 +70,7 @@ public: void AddGunshell(CEntity*, CVector const&, CVector2D const&, float); bool IsTypeMelee(void); bool IsType2Handed(void); + + static void DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end); }; static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error"); -- cgit v1.2.3