diff --git a/ChaosMod/ChaosMod.vcxproj b/ChaosMod/ChaosMod.vcxproj
index c6cc7cdf9..dacb5106a 100644
--- a/ChaosMod/ChaosMod.vcxproj
+++ b/ChaosMod/ChaosMod.vcxproj
@@ -190,6 +190,7 @@
+
diff --git a/ChaosMod/Effects/db/Vehs/VehsMonterTrucks.cpp b/ChaosMod/Effects/db/Vehs/VehsMonterTrucks.cpp
new file mode 100644
index 000000000..23482bf57
--- /dev/null
+++ b/ChaosMod/Effects/db/Vehs/VehsMonterTrucks.cpp
@@ -0,0 +1,70 @@
+#include
+
+#include "Memory/Vehicle.h"
+
+struct VehicleData
+{
+ float fRaise;
+};
+
+static std::map vehiclesMap;
+static std::map vehiclesCGMap;
+
+static void OnStop()
+{
+ for (auto const &[model, data] : vehiclesMap)
+ {
+ LoadModel(model);
+ Vehicle temp = CREATE_VEHICLE(model, 0.f, 0.f, -50.f, 0.f, true, false, true);
+ FREEZE_ENTITY_POSITION(temp, true);
+
+ Memory::SetVehicleRaise(temp, data.fRaise);
+
+ DELETE_ENTITY(&temp);
+ vehiclesMap.erase(model);
+ }
+
+ for (auto const &[veh, CG] : vehiclesCGMap)
+ {
+ SET_CGOFFSET(veh, CG.x, CG.y, CG.z);
+ }
+
+ vehiclesMap.clear();
+ vehiclesCGMap.clear();
+}
+
+static void OnTick()
+{
+ for (Vehicle veh : GetAllVehs())
+ {
+ if (!DOES_ENTITY_EXIST(veh))
+ continue;
+
+ Hash vehModel = GET_ENTITY_MODEL(veh);
+ if (!vehiclesMap.contains(vehModel))
+ {
+ Memory::SetVehicleRaise(veh, 1.f);
+
+ _SET_VEHICLE_WHEELS_DEAL_DAMAGE(veh, true);
+
+ vehiclesMap.emplace(vehModel, VehicleData(0.f));
+ }
+
+ if (!vehiclesCGMap.contains(veh))
+ {
+ Vector3 ogCG = GET_CGOFFSET(veh);
+ SET_CGOFFSET(veh, ogCG.x, ogCG.y, ogCG.z - 1.2f);
+
+ vehiclesCGMap.emplace(veh, ogCG);
+ }
+ }
+}
+
+// clang-format off
+REGISTER_EFFECT(nullptr, OnStop, OnTick, EffectInfo
+ {
+ .Name = "Monster Trucks",
+ .Id = "vehs_monster_trucks",
+ .IsTimed = true
+ }
+);
diff --git a/ChaosMod/Memory/Vehicle.h b/ChaosMod/Memory/Vehicle.h
index a30ff14a9..a1252eb73 100644
--- a/ChaosMod/Memory/Vehicle.h
+++ b/ChaosMod/Memory/Vehicle.h
@@ -211,4 +211,98 @@ namespace Memory
Memory::SetVector3(vehicleMatrixAddress + 0x10, vehicleRightVec * scaleMultiplier);
Memory::SetVector3(vehicleMatrixAddress + 0x20, vehicleUpVec * scaleMultiplier);
}
+
+ inline void SetVehicleRaise(Vehicle vehicle, float height)
+ {
+ auto vehAddr = getScriptHandleBaseAddress(vehicle);
+ *reinterpret_cast(*reinterpret_cast(vehAddr + 0x938) + 0xD0) = height;
+ }
+
+ inline void SetVehicleWheelSize(Vehicle vehicle, float size)
+ {
+ auto addr = hook::get_pattern("44 0F 2F 43 48 45 8D");
+ auto vehAddr = getScriptHandleBaseAddress(vehicle);
+
+ auto drawHandlerPtrOffset = *(uint8_t *)(addr + 4);
+ auto streamRenderGfxPtrOffset = *hook::get_pattern("4C 8D 48 ? 80 E1 01", -4);
+
+ auto drawHandler = *reinterpret_cast((uint64_t)vehAddr + drawHandlerPtrOffset);
+ auto streamRenderGfx = *reinterpret_cast(drawHandler + streamRenderGfxPtrOffset);
+
+ if (streamRenderGfx == 0)
+ {
+ return;
+ }
+
+ addr = hook::get_pattern("48 89 01 B8 00 00 80 3F 66 44 89 51");
+ auto streamRenderWheelSizeOffset = *(uint8_t *)(addr + 20);
+
+ *reinterpret_cast(streamRenderGfx + streamRenderWheelSizeOffset) = size;
+ }
+
+ inline float GetVehicleWheelSize(Vehicle vehicle)
+ {
+ auto addr = hook::get_pattern("44 0F 2F 43 48 45 8D");
+ auto vehAddr = getScriptHandleBaseAddress(vehicle);
+
+ auto drawHandlerPtrOffset = *(uint8_t *)(addr + 4);
+ auto streamRenderGfxPtrOffset = *hook::get_pattern("4C 8D 48 ? 80 E1 01", -4);
+
+ auto drawHandler = *reinterpret_cast((uint64_t)vehAddr + drawHandlerPtrOffset);
+ auto streamRenderGfx = *reinterpret_cast(drawHandler + streamRenderGfxPtrOffset);
+
+ if (streamRenderGfx == 0)
+ {
+ return 0.f;
+ }
+
+ addr = hook::get_pattern("48 89 01 B8 00 00 80 3F 66 44 89 51");
+ auto streamRenderWheelSizeOffset = *(uint8_t *)(addr + 20);
+
+ return *reinterpret_cast(streamRenderGfx + streamRenderWheelSizeOffset);
+ }
+
+ inline void SetVehicleWheelWidth(Vehicle vehicle, float width)
+ {
+ auto addr = hook::get_pattern("44 0F 2F 43 48 45 8D");
+ auto vehAddr = getScriptHandleBaseAddress(vehicle);
+
+ auto drawHandlerPtrOffset = *(uint8_t *)(addr + 4);
+ auto streamRenderGfxPtrOffset = *hook::get_pattern("4C 8D 48 ? 80 E1 01", -4);
+
+ auto drawHandler = *reinterpret_cast((uint64_t)vehAddr + drawHandlerPtrOffset);
+ auto streamRenderGfx = *reinterpret_cast(drawHandler + streamRenderGfxPtrOffset);
+
+ if (streamRenderGfx == 0)
+ {
+ return;
+ }
+
+ addr = hook::get_pattern("48 89 01 B8 00 00 80 3F 66 44 89 51");
+ auto streamRenderWheelWidthOffset = *(uint32_t *)(addr + 23);
+
+ *reinterpret_cast(streamRenderGfx + streamRenderWheelWidthOffset) = width;
+ }
+
+ inline float GetVehicleWheelWidth(Vehicle vehicle)
+ {
+ auto addr = hook::get_pattern("44 0F 2F 43 48 45 8D");
+ auto vehAddr = getScriptHandleBaseAddress(vehicle);
+
+ auto drawHandlerPtrOffset = *(uint8_t *)(addr + 4);
+ auto streamRenderGfxPtrOffset = *hook::get_pattern("4C 8D 48 ? 80 E1 01", -4);
+
+ auto drawHandler = *reinterpret_cast((uint64_t)vehAddr + drawHandlerPtrOffset);
+ auto streamRenderGfx = *reinterpret_cast(drawHandler + streamRenderGfxPtrOffset);
+
+ if (streamRenderGfx == 0)
+ {
+ return 0.f;
+ }
+
+ addr = hook::get_pattern("48 89 01 B8 00 00 80 3F 66 44 89 51");
+ auto streamRenderWheelWidthOffset = *(uint32_t *)(addr + 23);
+
+ return *reinterpret_cast(streamRenderGfx + streamRenderWheelWidthOffset);
+ }
}
\ No newline at end of file