mirror of
https://github.com/GTAmodding/re3.git
synced 2024-12-24 03:25:40 +00:00
commit
9d3c73156b
5 changed files with 318 additions and 15 deletions
|
@ -64,7 +64,6 @@ CPacManPickups
|
|||
CPedIK
|
||||
CPedPath
|
||||
CPlayerPed
|
||||
CProjectileInfo
|
||||
CRoadBlocks
|
||||
CRunningScript - being worked on
|
||||
CStats
|
||||
|
|
|
@ -86,6 +86,7 @@ enum Config {
|
|||
NUM_ACCIDENTS = 20,
|
||||
NUM_FIRES = 40,
|
||||
NUM_GARAGES = 32,
|
||||
NUM_PROJECTILES = 32,
|
||||
|
||||
NUMPEDROUTES = 200,
|
||||
NUMPHONES = 50,
|
||||
|
|
|
@ -109,7 +109,7 @@ DotProduct(const CVector &v1, const CVector &v2)
|
|||
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
|
||||
}
|
||||
|
||||
inline CVector
|
||||
inline const CVector
|
||||
CrossProduct(const CVector &v1, const CVector &v2)
|
||||
{
|
||||
return CVector(
|
||||
|
|
|
@ -1,17 +1,317 @@
|
|||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
#include "Camera.h"
|
||||
#include "General.h"
|
||||
#include "Heli.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "Particle.h"
|
||||
#include "Ped.h"
|
||||
#include "Plane.h"
|
||||
#include "ProjectileInfo.h"
|
||||
#include "Projectile.h"
|
||||
#include "Explosion.h"
|
||||
#include "Weapon.h"
|
||||
#include "World.h"
|
||||
|
||||
CProjectileInfo* gaProjectileInfo = (CProjectileInfo*)0x64ED50;
|
||||
CProjectile* (&CProjectileInfo::ms_apProjectile)[32] = *(CProjectile*(*)[32])*(uintptr*)0x87C748;
|
||||
CProjectileInfo (&gaProjectileInfo)[NUM_PROJECTILES] = *(CProjectileInfo(*)[NUM_PROJECTILES])*(uintptr*)0x64ED50;
|
||||
CProjectile* (&CProjectileInfo::ms_apProjectile)[NUM_PROJECTILES] = *(CProjectile*(*)[NUM_PROJECTILES])*(uintptr*)0x87C748;
|
||||
|
||||
WRAPPER void CProjectileInfo::RemoveAllProjectiles(void) { EAXJMP(0x55BB80); }
|
||||
WRAPPER bool CProjectileInfo::RemoveIfThisIsAProjectile(CObject *pObject) { EAXJMP(0x55BBD0); }
|
||||
WRAPPER bool CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove) { EAXJMP(0x55BA50); }
|
||||
void
|
||||
CProjectileInfo::Initialise()
|
||||
{
|
||||
debug("Initialising CProjectileInfo...\n");
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(ms_apProjectile); i++) {
|
||||
ms_apProjectile[i] = nil;
|
||||
gaProjectileInfo[i].m_eWeaponType = WEAPONTYPE_GRENADE;
|
||||
gaProjectileInfo[i].m_pSource = nil;
|
||||
gaProjectileInfo[i].m_nExplosionTime = 0;
|
||||
gaProjectileInfo[i].m_bInUse = false;
|
||||
}
|
||||
|
||||
debug("CProjectileInfo ready\n");
|
||||
}
|
||||
|
||||
void
|
||||
CProjectileInfo::Shutdown()
|
||||
{
|
||||
debug("Shutting down CProjectileInfo...\n");
|
||||
debug("CProjectileInfo shut down\n");
|
||||
}
|
||||
|
||||
CProjectileInfo*
|
||||
CProjectileInfo::GetProjectileInfo(int32 id)
|
||||
{
|
||||
return &gaProjectileInfo[id];
|
||||
}
|
||||
|
||||
bool
|
||||
CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos, float speed)
|
||||
{
|
||||
int8 SpecialCollisionResponseCase = COLLRESPONSE_NONE;
|
||||
bool gravity = true;
|
||||
CMatrix matrix;
|
||||
float elasticity = 0.75f;
|
||||
CPed* ped = (CPed*)entity;
|
||||
int time;
|
||||
CVector velocity;
|
||||
|
||||
switch (weapon)
|
||||
{
|
||||
case WEAPONTYPE_ROCKETLAUNCHER:
|
||||
{
|
||||
float vy = 1.25f;
|
||||
time = CTimer::GetTimeInMilliseconds() + 1400;
|
||||
if (ped->IsPlayer()) {
|
||||
matrix.GetForward() = TheCamera.Cams[TheCamera.ActiveCam].Front;
|
||||
matrix.GetUp() = TheCamera.Cams[TheCamera.ActiveCam].Up;
|
||||
matrix.GetRight() = CrossProduct(TheCamera.Cams[TheCamera.ActiveCam].Up, TheCamera.Cams[TheCamera.ActiveCam].Front);
|
||||
matrix.GetPosition() = pos;
|
||||
} else if (ped->m_pSeekTarget != nil) {
|
||||
float ry = CGeneral::GetRadianAngleBetweenPoints(1.0f, ped->m_pSeekTarget->GetPosition().z, 1.0f, pos.z);
|
||||
float rz = Atan2(-ped->GetForward().x, ped->GetForward().y);
|
||||
vy = 0.35f * speed + 0.15f;
|
||||
matrix.SetTranslate(0.0f, 1.0f, 1.0f);
|
||||
matrix.Rotate(0.0f, ry, rz);
|
||||
matrix.GetPosition() += pos;
|
||||
} else {
|
||||
matrix = ped->GetMatrix();
|
||||
}
|
||||
velocity = Multiply3x3(matrix, CVector(0.0f, vy, 0.0f));
|
||||
gravity = false;
|
||||
break;
|
||||
}
|
||||
case WEAPONTYPE_FLAMETHROWER:
|
||||
Error("Undefined projectile type, AddProjectile, ProjectileInfo.cpp");
|
||||
break;
|
||||
case WEAPONTYPE_MOLOTOV:
|
||||
{
|
||||
time = CTimer::GetTimeInMilliseconds() + 2000;
|
||||
float scale = 0.22f * speed + 0.15f;
|
||||
if (scale >= 0.2f)
|
||||
scale = 0.2f;
|
||||
float angle = Atan2(-ped->GetForward().x, ped->GetForward().y);
|
||||
matrix.SetTranslate(0.0f, 0.0f, 0.0f);
|
||||
matrix.RotateZ(angle);
|
||||
matrix.GetPosition() += pos;
|
||||
velocity.x = -1.0f * scale * Sin(angle);
|
||||
velocity.y = scale * Cos(angle);
|
||||
velocity.z = (0.2f * speed + 0.4f) * scale;
|
||||
break;
|
||||
}
|
||||
case WEAPONTYPE_GRENADE:
|
||||
{
|
||||
time = CTimer::GetTimeInMilliseconds() + 2000;
|
||||
float scale = 0.0f;
|
||||
if (speed != 0.0f)
|
||||
scale = 0.22f * speed + 0.15f;
|
||||
float angle = Atan2(-ped->GetForward().x, ped->GetForward().y);
|
||||
matrix.SetTranslate(0.0f, 0.0f, 0.0f);
|
||||
matrix.RotateZ(angle);
|
||||
matrix.GetPosition() += pos;
|
||||
SpecialCollisionResponseCase = COLLRESPONSE_UNKNOWN5;
|
||||
velocity.x = -1.0f * scale * Sin(angle);
|
||||
velocity.y = scale * Cos(angle);
|
||||
velocity.z = (0.4f * speed + 0.4f) * scale;
|
||||
elasticity = 0.5f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (gaProjectileInfo[i].m_bInUse && i < ARRAY_SIZE(gaProjectileInfo)) i++;
|
||||
|
||||
if (i == ARRAY_SIZE(gaProjectileInfo))
|
||||
return false;
|
||||
|
||||
switch (weapon)
|
||||
{
|
||||
case WEAPONTYPE_ROCKETLAUNCHER:
|
||||
ms_apProjectile[i] = new CProjectile(MI_MISSILE);
|
||||
break;
|
||||
case WEAPONTYPE_FLAMETHROWER:
|
||||
break;
|
||||
case WEAPONTYPE_MOLOTOV:
|
||||
ms_apProjectile[i] = new CProjectile(MI_MOLOTOV);
|
||||
break;
|
||||
case WEAPONTYPE_GRENADE:
|
||||
ms_apProjectile[i] = new CProjectile(MI_GRENADE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ms_apProjectile[i] == nil)
|
||||
return false;
|
||||
|
||||
gaProjectileInfo[i].m_eWeaponType = weapon;
|
||||
gaProjectileInfo[i].m_pSource = ped;
|
||||
ms_apProjectile[i]->GetMatrix() = matrix;
|
||||
ms_apProjectile[i]->SetMoveSpeed(velocity);
|
||||
ms_apProjectile[i]->bAffectedByGravity = gravity;
|
||||
|
||||
gaProjectileInfo[i].m_nExplosionTime = time;
|
||||
ms_apProjectile[i]->m_fElasticity = elasticity;
|
||||
ms_apProjectile[i]->m_nSpecialCollisionResponseCases = SpecialCollisionResponseCase;
|
||||
|
||||
gaProjectileInfo[i].m_bInUse = true;
|
||||
CWorld::Add(ms_apProjectile[i]);
|
||||
|
||||
gaProjectileInfo[i].m_vecPos = ms_apProjectile[i]->GetPosition();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CProjectileInfo::RemoveProjectile(CProjectileInfo *info, CProjectile *projectile)
|
||||
{
|
||||
RemoveNotAdd(info->m_pSource, info->m_eWeaponType, projectile->GetPosition());
|
||||
|
||||
info->m_bInUse = false;
|
||||
CWorld::Remove(projectile);
|
||||
delete projectile;
|
||||
}
|
||||
|
||||
void
|
||||
CProjectileInfo::RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos)
|
||||
{
|
||||
switch (weaponType)
|
||||
{
|
||||
case WEAPONTYPE_GRENADE:
|
||||
CExplosion::AddExplosion(nil, entity, EXPLOSION_GRENADE, pos, 0);
|
||||
break;
|
||||
case WEAPONTYPE_MOLOTOV:
|
||||
CExplosion::AddExplosion(nil, entity, EXPLOSION_MOLOTOV, pos, 0);
|
||||
break;
|
||||
case WEAPONTYPE_ROCKETLAUNCHER:
|
||||
CExplosion::AddExplosion(nil, entity, EXPLOSION_ROCKET, pos, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CProjectileInfo::Update()
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(gaProjectileInfo); i++) {
|
||||
if (!gaProjectileInfo[i].m_bInUse) continue;
|
||||
|
||||
CPed *ped = (CPed*)gaProjectileInfo[i].m_pSource;
|
||||
if (ped != nil && ped->m_type == ENTITY_TYPE_PED && !ped->IsPointerValid())
|
||||
gaProjectileInfo[i].m_pSource = nil;
|
||||
|
||||
if (ms_apProjectile[i] == nil) {
|
||||
gaProjectileInfo[i].m_bInUse = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
|
||||
CParticle::AddParticle(PARTICLE_SMOKE, ms_apProjectile[i]->GetPosition(), CVector(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
if (CTimer::GetTimeInMilliseconds() <= gaProjectileInfo[i].m_nExplosionTime) {
|
||||
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
|
||||
CVector pos = ms_apProjectile[i]->GetPosition();
|
||||
CWorld::pIgnoreEntity = ms_apProjectile[i];
|
||||
if (ms_apProjectile[i]->bHasCollided
|
||||
|| !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false)
|
||||
|| gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) {
|
||||
RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
|
||||
#ifdef FIX_BUGS
|
||||
ms_apProjectile[i] = nil;
|
||||
#endif
|
||||
}
|
||||
CWorld::pIgnoreEntity = nil;
|
||||
} else if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_MOLOTOV) {
|
||||
CVector pos = ms_apProjectile[i]->GetPosition();
|
||||
CWorld::pIgnoreEntity = ms_apProjectile[i];
|
||||
|
||||
if (gaProjectileInfo[i].m_pSource == nil
|
||||
|| ((gaProjectileInfo[i].m_vecPos - gaProjectileInfo[i].m_pSource->GetPosition()).MagnitudeSqr() >= 2.0f))
|
||||
{
|
||||
if (ms_apProjectile[i]->bHasCollided
|
||||
|| !CWorld::GetIsLineOfSightClear(gaProjectileInfo[i].m_vecPos, pos, true, true, true, true, false, false)
|
||||
|| gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER && (CHeli::TestRocketCollision(&pos) || CPlane::TestRocketCollision(&pos))) {
|
||||
RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
|
||||
#ifdef FIX_BUGS
|
||||
ms_apProjectile[i] = nil;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
CWorld::pIgnoreEntity = nil;
|
||||
}
|
||||
} else {
|
||||
RemoveProjectile(&gaProjectileInfo[i], ms_apProjectile[i]);
|
||||
#ifdef FIX_BUGS
|
||||
ms_apProjectile[i] = nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
gaProjectileInfo[i].m_vecPos = ms_apProjectile[i]->GetPosition();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove)
|
||||
{
|
||||
bool result = false;
|
||||
for (int i = 0; i < ARRAY_SIZE(ms_apProjectile); i++) {
|
||||
if (gaProjectileInfo[i].m_bInUse) {
|
||||
if (gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_MOLOTOV || gaProjectileInfo[i].m_eWeaponType == WEAPONTYPE_GRENADE) {
|
||||
CVector &pos = ms_apProjectile[i]->GetPosition();
|
||||
if (pos.x >= x1 && pos.x <= x2 && pos.y >= y1 && pos.y <= y2 && pos.z >= z1 && pos.z <= z2) {
|
||||
result = true;
|
||||
if (remove) {
|
||||
gaProjectileInfo[i].m_bInUse = false;
|
||||
CWorld::Remove(ms_apProjectile[i]);
|
||||
delete ms_apProjectile[i];
|
||||
#ifdef FIX_BUGS
|
||||
ms_apProjectile[i] = nil;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
CProjectileInfo::RemoveAllProjectiles()
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(ms_apProjectile); i++) {
|
||||
if (gaProjectileInfo[i].m_bInUse) {
|
||||
gaProjectileInfo[i].m_bInUse = false;
|
||||
CWorld::Remove(ms_apProjectile[i]);
|
||||
delete ms_apProjectile[i];
|
||||
#ifdef FIX_BUGS
|
||||
ms_apProjectile[i] = nil;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CProjectileInfo::RemoveIfThisIsAProjectile(CObject *object)
|
||||
{
|
||||
int i = 0;
|
||||
while (ms_apProjectile[i++] != object) {
|
||||
if (i >= ARRAY_SIZE(ms_apProjectile))
|
||||
return false;
|
||||
}
|
||||
|
||||
gaProjectileInfo[i].m_bInUse = false;
|
||||
CWorld::Remove(ms_apProjectile[i]);
|
||||
delete ms_apProjectile[i];
|
||||
ms_apProjectile[i] = nil;
|
||||
return true;
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x55ADF0, CProjectileInfo::Initialise, PATCH_JUMP);
|
||||
InjectHook(0x55AFF0, CProjectileInfo::Shutdown, PATCH_JUMP);
|
||||
InjectHook(0x55B010, CProjectileInfo::GetProjectileInfo, PATCH_JUMP);
|
||||
InjectHook(0x55B030, CProjectileInfo::AddProjectile, PATCH_JUMP);
|
||||
InjectHook(0x55B700, CProjectileInfo::RemoveProjectile, PATCH_JUMP);
|
||||
InjectHook(0x55B770, CProjectileInfo::RemoveNotAdd, PATCH_JUMP);
|
||||
InjectHook(0x55B7C0, CProjectileInfo::Update, PATCH_JUMP);
|
||||
InjectHook(0x55BA50, CProjectileInfo::IsProjectileInRange, PATCH_JUMP);
|
||||
InjectHook(0x55BB80, CProjectileInfo::RemoveAllProjectiles, PATCH_JUMP);
|
||||
InjectHook(0x55BBD0, CProjectileInfo::RemoveIfThisIsAProjectile, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
|
|
@ -10,20 +10,23 @@ class CProjectileInfo
|
|||
public:
|
||||
eWeaponType m_eWeaponType;
|
||||
CEntity* m_pSource;
|
||||
int m_nExplosionTime;
|
||||
char m_bInUse;
|
||||
char field_13;
|
||||
char field_14;
|
||||
char field_15;
|
||||
uint32 m_nExplosionTime;
|
||||
bool m_bInUse;
|
||||
CVector m_vecPos;
|
||||
|
||||
public:
|
||||
static CProjectileInfo* GetProjectileInfo(int32 id);
|
||||
static CProjectile* (&ms_apProjectile)[32];
|
||||
static CProjectile* (&ms_apProjectile)[NUM_PROJECTILES];
|
||||
|
||||
static void Initialise();
|
||||
static void Shutdown();
|
||||
static bool AddProjectile(CEntity *ped, eWeaponType weapon, CVector pos, float speed);
|
||||
static void RemoveProjectile(CProjectileInfo *info, CProjectile *projectile);
|
||||
static void RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos);
|
||||
static bool RemoveIfThisIsAProjectile(CObject *pObject);
|
||||
static void RemoveAllProjectiles(void);
|
||||
static void RemoveAllProjectiles();
|
||||
static void Update();
|
||||
static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
|
||||
};
|
||||
|
||||
extern CProjectileInfo* gaProjectileInfo;
|
||||
extern CProjectileInfo (&gaProjectileInfo)[NUM_PROJECTILES];
|
Loading…
Reference in a new issue