1#define ENABLE_BASE_DESTRUCTION
10[
ComponentEditorProps(
category:
"GameScripted/Destruction", description:
"Tire destruction component, for destruction and deformation of tires")]
16class SCR_DestructionTireComponent : SCR_DestructionMultiPhaseComponent
18 protected static const int MAX_BONES = 36;
24 [
Attribute(
"", UIWidgets.EditBox,
"List of phases in which the tire should handle deformation (this also means deflating)",
category:
"Tire Destruction")]
25 protected ref array<int> m_DeformPhaseIndexes;
27 [
Attribute(
"0.15", UIWidgets.Slider,
"Rate at which the tire deflates when in a tire deformation damage phase (in %/s)",
"0.01 1000 0.01",
category:
"Tire Destruction")]
28 protected float m_fDeflationRate;
30 [
Attribute(
"Tyre_", UIWidgets.EditBox,
"Name prefix (followed then by index) of the tire deformation joints",
category:
"Tire Destruction")]
31 protected string m_sTireJointNamePrefix;
33 [
Attribute(
"1", UIWidgets.CheckBox,
"If true, tire damage and destruction will affect vehicle physics (if attached to such)",
category:
"Tire Destruction")]
34 protected bool m_bAffectPhysics;
40 [
Attribute(
"1", UIWidgets.Slider,
"Ground deformation of the tire (in %)",
"0 1 0.01",
category:
"Tire Deformation Simple")]
41 protected float m_fGroundSlumpScale;
43 [
Attribute(
"1", UIWidgets.Slider,
"Radial deformation of the tire (in %)",
"0 1 0.01",
category:
"Tire Deformation Simple")]
44 protected float m_fRadiusScale;
46 [
Attribute(
"1", UIWidgets.Slider,
"Width deformation of the tire (in %)",
"0 1 0.01",
category:
"Tire Deformation Simple")]
47 protected float m_fTireWidthScale;
49 [
Attribute(
"1", UIWidgets.Slider,
"Sideward skew deformation of the tire (in %)",
"0 1 0.01",
category:
"Tire Deformation Simple")]
50 protected float m_fTireSideSkewScale;
56 [
Attribute(
"0.75", UIWidgets.Slider,
"Ground contact width scale addition (in %) - [Scaled by m_fGroundSlumpScale]",
"-2 2 0.01",
category:
"Tire Deformation Advanced")]
57 protected float m_fDeformParam_ScaleAdd_SquishWidthGround;
59 [
Attribute(
"-0.3", UIWidgets.Slider,
"Opposite to ground width scale addition (in %) - [Scaled by m_fTireWidthScale]",
"-2 2 0.01",
category:
"Tire Deformation Advanced")]
60 protected float m_fDeformParam_ScaleAdd_SquishWidthTop;
62 [
Attribute(
"0.25", UIWidgets.Slider,
"Flatten tire top offset (in m) - [Scaled by m_fRadiusScale]",
"-10 10 0.01",
category:
"Tire Deformation Advanced")]
63 protected float m_fDeformParam_Offset_FlattenTop;
65 [
Attribute(
"0.25", UIWidgets.Slider,
"Outward slump of tire on front/back of ground contact point (in m) - [Scaled by m_fGroundSlumpScale]",
"-10 10 0.01",
category:
"Tire Deformation Advanced")]
66 protected float m_fDeformParam_Offset_GroundSlump;
68 [
Attribute(
"0.1", UIWidgets.Slider,
"Outward extrusion near ground contact point (in m)",
"-10 10 0.01",
category:
"Tire Deformation Advanced")]
69 protected float m_fDeformParam_Offset_ExtrudeBottomOutward;
71 [
Attribute(
"0.35", UIWidgets.Slider,
"Upward extrusion near ground contact point (in m)",
"-10 10 0.01",
category:
"Tire Deformation Advanced")]
72 protected float m_fDeformParam_Offset_ExtrudeBottomUpward;
74 [
Attribute(
"0.1", UIWidgets.Slider,
"Downward extrusion of top opposite ground contact point (in m)",
"-10 10 0.01",
category:
"Tire Deformation Advanced")]
75 protected float m_fDeformParam_Offset_ExtrudeTopDownward;
77 [
Attribute(
"0.01", UIWidgets.Slider,
"Sideward skew extrusion all around the tire (in m) - [Scaled by m_fTireSideSkewScale]",
"-10 10 0.01",
category:
"Tire Deformation Advanced")]
78 protected float m_fDeformParam_Offset_ExtrudeSidewardSkew;
80#ifdef ENABLE_BASE_DESTRUCTION
81 protected bool m_bHandleDeformation;
82 protected float m_fInflation = 1;
83 protected float m_fWheelRadius = -1;
84 protected ref array<int> m_WheelBones = {};
85 protected ref SCR_DamagePhaseData m_InitialData;
87 protected VehicleWheeledSimulation m_VehicleWheeledSimulation;
89 protected int m_iWheelIndex = -1;
96 m_iWheelIndex = wheelIndex;
98 if (m_iWheelIndex > -1 && m_VehicleWheeledSimulation && m_iWheelIndex < m_VehicleWheeledSimulation.WheelCount())
99 m_fWheelRadius = m_VehicleWheeledSimulation.WheelGetRadius(m_iWheelIndex);
105 bool GetShouldHandleDeformation(
int damagePhase)
107 return m_DeformPhaseIndexes && m_DeformPhaseIndexes.Find(damagePhase) != -1;
113 void EnableTireDeformation(
bool enable)
115#ifdef ENABLE_DEFORMATION
116 m_bHandleDeformation = enable;
119 m_WheelBones.Clear();
120 if (!m_bHandleDeformation)
123 for (
int i = 0; i < MAX_BONES; i++)
127 m_WheelBones.Insert(boneIndex);
131 protected float groundContactPct1 = 1;
136 super.OnFrame(owner, timeSlice);
138 if (!m_bHandleDeformation)
142 if (m_VehicleWheeledSimulation && m_fWheelRadius > 0)
144 float targetWheelRadius = (0.5 + m_fInflation * 0.5) * m_fWheelRadius;
145 if (targetWheelRadius != m_VehicleWheeledSimulation.WheelGetRadius(m_iWheelIndex))
147 m_VehicleWheeledSimulation.WheelSetRadiusState(m_iWheelIndex, targetWheelRadius);
149 Physics physics = null;
155 if (physics && !physics.IsActive())
162 vector floorNorm = vector.Up;
166 m_fInflation = Math.Clamp(timeSlice * -m_fDeflationRate + m_fInflation, 0, 1);
168 float deflationPct = 1 - Math.Pow(1 - Math.Clamp((1 - m_fInflation) * 2, 0, 1), 1.5);
169 float deflationExpPct = (1 - Math.Clamp(m_fInflation * 1.7, 0, 1));
170 deflationExpPct += (1 - deflationExpPct) * deflationExpPct;
171 deflationExpPct *= deflationExpPct;
172 float deflationExpPct2 = (1 - Math.Clamp(m_fInflation * 1.1, 0, 1));
173 deflationExpPct2 += (1 - deflationExpPct2) * deflationExpPct2;
174 deflationExpPct2 *= deflationExpPct2;
175 groundContactPct1 = Math.Clamp(groundContactPct1 + (
Debug.KeyState(
KeyCode.KC_RIGHT) -
Debug.KeyState(
KeyCode.KC_LEFT)) * timeSlice, 0, 1);
176 float groundContactPct = groundContactPct1;
179 vector boneMatLocal[4];
180 int numBones = m_WheelBones.Count();
181 for (
int i = 0; i < numBones; i++)
183 int boneIndex = m_WheelBones.Get(i);
184 owner.
GetAnimation().GetBoneMatrix(boneIndex, boneMatLocal);
185 vector boneUp = boneMatLocal[2].Normalized();
186 boneUp = boneUp.Multiply3(wheelMat);
187 float boneFloorDot = Math.Clamp(floorNorm * boneUp, 0, 1);
188 float boneTopDot = 1 - boneFloorDot;
189 float tyreBottom = Math.Pow(boneFloorDot, 2);
190 float tyreTop = Math.Pow(boneTopDot, 2);
192 float widthScale = 1;
193 widthScale += tyreBottom * deflationPct * m_fDeformParam_ScaleAdd_SquishWidthGround * m_fGroundSlumpScale * groundContactPct;
194 widthScale += tyreTop * deflationExpPct * m_fDeformParam_ScaleAdd_SquishWidthTop * m_fTireWidthScale * groundContactPct;
195 widthScale += deflationExpPct * m_fDeformParam_ScaleAdd_SquishWidthTop * m_fTireWidthScale * (1 - groundContactPct);
197 float heightOffset = 0;
198 heightOffset += boneTopDot * deflationExpPct2 * m_fDeformParam_Offset_FlattenTop * m_fRadiusScale * tyreTop;
199 heightOffset += boneTopDot * deflationExpPct * m_fDeformParam_Offset_GroundSlump * m_fGroundSlumpScale * (1 - tyreTop);
200 heightOffset += Math.Sin(tyreBottom * 180 * Math.DEG2RAD) * deflationPct * -m_fDeformParam_Offset_ExtrudeBottomOutward;
202 float squishHeightOffset = 0;
203 squishHeightOffset += tyreBottom * deflationPct * m_fDeformParam_Offset_ExtrudeBottomUpward * groundContactPct;
204 squishHeightOffset += tyreTop * deflationPct * m_fDeformParam_Offset_ExtrudeTopDownward * (1 - groundContactPct);
206 int sidePct = (i % 3);
207 float sideOffset = (-1 + (float)sidePct * 2) * deflationExpPct * m_fDeformParam_Offset_ExtrudeSidewardSkew * m_fTireSideSkewScale;
209 vector localBoneMat[4];
210 Math3D.MatrixIdentity4(localBoneMat);
212 localBoneMat[0] = vector.Right * widthScale;
213 localBoneMat[3] = vector.Forward * (heightOffset + squishHeightOffset) + vector.Right * sideOffset;
215 owner.
GetAnimation().SetBoneMatrix(owner, boneIndex, localBoneMat);
222 void ReturnToInitialDamagePhase(SCR_DamagePhaseData pData)
224 if (GetDamagePhase() != 0)
227 if (GetTargetDamagePhase() != 0)
228 SetTargetDamagePhase(0);
230 ScriptCallQueue callQueue =
GetGame().GetCallqueue();
231 if (!callQueue || callQueue.GetRemainingTime(ChangeModel) > -1)
234 callQueue.CallLater(ChangeModel,
param1: pData.m_PhaseModel);
243 if (damagePhase == 0)
244 ReturnToInitialDamagePhase(m_InitialData);
246 super.GoToDamagePhase(damagePhase, delayMeshChange);
248 EnableTireDeformation(GetShouldHandleDeformation(GetDamagePhase()));
256 super.OnPostInit(owner);
260 EntityComponentPrefabData prefabData = owner.
FindComponentData(SCR_DestructionTireInitialDamageDataComponentClass);
263 SCR_DestructionTireInitialDamageDataComponentClass
data = SCR_DestructionTireInitialDamageDataComponentClass.Cast(prefabData);
265 m_InitialData =
data.InitialData;
268 EnableTireDeformation(GetShouldHandleDeformation(GetDamagePhase()));
274 m_VehicleWheeledSimulation = VehicleWheeledSimulation.Cast(parent.
FindComponent(VehicleWheeledSimulation));
ArmaReforgerScripted GetGame()
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
void GoToDamagePhase(int damagePhaseIndex, int previousDamagePhaseIndex, SCR_DestructionData destructionData, bool streamed)
Only call from OnStateChanged, otherwise you have HUGE desync.
Get all prefabs that have the spawner data
void SetWheelIndex(int index)
enum EVehicleType IEntity
proto external Managed FindComponent(typename typeName)
proto external Physics GetPhysics()
proto external Animation GetAnimation()
proto external void GetTransform(out vector mat[])
proto external IEntity GetParent()
proto external EntityComponentPrefabData FindComponentData(typename typeName)
Multi-Phase destruction phase.
IEntity GetOwner()
Owner entity of the fuel tank.
SCR_FieldOfViewSettings Attribute