@@ -83,6 +83,7 @@ void CProjectileInfoSA::DestroyProjectileObject(CObjectSAInterface* object)
83
83
if (info.m_projectile ->m_object == object)
84
84
{
85
85
delete info.m_projectile ;
86
+ info.m_projectile = nullptr ;
86
87
break ;
87
88
}
88
89
}
@@ -131,13 +132,8 @@ void CProjectileInfoSA::RemoveDetonatorProjectiles()
131
132
if (!info.m_isActive || info.m_weaponType != eWeaponType::WEAPONTYPE_REMOTE_SATCHEL_CHARGE)
132
133
continue ;
133
134
134
- CVector pos;
135
-
136
135
CObjectSAInterface* object = info.m_projectile ->m_object ;
137
- if (object->matrix )
138
- pos = object->matrix ->vPos ;
139
- else
140
- pos = object->m_transform .m_translate ;
136
+ CVector pos = object->matrix ? object->matrix ->vPos : object->m_transform .m_translate ;
141
137
142
138
object->bRemoveFromWorld = true ;
143
139
@@ -166,6 +162,7 @@ void CProjectileInfoSA::RemoveIfThisIsAProjectile(CObjectSAInterface* object)
166
162
DestroyProjectileObject (info.m_projectile ->m_object );
167
163
168
164
delete info.m_projectile ;
165
+ info.m_projectile = nullptr ;
169
166
}
170
167
}
171
168
@@ -183,7 +180,9 @@ void CProjectileInfoSA::RemoveAllProjectiles()
183
180
DestroyProjectileObject (info.m_projectile ->m_object );
184
181
185
182
info.m_isActive = false ;
183
+
186
184
delete info.m_projectile ;
185
+ info.m_projectile = nullptr ;
187
186
}
188
187
}
189
188
@@ -351,22 +350,19 @@ void CProjectileInfoSA::Update()
351
350
projectileInfo->m_counter = 0 ;
352
351
}
353
352
354
- // LABEL_138
355
- const CVector& pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
356
- projectileInfo->m_lastPos = pos;
353
+ UpdateLastPos (projectileInfo);
357
354
continue ;
358
355
}
359
356
360
- const CVector& pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
361
- projectileInfo->m_lastPos = pos;
357
+ UpdateLastPos (projectileInfo);
362
358
StaticRemoveProjectile (projectileInfo, projectileInfo->m_projectile );
363
359
continue ;
364
360
}
365
361
366
362
if (projectileInfo->m_weaponType == eWeaponType::WEAPONTYPE_ROCKET)
367
363
{
368
364
float time = pGame->GetTimeStep () * 0 .008f ;
369
- projectile->m_vecLinearVelocity = projectile->m_vecLinearVelocity + projectile->matrix ->vFront * time;
365
+ projectile->m_vecLinearVelocity += ( projectile->matrix ? projectile->matrix ->vFront : CVector ( 0 , 0 , 0 )) * time;
370
366
371
367
float length = projectile->m_vecLinearVelocity .Length ();
372
368
if (length > 9.9 )
@@ -375,43 +371,10 @@ void CProjectileInfoSA::Update()
375
371
projectile->m_vecLinearVelocity *= 9 .9f ;
376
372
}
377
373
378
- // LABEL_120
379
- if (!projectile->bOnSolidSurface )
380
- {
381
- CVector pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
382
-
383
- *(void **)0xB7CD68 = projectileInfo->m_creator ; // pGame->GetWorld()->IgnoreEntity but later
384
- projectile->bUsesCollision = false ;
385
-
386
- // Call CWorld::GetIsLineOfSightClear
387
- bool clear = ((bool (__cdecl*)(CVector*, CVector*, bool , bool , bool , bool , bool , bool , bool ))0x56A490 )(&projectileInfo->m_lastPos , &pos, true , true , true , true , false , false , false );
388
-
389
- projectile->bUsesCollision = true ;
390
- *(void **)0xB7CD68 = nullptr ;
391
-
392
- projectile->m_entityIgnoredCollision = projectileInfo->m_creator ;
393
- if (clear)
394
- {
395
- const CVector& pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
396
- projectileInfo->m_lastPos = pos;
397
- continue ;
398
- }
399
- }
400
-
401
- if (projectile->m_ucCollisionState > 0 )
402
- {
403
- if (projectile->pLastContactedEntity [0 ] && (projectile->pLastContactedEntity [0 ]->GetInterface () == projectileInfo->m_creator || projectile->pLastContactedEntity [0 ]->GetModelIndex () == 345 ))
404
- {
405
- // LABEL_138
406
- const CVector& pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
407
- projectileInfo->m_lastPos = pos;
408
- continue ;
409
- }
410
- }
374
+ if (CheckIsLineOfSightClear (projectileInfo))
375
+ continue ;
411
376
412
- // LABEL_56
413
- const CVector& pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
414
- projectileInfo->m_lastPos = pos;
377
+ UpdateLastPos (projectileInfo);
415
378
StaticRemoveProjectile (projectileInfo, projectileInfo->m_projectile );
416
379
continue ;
417
380
}
@@ -501,114 +464,68 @@ void CProjectileInfoSA::Update()
501
464
if (!targetProjectile || evaluate2 <= evaluate1)
502
465
targetProjectile = (CPhysicalSAInterface*)projectileInfo->m_target ;
503
466
504
- bool unk_v103 = false ;
467
+ bool isPlaneTargetFromLocalPlayer = false ;
505
468
506
469
if (targetProjectile->nType == ENTITY_TYPE_VEHICLE)
507
470
{
508
471
if ((projectileInfo->m_creator == localPlayer || projectileInfo->m_creator == localPlayer->pVehicle ) && static_cast <CVehicleSAInterface*>(targetProjectile)->m_vehicleSubClass == (uint32_t )VehicleClass::PLANE)
509
- unk_v103 = true ;
472
+ isPlaneTargetFromLocalPlayer = true ;
510
473
}
511
474
512
- CVector startPoint_unk = projectile->m_vecLinearVelocity * 100 .0f + pos;
475
+ CVector startPos = projectile->m_vecLinearVelocity * 100 .0f + pos;
513
476
514
- if (unk_v103 )
515
- startPoint_unk = pos;
477
+ if (isPlaneTargetFromLocalPlayer )
478
+ startPos = pos;
516
479
517
480
CVector targetProjectilePos = targetProjectile->matrix ? targetProjectile->matrix ->vPos : targetProjectile->m_transform .m_translate ;
518
481
519
- float mult = 0 .0f ;
520
-
521
482
CVector diff = pos - targetProjectilePos;
522
483
float vecLen = diff.Length ();
523
- if (vecLen >= 50 .0f )
524
- mult = 50 .0f ;
525
- else
526
- mult = vecLen;
527
-
528
- if (unk_v103)
529
- {
530
- if (vecLen > 1 .5f )
531
- mult = 1 .5f ;
532
- else
533
- mult = vecLen;
534
- }
484
+ float maxDist = isPlaneTargetFromLocalPlayer ? std::min (vecLen, 1 .5f ) : std::min (vecLen, 50 .0f );
535
485
536
- CVector vecTarget = targetProjectile->m_vecLinearVelocity * mult ;
537
- CVector vec_v113 = projectile->m_vecLinearVelocity ;
538
- vec_v113 .Normalize ();
486
+ CVector targetVelocityCompensation = targetProjectile->m_vecLinearVelocity * maxDist ;
487
+ CVector projectileDir = projectile->m_vecLinearVelocity ;
488
+ projectileDir .Normalize ();
539
489
540
- CVector vec_110 = CVector ((vecTarget .fX + targetProjectilePos.fX ) - startPoint_unk .fX , (vecTarget .fY + targetProjectilePos.fY ) - startPoint_unk .fY , (vecTarget .fZ + targetProjectilePos.fZ ) - startPoint_unk .fZ );
490
+ CVector aimAdjustment = CVector ((targetVelocityCompensation .fX + targetProjectilePos.fX ) - startPos .fX , (targetVelocityCompensation .fY + targetProjectilePos.fY ) - startPos .fY , (targetVelocityCompensation .fZ + targetProjectilePos.fZ ) - startPos .fZ );
541
491
542
- float unk_v84 = vec_110 .fX * vec_v113 .fX + vec_110 .fY * vec_v113 .fY + vec_110 .fZ * vec_v113 .fZ ;
543
- if (unk_v84 < 0 .0f )
544
- vec_110 -= vec_v113 * unk_v84 ;
492
+ float dotToAimDir = aimAdjustment .fX * projectileDir .fX + aimAdjustment .fY * projectileDir .fY + aimAdjustment .fZ * projectileDir .fZ ;
493
+ if (dotToAimDir < 0 .0f )
494
+ aimAdjustment -= projectileDir * dotToAimDir ;
545
495
546
- vec_110 .Normalize ();
496
+ aimAdjustment .Normalize ();
547
497
548
- float mult2 = 0 .0f ;
549
- float mult3 = 1 .0f ;
498
+ float steeringStrength = 0 .0f ;
499
+ float velocityScale = 1 .0f ;
550
500
551
501
if (projectileInfo->m_creator == localPlayer || projectileInfo->m_creator == localPlayer->pVehicle )
552
- mult2 = 0 .011f ;
502
+ steeringStrength = 0 .011f ;
553
503
else
554
- mult2 = 0 .009f ;
504
+ steeringStrength = 0 .009f ;
555
505
556
506
if (targetProjectile->m_vecLinearVelocity .Length () > 0 .8f )
557
- mult2 *= 1 .2f ;
507
+ steeringStrength *= 1 .2f ;
558
508
559
- if (unk_v103 )
509
+ if (isPlaneTargetFromLocalPlayer )
560
510
{
561
- mult2 = 0 .15f ;
562
- mult3 = pGame->GetTimeStep () * 0 .95f ;
511
+ steeringStrength = 0 .15f ;
512
+ velocityScale = pGame->GetTimeStep () * 0 .95f ;
563
513
}
564
514
565
- projectile->m_vecLinearVelocity *= mult3 ;
566
- projectile->m_vecLinearVelocity += vec_110 * (pGame->GetTimeStep () * mult2 );
515
+ projectile->m_vecLinearVelocity *= velocityScale ;
516
+ projectile->m_vecLinearVelocity += aimAdjustment * (pGame->GetTimeStep () * steeringStrength );
567
517
568
- float len3 = projectile->m_vecLinearVelocity .Length ();
569
- if (len3 > 9 .9f )
518
+ if (projectile->m_vecLinearVelocity .Length () > 9 .9f )
570
519
{
571
520
projectile->m_vecLinearVelocity .Normalize ();
572
521
projectile->m_vecLinearVelocity *= 9 .9f ;
573
522
}
574
523
575
- projectile->matrix ->vFront = vec_v113;
576
-
577
- // LABEL_120
578
- if (!projectile->bOnSolidSurface )
579
- {
580
- CVector pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
581
-
582
- *(void **)0xB7CD68 = projectileInfo->m_creator ;
583
- projectile->bUsesCollision = false ;
524
+ projectile->matrix ->vFront = projectileDir;
584
525
585
- // CWorld::GetIsLineOfSightClear
586
- bool clear = (( bool (__cdecl*)(CVector*, CVector*, bool , bool , bool , bool , bool , bool , bool )) 0x56A490 )(&projectileInfo-> m_lastPos , &pos, true , true , true , true , false , false , false ) ;
526
+ if ( CheckIsLineOfSightClear (projectileInfo))
527
+ continue ;
587
528
588
- projectile->bUsesCollision = true ;
589
- *(void **)0xB7CD68 = nullptr ;
590
-
591
- projectile->m_entityIgnoredCollision = projectileInfo->m_creator ;
592
- if (clear)
593
- {
594
- const CVector& pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
595
- projectileInfo->m_lastPos = pos;
596
- continue ;
597
- }
598
- }
599
-
600
- if (projectile->m_ucCollisionState > 0 )
601
- {
602
- if (projectile->pLastContactedEntity [0 ] && (projectile->pLastContactedEntity [0 ]->GetInterface () == projectileInfo->m_creator || projectile->pLastContactedEntity [0 ]->GetModelIndex () == 345 ))
603
- {
604
- // LABEL_138
605
- const CVector& pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
606
- projectileInfo->m_lastPos = pos;
607
- continue ;
608
- }
609
- }
610
-
611
- // LABEL_56
612
529
projectileInfo->m_lastPos = pos;
613
530
StaticRemoveProjectile (projectileInfo, projectileInfo->m_projectile );
614
531
continue ;
@@ -620,9 +537,7 @@ void CProjectileInfoSA::Update()
620
537
{
621
538
if (projectileInfo->m_weaponType != eWeaponType::WEAPONTYPE_REMOTE_SATCHEL_CHARGE || projectile->m_fDamageImpulseMagnitude <= 0 .0f || !projectile->m_pCollidedEntity || projectile->m_pAttachedEntity )
622
539
{
623
- // LABEL_138
624
- const CVector& pos = projectile->matrix ? projectile->matrix ->vPos : projectile->m_transform .m_translate ;
625
- projectileInfo->m_lastPos = pos;
540
+ UpdateLastPos (projectileInfo);
626
541
continue ;
627
542
}
628
543
@@ -665,22 +580,75 @@ void CProjectileInfoSA::InitCollision(CObjectSAInterface* projectile)
665
580
colData->m_spheres = ((CColSphereSA * (__cdecl*)(int ))0x72F420 )(20 ); // CMemoryMgr::Malloc
666
581
667
582
// CColSphere::Set
668
- ((void (__thiscall*)(CColSphereSA*, float , CVector&, unsigned char , char , unsigned char ))(0x40FD10 ))(
669
- colData->m_spheres , col->m_sphere .m_radius * 0 .75f , col->m_sphere .m_center , 56 , 0 , 255 );
583
+ ((void (__thiscall*)(CColSphereSA*, float , CVector&, unsigned char , char , unsigned char ))(0x40FD10 ))(colData->m_spheres , col->m_sphere .m_radius * 0 .75f , col->m_sphere .m_center , 56 , 0 , 255 );
670
584
}
671
585
}
672
586
else
673
587
{
674
588
// CColModel::AllocateData
675
589
((void (__thiscall*)(CColModelSAInterface*, int , int , int , int , int , int ))(0x40F870 ))(col, 1 , 0 , 0 , 0 , 0 , 0 );
676
590
677
- // CColSphere::Set
678
- (( void (__thiscall*)(CColSphereSA*, float , CVector&, unsigned char , char , unsigned char ))( 0x40FD10 ))(
679
- col->m_data ->m_spheres , col->m_sphere .m_radius * 0 .75f , col->m_sphere .m_center , 56 , 0 , 255 );
591
+ if (col-> m_data )
592
+ // CColSphere::Set
593
+ (( void (__thiscall*)(CColSphereSA*, float , CVector&, unsigned char , char , unsigned char ))( 0x40FD10 ))( col->m_data ->m_spheres , col->m_sphere .m_radius * 0 .75f , col->m_sphere .m_center , 56 , 0 , 255 );
680
594
}
681
595
}
682
596
}
683
597
598
+ void CProjectileInfoSA::UpdateLastPos (CProjectileInfoSA* info)
599
+ {
600
+ if (!info)
601
+ return ;
602
+
603
+ CObjectSAInterface* object = info->m_projectile ? info->m_projectile ->m_object : nullptr ;
604
+ if (!object)
605
+ return ;
606
+
607
+ info->m_lastPos = object->matrix ? object->matrix ->vPos : object->m_transform .m_translate ;
608
+ }
609
+
610
+ bool CProjectileInfoSA::CheckIsLineOfSightClear (CProjectileInfoSA* info)
611
+ {
612
+ if (!info)
613
+ return false ;
614
+
615
+ CObjectSAInterface* object = info->m_projectile ? info->m_projectile ->m_object : nullptr ;
616
+ if (!object)
617
+ return false ;
618
+
619
+ if (!object->bOnSolidSurface )
620
+ {
621
+ CVector pos = object->matrix ? object->matrix ->vPos : object->m_transform .m_translate ;
622
+
623
+ *(void **)0xB7CD68 = info->m_creator ;
624
+ object->bUsesCollision = false ;
625
+
626
+ // CWorld::GetIsLineOfSightClear
627
+ bool clear = ((bool (__cdecl*)(CVector*, CVector*, bool , bool , bool , bool , bool , bool , bool ))0x56A490 )(&info->m_lastPos , &pos, true , true , true , true , false , false , false );
628
+
629
+ object->bUsesCollision = true ;
630
+ *(void **)0xB7CD68 = nullptr ;
631
+
632
+ object->m_entityIgnoredCollision = info->m_creator ;
633
+ if (clear)
634
+ {
635
+ UpdateLastPos (info);
636
+ return true ;
637
+ }
638
+ }
639
+
640
+ if (object->m_ucCollisionState > 0 )
641
+ {
642
+ if (object->pLastContactedEntity [0 ] && (object->pLastContactedEntity [0 ]->GetInterface () == info->m_creator || object->pLastContactedEntity [0 ]->GetModelIndex () == 345 ))
643
+ {
644
+ UpdateLastPos (info);
645
+ return true ;
646
+ }
647
+ }
648
+
649
+ return false ;
650
+ }
651
+
684
652
CProjectileInfo* CProjectileInfoSA::StaticAddProjectile (CEntitySAInterface* creator, eWeaponType projectileType, CVector pos, float force, CVector* target, CEntitySAInterface* targetEntity)
685
653
{
686
654
int freeIndex = FindFreeIndex ();
@@ -716,10 +684,10 @@ CProjectileInfo* CProjectileInfoSA::StaticAddProjectile(CEntitySAInterface* crea
716
684
717
685
CVector projectileVelocity = ComputeOffsetVector (heading, offset, force);
718
686
719
- int unk_v64 = 0 ;
687
+ bool useStaticObjectInfo = false ;
720
688
bool applyGravity = true ;
721
689
722
- int model = 1337 ;
690
+ std:: uint32_t model;
723
691
724
692
if (projectileType == eWeaponType::WEAPONTYPE_FLARE)
725
693
{
@@ -755,12 +723,12 @@ CProjectileInfo* CProjectileInfoSA::StaticAddProjectile(CEntitySAInterface* crea
755
723
projectileVelocity += static_cast <CVehicleSAInterface*>(creator)->m_vecLinearVelocity ;
756
724
757
725
InitCollision (projectile);
758
- unk_v64 = 5 ;
726
+ useStaticObjectInfo = true ;
759
727
break ;
760
728
}
761
729
case eWeaponType::WEAPONTYPE_TEARGAS:
762
730
{
763
- unk_v64 = 5 ;
731
+ useStaticObjectInfo = true ;
764
732
elasticity = 0 .5f ;
765
733
timeToDestroy = 20000 ;
766
734
@@ -854,7 +822,8 @@ CProjectileInfo* CProjectileInfoSA::StaticAddProjectile(CEntitySAInterface* crea
854
822
projectile->bEnableCollision = true ;
855
823
projectile->bApplyGravity = applyGravity;
856
824
857
- if (unk_v64 == 5 )
825
+ // CObjectData::Initialise (0x5B5420)
826
+ if (useStaticObjectInfo)
858
827
projectile->pObjectInfo = (CObjectInfo*)0xBB4BD0 ;
859
828
860
829
pGame->GetWorld ()->Add (projectile, eDebugCaller::CObject_Constructor);
0 commit comments