diff --git a/MM2Hook.vcxproj b/MM2Hook.vcxproj
index efffb327..91bdfcc2 100644
--- a/MM2Hook.vcxproj
+++ b/MM2Hook.vcxproj
@@ -820,6 +820,7 @@
+
diff --git a/MM2Hook.vcxproj.filters b/MM2Hook.vcxproj.filters
index 62c6950f..934e6dc4 100644
--- a/MM2Hook.vcxproj.filters
+++ b/MM2Hook.vcxproj.filters
@@ -2797,6 +2797,8 @@
Source Files\modules\node
+
+ Source Files\modules\effects
Source Files\modules\vehicle
diff --git a/mm2hook.ini b/mm2hook.ini
index ecb5336b..75ed426a 100644
--- a/mm2hook.ini
+++ b/mm2hook.ini
@@ -23,6 +23,7 @@ UseModsFolder=1 ; Enable use of the mods folder for overriding the
MaximumCopsLimit=3 ; Limits the number of cops pursuing the player. 3 = Default, 0 = Unlimited.
Ragdolls=1 ; Enable collision with pedestrians, with ragdoll physics like Midnight Club: Street Racing.
3DDamage=1 ; Enable 3D damage on supported mods like Midnight Club: Street Racing.
+3DDynamicDamage=0 ; Enable switching 3D damage type from specific to dynamic on all vehicles when 3D damage is enabled.
3DShadows=0 ; Enable 3D shadows on player vehicles, opponent vehicles, traffic, and props
DynamicParkedCarDensity=1 ; Allows the traffic density slider to also control how many parked cars you see in Cruise mode. No traffic = no parked cars.
OpponentsUseAllColors=0 ; Allow opponents to use more than their default four colors
@@ -36,6 +37,9 @@ HornSirenThreshold=0.15 ; Threshold in seconds for how long the horn butto
ExplosionSound=1 ; Enables explosion sound effect for player's emergency vehicles if they're damaged out with activated siren, it also turns off the engine for all cars if they're destroyed.
ReflectionsOnBreakables=1 ; Enables reflections on breakable parts, such as mirrors.
ReflectionsOnCarParts=0 ; Enables reflections on car parts such as wheels and fenders. Note that addon cars will have shiny tires with this enabled if they are not set up correctly.
+ReflectionsOnDamagedParts=0 ; Enables reflections on damaged parts of the vehicle when MM1 damage is enabled.
+MM1StyleDamage=1 ; Modifies the way damage textures are applied to vehicles, in a way that resembles how Midtown Madness 1 did it.
+MM1StyleFlipOver=0 ; Modifies the way the car flips over itself in a way that resembles how Midtown Madness 1 did it.
MM1StyleTransmission=0 ; Improves transmission physics with more realistic behavior.
MM1StyleAutoReverse=0 ; Improves auto reverse system with behavior resembling Midtown Madness 1.
EnableHudArrowStyles=1 ; Enables the unused alternative style hud arrows for Blitz and Crash Course game modes.
@@ -44,8 +48,6 @@ EscapeDeepWater=1 ; Enables a new check which allows you to continue
ResetToNearestLocation=0 ; Resets you to the nearest valid location if you fall into deep water.
PhysicalEngineDamage=0 ; Damage affects engine torque when the engine spews smoke and that means the vehicle will have less acceleration and less top speed.
EnableMouseBar=0 ; Enables showing up the mouse bar for all input devices, this style is similar to the steering bar in Gran Turismo games.
-MM1StyleFlipOver=0 ; Modifies the way the car flips over itself in a way that resembles how Midtown Madness 1 did it.
-MM1StyleDamage=1 ; Modifies the way damage textures are applied to vehicles, in a way that resembles how Midtown Madness 1 did it.
UseRichPresence=1 ; Broadcast your current game mode, city, and vehicle on your Discord profile.
EnableLua=1 ; Enable the Lua script system. Always disabled in multiplayer.
diff --git a/src/handlers/feature_handlers/vehCarModelFeatureHandler.cpp b/src/handlers/feature_handlers/vehCarModelFeatureHandler.cpp
index 12ee1e6f..6298f13d 100644
--- a/src/handlers/feature_handlers/vehCarModelFeatureHandler.cpp
+++ b/src/handlers/feature_handlers/vehCarModelFeatureHandler.cpp
@@ -5,6 +5,7 @@ using namespace MM2;
static ConfigValue cfgMm1StyleTransmission("MM1StyleTransmission", false);
static ConfigValue cfgMm1StyleDamage("MM1StyleDamage", true);
static ConfigValue cfgEnable3DDamage("3DDamage", true);
+static ConfigValue cfgEnable3DDynamicDamage("3DDynamicDamage", false);
static ConfigValue cfgCarShadows("3DShadows", false);
/*
@@ -48,7 +49,7 @@ void vehCarModelFeatureHandler::ApplyImpact(vehDamageImpactInfo* a1)
auto damage3d = damage->GetCar()->GetModel()->GetDamage3D();
if (damage3d)
{
- damage3d->Impact(a1->LocalPosition);
+ damage3d->Impact(a1->LocalPosition, vehCarModel::Enable3DDynamicDamage);
}
auto mm1Damage = damage->GetCar()->GetModel()->GetMM1Damage();
@@ -144,6 +145,7 @@ void vehCarModelFeatureHandler::Install() {
ConfigValue cfgEnableSpinningWheels("EnableSpinningWheels", true);
ConfigValue cfgPartReflections("ReflectionsOnCarParts", false);
+ ConfigValue cfgDamageReflections("ReflectionsOnDamagedParts", false);
ConfigValue cfgHeadlightFlashing("EnableHeadlightFlashing", true);
ConfigValue cfgNfsMwStyleTotaledCar("NFSMWStyleTotaledCar", false);
ConfigValue cfgBreakableRenderTweak("BreakableRenderTweak", false);
@@ -162,12 +164,14 @@ void vehCarModelFeatureHandler::Install() {
vehCarModel::PartReflections = cfgPartReflections.Get();
vehCarModel::WheelReflections = vehCarModel::PartReflections;
+ vehCarModel::DamageReflections = cfgDamageReflections.Get();
vehCarModel::mm1StyleTransmission = cfgMm1StyleTransmission.Get();
vehCarModel::mm1StyleDamage = cfgMm1StyleDamage.Get();
vehCarModel::breakableRenderTweak = cfgBreakableRenderTweak.Get();
vehCarModel::Enable3DDamage = cfgEnable3DDamage.Get();
+ vehCarModel::Enable3DDynamicDamage = cfgEnable3DDynamicDamage.Get();
vehCarModel::Enable3DShadows = cfgCarShadows.Get();
}
diff --git a/src/mm2_vehicle.cpp b/src/mm2_vehicle.cpp
index adfd4951..dd5c7ccd 100644
--- a/src/mm2_vehicle.cpp
+++ b/src/mm2_vehicle.cpp
@@ -14,6 +14,7 @@ bool vehCarModel::EnableHeadlightFlashing = true;
bool vehCarModel::MWStyleTotaledCar = false;
bool vehCarModel::PartReflections = false;
bool vehCarModel::WheelReflections = false;
+bool vehCarModel::DamageReflections = false;
int vehCarModel::SirenType = 0;
int vehCarModel::HeadlightType = 0;
float vehCarModel::SirenCycle = 0.25f;
@@ -29,6 +30,7 @@ bool vehCarModel::mm1StyleDamage = true;
bool vehCarModel::breakableRenderTweak = false;
bool vehCarModel::Enable3DDamage = true;
+bool vehCarModel::Enable3DDynamicDamage = false;
bool vehCarModel::Enable3DShadows = true;
/*
diff --git a/src/modules/effects/damage3d.cpp b/src/modules/effects/damage3d.cpp
new file mode 100644
index 00000000..30416188
--- /dev/null
+++ b/src/modules/effects/damage3d.cpp
@@ -0,0 +1,274 @@
+#include "damage3d.h"
+
+namespace MM2
+{
+ fxDamage3D::fxDamage3D()
+ {
+ m_DamageRadius = 0.25f;
+ }
+
+ fxDamage3D::~fxDamage3D()
+ {
+ delete[] m_VertDeformAmount;
+ delete[] m_PacketMatchesVertCount;
+
+ if (m_EnableMM1Damage)
+ delete[] m_VertDeformPosition;
+ }
+
+ void fxDamage3D::Init(modStatic* bodyModel, modStatic* damageModel, bool mm1Damage)
+ {
+ m_BodyModel = bodyModel;
+ m_DamageModel = damageModel;
+ m_DeformModel = bodyModel->Clone();
+ m_DeformDamageModel = bodyModel->Clone();
+
+ int bodyPacketCount = 0;
+ int bodyVertCount = 0;
+ for (int i = 0; i < bodyModel->GetPacketCount(); i++)
+ {
+ auto packet = bodyModel->GetPacket(i);
+ while (packet)
+ {
+ bodyVertCount += packet->GetAdjunctCount();
+ bodyPacketCount++;
+ packet = packet->GetNext();
+ }
+ }
+
+ m_VertDeformAmount = new float[bodyVertCount];
+ m_PacketMatchesVertCount = new bool[bodyPacketCount];
+
+ int currentPacket = 0;
+ for (int i = 0; i < bodyModel->GetPacketCount(); i++)
+ {
+ if (i >= damageModel->GetPacketCount()) break;
+
+ auto bodyPacket = bodyModel->GetPacket(i);
+ auto damagePacket = damageModel->GetPacket(i);
+
+ while (bodyPacket && damagePacket)
+ {
+ m_PacketMatchesVertCount[currentPacket] = (bodyPacket->GetAdjunctCount() == damagePacket->GetAdjunctCount());
+ bodyPacket = bodyPacket->GetNext();
+ damagePacket = damagePacket->GetNext();
+ currentPacket++;
+ }
+ }
+
+ m_EnableMM1Damage = mm1Damage;
+
+ if (mm1Damage)
+ {
+ m_VertDeformPosition = new Vector3[bodyVertCount];
+
+ int currentVertex = 0;
+ for (int i = 0; i < bodyModel->GetPacketCount(); i++)
+ {
+ auto bodyPacket = bodyModel->GetPacket(i);
+ while (bodyPacket)
+ {
+ bodyPacket->DoLock();
+
+ for (unsigned int j = 0; j < bodyPacket->GetAdjunctCount(); j++)
+ {
+ bodyPacket->GetPosition(m_VertDeformPosition[currentVertex], j);
+ currentVertex++;
+ }
+
+ bodyPacket->DoUnlock();
+ bodyPacket = bodyPacket->GetNext();
+ }
+ }
+ }
+
+ SetNoDamage();
+ }
+
+ void fxDamage3D::SetNoDamage()
+ {
+ int currentVertex = 0;
+
+ for (int i = 0; i < m_DeformModel->GetPacketCount(); i++)
+ {
+ if (i >= m_BodyModel->GetPacketCount()) break;
+
+ auto deformDamagePacket = m_DeformDamageModel->GetPacket(i);
+ auto deformPacket = m_DeformModel->GetPacket(i);
+ auto bodyPacket = m_BodyModel->GetPacket(i);
+
+ while (bodyPacket && deformPacket && deformDamagePacket)
+ {
+ bodyPacket->DoLock(); deformPacket->DoLock(); deformDamagePacket->DoLock();
+
+ for (unsigned int j = 0; j < bodyPacket->GetAdjunctCount() && j < deformPacket->GetAdjunctCount(); j++)
+ {
+ Vector3 position = Vector3::ORIGIN;
+ bodyPacket->GetPosition(position, j);
+ deformPacket->SetPosition(position, j);
+ deformDamagePacket->SetPosition(position, j);
+ m_VertDeformAmount[currentVertex] = 0.0f;
+ currentVertex++;
+ }
+
+ if (m_EnableMM1Damage)
+ {
+ for (unsigned int j = 0; j < deformPacket->GetTriangleCount() / 3; j++)
+ {
+ int tri[3];
+ bodyPacket->GetTri(tri, j);
+ deformPacket->SetTri(tri[0], tri[1], tri[2], j);
+ deformDamagePacket->SetTri(0, 0, 0, j);
+ }
+ }
+
+ bodyPacket->DoUnlock(); deformPacket->DoUnlock(); deformDamagePacket->DoUnlock();
+
+ bodyPacket = bodyPacket->GetNext();
+ deformPacket = deformPacket->GetNext();
+ deformDamagePacket = deformDamagePacket->GetNext();
+ }
+ }
+ }
+
+ void fxDamage3D::SetFullDamage()
+ {
+ int currentVertex = 0;
+
+ for (int i = 0; i < m_DeformModel->GetPacketCount(); i++)
+ {
+ if (i >= m_DamageModel->GetPacketCount()) break;
+
+ auto deformDamagePacket = m_DeformDamageModel->GetPacket(i);
+ auto deformPacket = m_DeformModel->GetPacket(i);
+ auto damagePacket = m_DamageModel->GetPacket(i);
+
+ while (damagePacket && deformPacket && deformDamagePacket)
+ {
+ damagePacket->DoLock(); deformPacket->DoLock(); deformDamagePacket->DoLock();
+
+ for (unsigned int j = 0; j < damagePacket->GetAdjunctCount() && j < deformPacket->GetAdjunctCount(); j++)
+ {
+ Vector3 position = Vector3::ORIGIN;
+ damagePacket->GetPosition(position, j);
+ deformPacket->SetPosition(position, j);
+ deformDamagePacket->SetPosition(position, j);
+ m_VertDeformAmount[currentVertex] = 1.0f;
+ currentVertex++;
+ }
+
+ if (m_EnableMM1Damage)
+ {
+ for (unsigned int j = 0; j < deformDamagePacket->GetTriangleCount() / 3; j++)
+ {
+ int tri[3];
+ damagePacket->GetTri(tri, j);
+ deformDamagePacket->SetTri(tri[0], tri[1], tri[2], j);
+ deformPacket->SetTri(0, 0, 0, j);
+ }
+ }
+
+ damagePacket->DoUnlock(); deformPacket->DoUnlock(); deformDamagePacket->DoUnlock();
+
+ damagePacket = damagePacket->GetNext();
+ deformPacket = deformPacket->GetNext();
+ deformDamagePacket = deformDamagePacket->GetNext();
+ }
+ }
+ }
+
+ void fxDamage3D::Impact(Vector3& localImpactPosition, bool dynamicDamage)
+ {
+ int currentVertex = 0;
+ int currentVertex2 = 0;
+ int currentPacket = 0;
+
+ for (int i = 0; i < m_DeformModel->GetPacketCount(); i++)
+ {
+ if (i >= m_DamageModel->GetPacketCount()) break;
+
+ auto deformDamagePacket = m_DeformDamageModel->GetPacket(i);
+ auto deformPacket = m_DeformModel->GetPacket(i);
+ auto damagePacket = m_DamageModel->GetPacket(i);
+ auto bodyPacket = m_DamageModel->GetPacket(i);
+
+ while (damagePacket && deformPacket && bodyPacket && deformDamagePacket)
+ {
+ if (m_PacketMatchesVertCount[currentPacket]) {
+ damagePacket->DoLock(); deformPacket->DoLock(); bodyPacket->DoLock(); deformDamagePacket->DoLock();
+
+ for (unsigned int j = 0; j < damagePacket->GetAdjunctCount() && j < deformPacket->GetAdjunctCount(); j++)
+ {
+ Vector3 position = Vector3::ORIGIN;
+ bodyPacket->GetPosition(position, j);
+
+ float squareDistance = (localImpactPosition - position).Mag2();
+ if (squareDistance < m_DamageRadius)
+ {
+ Vector3 fullDamagePosition = Vector3::ORIGIN;
+ Vector3 bodyModelPosition = Vector3::ORIGIN;
+
+ damagePacket->GetPosition(fullDamagePosition, j);
+ bodyPacket->GetPosition(bodyModelPosition, j);
+
+ float deformAmount = 1.0f - (squareDistance / m_DamageRadius);
+ if (deformAmount < m_VertDeformAmount[currentVertex])
+ {
+ deformAmount = m_VertDeformAmount[currentVertex];
+ }
+ if (!dynamicDamage)
+ m_VertDeformAmount[currentVertex] = deformAmount;
+
+ Vector3 deformedPosition = Vector3::ORIGIN;
+ dynamicDamage ?
+ deformedPosition.Lerp(deformAmount, bodyModelPosition, fullDamagePosition - localImpactPosition * 0.1f) :
+ deformedPosition.Lerp(deformAmount, bodyModelPosition, fullDamagePosition);
+ deformPacket->SetPosition(deformedPosition, j);
+ deformDamagePacket->SetPosition(deformedPosition, j);
+
+ currentVertex++;
+ }
+ }
+
+ if (m_EnableMM1Damage)
+ {
+ for (unsigned int j = 0; j < deformDamagePacket->GetTriangleCount() / 3; j++)
+ {
+ int tri[3];
+ bodyPacket->GetTri(tri, j);
+
+ float dist0 = (m_VertDeformPosition[currentVertex2 + tri[0]] - localImpactPosition).Mag2();
+ float dist1 = (m_VertDeformPosition[currentVertex2 + tri[1]] - localImpactPosition).Mag2();
+ float dist2 = (m_VertDeformPosition[currentVertex2 + tri[2]] - localImpactPosition).Mag2();
+
+ if (dist0 < m_DamageRadius || dist1 < m_DamageRadius || dist2 < m_DamageRadius)
+ {
+ deformDamagePacket->SetTri(tri[0], tri[1], tri[2], j);
+ deformPacket->SetTri(0, 0, 0, j);
+ }
+ }
+ }
+
+ damagePacket->DoUnlock(); deformPacket->DoUnlock(); bodyPacket->DoUnlock(); deformDamagePacket->DoUnlock();
+ }
+ currentVertex2 += deformDamagePacket->GetAdjunctCount();
+
+ damagePacket = damagePacket->GetNext();
+ deformPacket = deformPacket->GetNext();
+ bodyPacket = bodyPacket->GetNext();
+ deformDamagePacket = deformDamagePacket->GetNext();
+ currentPacket++;
+ }
+ }
+ }
+
+ modStatic* fxDamage3D::GetDeformModel()
+ {
+ return m_DeformModel;
+ }
+
+ modStatic* fxDamage3D::GetDeformDamageModel()
+ {
+ return m_DeformDamageModel;
+ }
+}
\ No newline at end of file
diff --git a/src/modules/effects/damage3d.h b/src/modules/effects/damage3d.h
index f2904b2f..687a112c 100644
--- a/src/modules/effects/damage3d.h
+++ b/src/modules/effects/damage3d.h
@@ -17,188 +17,29 @@ namespace MM2
modStatic* m_BodyModel;
modStatic* m_DamageModel;
modStatic* m_DeformModel;
+ modStatic* m_DeformDamageModel;
+ Vector3* m_VertDeformPosition;
float* m_VertDeformAmount;
float m_DamageRadius;
bool* m_PacketMatchesVertCount;
+ bool m_EnableMM1Damage;
public:
ANGEL_ALLOCATOR
- fxDamage3D()
- {
- m_DamageRadius = 0.9f;
- }
+ fxDamage3D();
- virtual ~fxDamage3D()
- {
- delete[] m_VertDeformAmount;
- delete[] m_PacketMatchesVertCount;
- }
+ virtual ~fxDamage3D();
- void Init(modStatic* bodyModel, modStatic* damageModel)
- {
- m_BodyModel = bodyModel;
- m_DamageModel = damageModel;
- m_DeformModel = bodyModel->Clone();
+ void Init(modStatic* bodyModel, modStatic* damageModel, bool mm1Damage);
- int bodyPacketCount = 0;
- int bodyVertCount = 0;
- for (int i = 0; i < bodyModel->GetPacketCount(); i++)
- {
- auto packet = bodyModel->GetPacket(i);
- while (packet)
- {
- bodyVertCount += packet->GetAdjunctCount();
- bodyPacketCount++;
- packet = packet->GetNext();
- }
- }
+ void SetNoDamage();
- m_VertDeformAmount = new float[bodyVertCount];
- m_PacketMatchesVertCount = new bool[bodyPacketCount];
+ void SetFullDamage();
- int currentPacket = 0;
- for (int i = 0; i < bodyModel->GetPacketCount(); i++)
- {
- if (i >= damageModel->GetPacketCount()) break;
+ void Impact(Vector3& localImpactPosition, bool dynamicDamage);
- auto bodyPacket = bodyModel->GetPacket(i);
- auto damagePacket = damageModel->GetPacket(i);
+ modStatic* GetDeformModel();
- while (bodyPacket && damagePacket)
- {
- m_PacketMatchesVertCount[currentPacket] = (bodyPacket->GetAdjunctCount() == damagePacket->GetAdjunctCount());
- bodyPacket = bodyPacket->GetNext();
- damagePacket = damagePacket->GetNext();
- currentPacket++;
- }
- }
-
- SetNoDamage();
- }
-
- void SetNoDamage()
- {
- int currentVertex = 0;
-
- for (int i = 0; i < m_DeformModel->GetPacketCount(); i++)
- {
- if (i >= m_BodyModel->GetPacketCount()) break;
-
- auto deformPacket = m_DeformModel->GetPacket(i);
- auto bodyPacket = m_BodyModel->GetPacket(i);
-
- while (bodyPacket && deformPacket)
- {
- bodyPacket->DoLock(); deformPacket->DoLock();
-
- for (unsigned int j = 0; j < bodyPacket->GetAdjunctCount() && j < deformPacket->GetAdjunctCount(); j++)
- {
- Vector3 position = Vector3::ORIGIN;
- bodyPacket->GetPosition(position, j);
- deformPacket->SetPosition(position, j);
- m_VertDeformAmount[currentVertex] = 0.0f;
- currentVertex++;
- }
-
- bodyPacket->DoUnlock(); deformPacket->DoUnlock();
- bodyPacket = bodyPacket->GetNext();
- deformPacket = deformPacket->GetNext();
- }
- }
- }
-
- void SetFullDamage()
- {
- int currentVertex = 0;
-
- for (int i = 0; i < m_DeformModel->GetPacketCount(); i++)
- {
- if (i >= m_DamageModel->GetPacketCount()) break;
-
- auto deformPacket = m_DeformModel->GetPacket(i);
- auto damagePacket = m_DamageModel->GetPacket(i);
-
- while (damagePacket && deformPacket)
- {
- damagePacket->DoLock(); deformPacket->DoLock();
-
- for (unsigned int j = 0; j < damagePacket->GetAdjunctCount() && j < deformPacket->GetAdjunctCount(); j++)
- {
- Vector3 position = Vector3::ORIGIN;
- damagePacket->GetPosition(position, j);
- deformPacket->SetPosition(position, j);
- m_VertDeformAmount[currentVertex] = 1.0f;
- currentVertex++;
- }
-
- damagePacket->DoUnlock(); deformPacket->DoUnlock();
- damagePacket = damagePacket->GetNext();
- deformPacket = deformPacket->GetNext();
- }
- }
- }
-
- void Impact(Vector3 localImpactPosition)
- {
- int currentVertex = 0;
- int currentPacket = 0;
-
- for (int i = 0; i < m_DeformModel->GetPacketCount(); i++)
- {
- if (i >= m_DamageModel->GetPacketCount()) break;
-
- auto deformPacket = m_DeformModel->GetPacket(i);
- auto damagePacket = m_DamageModel->GetPacket(i);
- auto bodyPacket = m_DamageModel->GetPacket(i);
-
- while (damagePacket && deformPacket && bodyPacket)
- {
- if (m_PacketMatchesVertCount[currentPacket]) {
- damagePacket->DoLock(); deformPacket->DoLock(); bodyPacket->DoLock();
-
- for (unsigned int j = 0; j < damagePacket->GetAdjunctCount() && j < deformPacket->GetAdjunctCount(); j++)
- {
- Vector3 position = Vector3::ORIGIN;
- bodyPacket->GetPosition(position, j);
-
- float squareDistance = (localImpactPosition - position).Mag2();
- if (squareDistance <= m_DamageRadius)
- {
- Vector3 fullDamagePosition = Vector3::ORIGIN;
- Vector3 bodyModelPosition = Vector3::ORIGIN;
-
- damagePacket->GetPosition(fullDamagePosition, j);
- bodyPacket->GetPosition(bodyModelPosition, j);
-
- float deformAmount = 1.0f - (squareDistance / m_DamageRadius);
- if (deformAmount < m_VertDeformAmount[currentVertex])
- {
- deformAmount = m_VertDeformAmount[currentVertex];
- }
- m_VertDeformAmount[currentVertex] = deformAmount;
-
- Vector3 deformedPosition = Vector3::ORIGIN;
- deformedPosition.Lerp(deformAmount, bodyModelPosition, fullDamagePosition);
- deformPacket->SetPosition(deformedPosition, j);
-
- currentVertex++;
- }
- }
-
- damagePacket->DoUnlock(); deformPacket->DoUnlock(); bodyPacket->DoUnlock();
- }
-
- damagePacket = damagePacket->GetNext();
- deformPacket = deformPacket->GetNext();
- bodyPacket = bodyPacket->GetNext();
- currentPacket++;
- }
- }
- }
-
- modStatic* GetDeformModel()
- {
- return m_DeformModel;
- }
+ modStatic* GetDeformDamageModel();
};
}
\ No newline at end of file
diff --git a/src/modules/vehicle/carmodel.cpp b/src/modules/vehicle/carmodel.cpp
index 58bc72e8..6cf6fd48 100644
--- a/src/modules/vehicle/carmodel.cpp
+++ b/src/modules/vehicle/carmodel.cpp
@@ -598,25 +598,6 @@ namespace MM2
}
}
}
-
- //init damage3d
- if (this->damage3D != nullptr)
- {
- // delete old damage3D
- delete this->damage3D;
- this->damage3D = nullptr;
- }
-
- if (this->GetGeomIndex() != 0 && vehCarModel::Enable3DDamage)
- {
- auto bodyEntry = this->GetGeomBase(0);
- auto bodyDamageEntry = this->GetGeomBase(BODYDAMAGE_GEOM_ID);
- if (bodyEntry->GetHighLOD() != nullptr && bodyDamageEntry->GetHighLOD() != nullptr)
- {
- this->damage3D = new fxDamage3D();
- damage3D->Init(bodyEntry->GetHighLOD(), bodyDamageEntry->GetHighLOD());
- }
- }
}
else
{
@@ -639,6 +620,28 @@ namespace MM2
}
}
+ if (vehCarModel::Enable3DDamage)
+ {
+ //init damage3d
+ if (this->damage3D != nullptr)
+ {
+ // delete old damage3D
+ delete this->damage3D;
+ this->damage3D = nullptr;
+ }
+
+ if (this->GetGeomIndex() != 0)
+ {
+ auto bodyEntry = this->GetGeomBase(0);
+ auto bodyDamageEntry = this->GetGeomBase(BODYDAMAGE_GEOM_ID);
+ if (bodyEntry->GetHighLOD() != nullptr)
+ {
+ this->damage3D = new fxDamage3D();
+ damage3D->Init(bodyEntry->GetHighLOD(), bodyDamageEntry->GetHighLOD() != nullptr ? bodyDamageEntry->GetHighLOD() : bodyEntry->GetHighLOD(), vehCarModel::mm1StyleDamage);
+ }
+ }
+ }
+
//optimize this instance
if (hasGeometry)
lvlInstance::Optimize(this->variant);
@@ -809,13 +812,35 @@ namespace MM2
//draw the body
modStatic* bodyGeom = this->GetGeom(lod, 0);
- if (!mm1StyleDamage)
+ if (Enable3DDamage)
{
- bodyGeom = (damage3D != nullptr && lod >= 2) ? damage3D->GetDeformModel() : this->GetGeom(lod, 0);
- if (bodyGeom != nullptr)
- bodyGeom->Draw(shaders);
+ if (damage3D != nullptr)
+ {
+ bodyGeom = lod >= 2 ? damage3D->GetDeformModel() : this->GetGeom(lod, 0);
+ if (bodyGeom != nullptr)
+ bodyGeom->Draw(shaders);
+
+ if (mm1StyleDamage)
+ {
+ modStatic* bodyDamage = lod >= 2 ? damage3D->GetDeformDamageModel() : this->GetGeom(lod, 0);
+ if (bodyDamage != nullptr)
+ bodyDamage->Draw(lod >= 2 && mm1Damage != nullptr ? mm1Damage->GetDamageShaders() : shaders);
+
+ if (DamageReflections)
+ {
+ float reflectionIntensity;
+ auto reflectionMap = lvlLevel::GetSingleton()->GetEnvMap(this->GetRoomId(), this->GetPosition(), reflectionIntensity);
+ if (lod == 3 && reflectionMap != nullptr && bodyDamage != nullptr)
+ {
+ modShader::BeginEnvMap(reflectionMap, *this->carSim->GetWorldMatrix());
+ bodyDamage->DrawEnvMapped(shaders, reflectionMap, reflectionIntensity);
+ modShader::EndEnvMap();
+ }
+ }
+ }
+ }
}
- else
+ else if (mm1StyleDamage)
{
if (mm1Damage != nullptr)
{
@@ -826,8 +851,25 @@ namespace MM2
modStatic* bodyDamage = lod >= 2 ? mm1Damage->GetDamageModel() : this->GetGeom(lod, 0);
if (bodyDamage != nullptr)
bodyDamage->Draw(lod >= 2 ? mm1Damage->GetDamageShaders() : shaders);
+
+ if (DamageReflections)
+ {
+ float reflectionIntensity;
+ auto reflectionMap = lvlLevel::GetSingleton()->GetEnvMap(this->GetRoomId(), this->GetPosition(), reflectionIntensity);
+ if (lod == 3 && reflectionMap != nullptr && bodyDamage != nullptr)
+ {
+ modShader::BeginEnvMap(reflectionMap, *this->carSim->GetWorldMatrix());
+ bodyDamage->DrawEnvMapped(shaders, reflectionMap, reflectionIntensity);
+ modShader::EndEnvMap();
+ }
+ }
}
}
+ else
+ {
+ if (bodyGeom != nullptr)
+ bodyGeom->Draw(shaders);
+ }
//draw BREAK objects below the body
if (!breakableRenderTweak)
diff --git a/src/modules/vehicle/carmodel.h b/src/modules/vehicle/carmodel.h
index 89194d02..42768d11 100644
--- a/src/modules/vehicle/carmodel.h
+++ b/src/modules/vehicle/carmodel.h
@@ -126,6 +126,7 @@ namespace MM2
static float HeadlightFlashingSpeed;
static bool PartReflections;
static bool WheelReflections;
+ static bool DamageReflections;
static bool mm1StyleTransmission;
static bool mm1StyleDamage;
static bool breakableRenderTweak;
@@ -139,6 +140,7 @@ namespace MM2
//3d damage feature
static bool Enable3DDamage;
+ static bool Enable3DDynamicDamage;
private:
bool enabledElectrics[4]; //0/1 are back, 2/3 are front
vehCar* car;