Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_DestructionUtility.c
Go to the documentation of this file.
1
6{
7 protected static const float SIMULATION_IMPRECISION_MULTIPLIER = 1.1;
8 protected static const int MIN_MOMENTUM_RESPONSE_INDEX = 1;
9 protected static const int MAX_MOMENTUM_RESPONSE_INDEX = 5;
10 protected static const int MIN_DESTRUCTION_RESPONSE_INDEX = 6;
11 protected static const int MAX_DESTRUCTION_RESPONSE_INDEX = 10;
12 protected static const string DAMAGE_PHASE_SIGNAL_NAME = "DamagePhase";
13
14 //------------------------------------------------------------------------------------------------
20 static float CalculateMomentum(notnull Contact contact, float ownerMass, float otherMass)
21 {
22 float dotMultiplier = vector.Dot(contact.VelocityAfter1.Normalized(), contact.VelocityBefore1.Normalized());
23 float momentumBefore = ownerMass * contact.VelocityBefore1.Length() * SIMULATION_IMPRECISION_MULTIPLIER;
24 float momentumAfter = ownerMass * contact.VelocityAfter1.Length() * dotMultiplier;
25 float momentumA = Math.AbsFloat(momentumBefore - momentumAfter);
26
27 dotMultiplier = vector.Dot(contact.VelocityAfter2.Normalized(), contact.VelocityBefore2.Normalized());
28 momentumBefore = otherMass * contact.VelocityBefore2.Length() * SIMULATION_IMPRECISION_MULTIPLIER;
29 momentumAfter = otherMass * contact.VelocityAfter2.Length() * dotMultiplier;
30 float momentumB = Math.AbsFloat(momentumBefore - momentumAfter);
31 return momentumA + momentumB;
32 }
33
34 //------------------------------------------------------------------------------------------------
36 static void SpawnDestroyObjects(notnull IEntity owner, notnull array<ref SCR_BaseSpawnable> spawnList, notnull SCR_DestructionHitInfo destructionHitInfo)
37 {
38 Physics physics = owner.GetPhysics();
39 if (!physics)
40 return;
41
42 foreach (SCR_BaseSpawnable spawnObject : spawnList)
43 {
44 spawnObject.Spawn(owner, physics, destructionHitInfo);
45 }
46 }
47
48 //------------------------------------------------------------------------------------------------
54 static void PlaySound(notnull IEntity owner, SCR_EMaterialSoundTypeBreak materialSoundType, int numDamagePhases, int damagePhaseIndex)
55 {
56 SCR_SoundManagerModule soundManager = SCR_SoundManagerModule.GetInstance(owner.GetWorld());
57 if (!soundManager)
58 return;
59
61 if (!destructionManager)
62 return;
63
64 SCR_AudioSourceConfiguration audioSourceConfiguration = destructionManager.GetAudioSourceConfiguration();
65 if (!audioSourceConfiguration)
66 return;
67
68 // Get AudioSource
69 audioSourceConfiguration.m_sSoundEventName = SCR_SoundEvent.SOUND_MPD_ + owner.Type().EnumToString(SCR_EMaterialSoundTypeBreak, materialSoundType);
70
71 // Get center of bounding box
72 vector mins;
73 vector maxs;
74 owner.GetWorldBounds(mins, maxs);
75 vector position = vector.Lerp(mins, maxs, 0.5);
76
77 SCR_AudioSource audioSource = soundManager.CreateAudioSource(owner, audioSourceConfiguration, position);
78 if (!audioSource)
79 return;
80
81 // Set signals
82 audioSource.SetSignalValue(SCR_AudioSource.PHASES_TO_DESTROYED_PHASE_SIGNAL_NAME, numDamagePhases - damagePhaseIndex - 1);
83 audioSource.SetSignalValue(SCR_AudioSource.ENTITY_SIZE_SIGNAL_NAME, GetDestructibleSize(owner));
84
85
86 // Play sound
87 soundManager.PlayAudioSource(audioSource);
88 }
89
90 //------------------------------------------------------------------------------------------------
94 static void SetModel(notnull IEntity owner, ResourceName modelName)
95 {
96 Resource resource;
97 VObject model = GetModel(modelName, resource);
98 if (!model)
99 return;
100
101 SetModel(owner, model);
102 }
103
104 //------------------------------------------------------------------------------------------------
109 static void SetModel(notnull IEntity owner, ResourceName modelName, string remap)
110 {
111 Resource resource;
112 VObject model = GetModel(modelName, resource);
113 if (!model)
114 return;
115
116 SetModel(owner, model, remap);
117 }
118
119 //------------------------------------------------------------------------------------------------
123 static void SetModel(notnull IEntity owner, notnull VObject model)
124 {
125 owner.SetObject(model, string.Empty);
126 owner.Update();
127
128 Physics phys = owner.GetPhysics();
129 if (!phys)
130 return;
131
132 // Update physics geometries after mesh change
133 if (!phys.UpdateGeometries())
134 phys.Destroy(); // No geoms found, destroy physics
135 }
136
137 //------------------------------------------------------------------------------------------------
141 static void SetModel(notnull IEntity owner, notnull VObject model, string remap)
142 {
143 owner.SetObject(model, remap);
144 owner.Update();
145
146 Physics phys = owner.GetPhysics();
147 if (!phys)
148 return;
149
150 // Update physics geometries after mesh change
151 if (!phys.UpdateGeometries())
152 phys.Destroy(); // No geoms found, destroy physics
153 }
154
155 //------------------------------------------------------------------------------------------------
160 static VObject GetModel(ResourceName modelName, out Resource resource)
161 {
162 resource = Resource.Load(modelName);
163 if (!resource.IsValid())
164 return null;
165
166 BaseResourceObject resourceObject = resource.GetResource();
167 if (!resourceObject)
168 return null;
169
170 return resourceObject.ToVObject();
171 }
172
173 //------------------------------------------------------------------------------------------------
177 static float GetDestructibleSize(notnull IEntity owner)
178 {
179 vector mins, maxs
180 owner.GetBounds(mins, maxs);
181 return (maxs[0] - mins[0]) * (maxs[1] - mins[1]);
182 }
183
184 //------------------------------------------------------------------------------------------------
189 static void UpdateResponseIndex(notnull Physics physics, float health, float maxHealth)
190 {
191 int responseIndex = physics.GetResponseIndex();
192 if (responseIndex <= MIN_DESTRUCTION_RESPONSE_INDEX)
193 return; // Cannot go lower
194
195 if (maxHealth <= 0)
196 maxHealth = 0;
197
198 float healthPercentage = health / maxHealth;
200
201 responseIndex = Math.ClampInt(MIN_DESTRUCTION_RESPONSE_INDEX - 1 + Math.Ceil(minMaxDiff * healthPercentage), MIN_DESTRUCTION_RESPONSE_INDEX, responseIndex);
202 physics.SetResponseIndex(responseIndex);
203 }
204
205 //------------------------------------------------------------------------------------------------
208 static void RegenerateNavmeshDelayed(notnull IEntity owner)
209 {
210 if (Replication.IsClient())
211 return;
212
213 SCR_AIWorld aiWorld = SCR_AIWorld.Cast(GetGame().GetAIWorld());
214
215 if (!aiWorld)
216 return;
217
218 array<ref Tuple2<vector, vector>> areas = {};
219 array<bool> redoAreas = {};
220 aiWorld.GetNavmeshRebuildAreas(owner, areas, redoAreas); // Get area with current phase
221 GetGame().GetCallqueue().CallLater(aiWorld.RequestNavmeshRebuildAreas, 1000, false, areas, redoAreas); // Rebuild later with new phase/when owner object is destroyed
222 }
223
224 //------------------------------------------------------------------------------------------------
228 // Update DamagePhase signal on entity that has SignalsManagerComponent
229 // Used for triggering looped sounds
230 static void SetDamagePhaseSignal(notnull IEntity owner, int damagePhaseIndex = 0)
231 {
232 SignalsManagerComponent signalsManagerComponent = SignalsManagerComponent.Cast(owner.FindComponent(SignalsManagerComponent));
233 if (!signalsManagerComponent)
234 return;
235
236 // Pristine = 0, Destoyed > 0
237 signalsManagerComponent.SetSignalValue(signalsManagerComponent.AddOrFindSignal(DAMAGE_PHASE_SIGNAL_NAME), damagePhaseIndex);
238 }
239
240 //------------------------------------------------------------------------------------------------//------------------------------------------------------------------------------------------------
246 static string SanitizeRemapString(string originalRemap, string newRemap)
247 {
248 array<string> sanitizedEntries = {};
249 array<string> originalEntries = {};
250 array<string> originalSlots = {};
251
252 // Split original remap into entries
253 originalRemap.Split(SCR_StringHelper.SEMICOLON, originalEntries, true);
254
255 // Extract slots from original remap
256 foreach (string entry : originalEntries)
257 {
258 int firstQuote = entry.IndexOf(SCR_StringHelper.SINGLE_QUOTE);
259 if (firstQuote == -1)
260 continue;
261
262 string remainingStr = entry.Substring(firstQuote + 1, entry.Length() - (firstQuote + 1));
263 int secondQuote = remainingStr.IndexOf(SCR_StringHelper.SINGLE_QUOTE);
264 if (secondQuote == -1)
265 continue;
266
267 string slot = entry.Substring(firstQuote + 1, secondQuote);
268 originalSlots.Insert(slot);
269 }
270
271 // Split new remap into entries
272 array<string> newEntries = {};
273 newRemap.Split(SCR_StringHelper.SEMICOLON, newEntries, true);
274
275 // Process new remap entries
276 foreach (string entry : newEntries)
277 {
278 int firstQuote = entry.IndexOf(SCR_StringHelper.SINGLE_QUOTE);
279 if (firstQuote == -1)
280 continue;
281
282 string remainingStr = entry.Substring(firstQuote + 1, entry.Length() - (firstQuote + 1));
283 int secondQuote = remainingStr.IndexOf(SCR_StringHelper.SINGLE_QUOTE);
284 if (secondQuote == -1)
285 continue;
286
287 string slot = entry.Substring(firstQuote + 1, secondQuote);
288
289 // Only keep entries where slot exists in original remap
290 if (originalSlots.Contains(slot))
291 sanitizedEntries.Insert(entry);
292 }
293
294 // Reconstruct sanitized remap string
295 string sanitizedRemap;
296 foreach (string entry : sanitizedEntries)
297 {
298 if (!sanitizedRemap.IsEmpty())
299 sanitizedRemap += SCR_StringHelper.SEMICOLON;
300
301 sanitizedRemap += entry;
302 }
303
304 return sanitizedRemap;
305 }
306}
307
308#define ENABLE_BASE_DESTRUCTION
309enum SCR_EMaterialSoundTypeDebris
310{
332 WOOD_PLANK_LARGE
333}
334
335enum SCR_EMaterialSoundTypeBreak
336{
337 NONE,
356 BREAK_WOOD_SOLID
357}
ArmaReforgerScripted GetGame()
Definition game.c:1398
void SCR_AudioSource(SCR_AudioSourceConfiguration audioSourceConfiguration, vector mat[4])
SCR_CommunicationSoundComponentClass MORTAR
vector position
class SCR_DestructionUtility BREAK_CERAMIC
class SCR_DestructionUtility CERAMIC
class SCR_DestructionUtility GLASS
class SCR_DestructionUtility BREAK_METAL_GENERATOR
class SCR_DestructionUtility WOOD_PLANK_SMALL
class SCR_DestructionUtility BREAK_ROCK
class SCR_DestructionUtility BREAK_HAYBALE
class SCR_DestructionUtility METAL_LIGHT
class SCR_DestructionUtility METAL_HUGE_LONG
class SCR_DestructionUtility BREAK_TENT
class SCR_DestructionUtility BREAK_PLASTIC
class SCR_DestructionUtility BREAK_MATRESS
class SCR_DestructionUtility ROCK_SMALL
class SCR_DestructionUtility HAYBALE
class SCR_DestructionUtility BREAK_MOIST
class SCR_DestructionUtility ROCK
class SCR_DestructionUtility BREAK_METAL
class SCR_DestructionUtility BREAK_METAL_HUGE
class SCR_DestructionUtility BREAK_GLASS_PANE
class SCR_DestructionUtility BREAK_PIANO
class SCR_DestructionUtility PLASTIC_SOLID
class SCR_DestructionUtility BREAK_SANDBAG
class SCR_DestructionUtility BELL_SMALL
class SCR_DestructionUtility METAL_POLE
class SCR_DestructionUtility MOIST
class SCR_DestructionUtility METAL_NETFENCE
class SCR_DestructionUtility BREAK_GLASS
class SCR_DestructionUtility MATRESS
class SCR_DestructionUtility BREAK_METAL_POLE
class SCR_DestructionUtility BREAK_GROUNDRADAR
class SCR_DestructionUtility BREAK_METAL_NETFENCE
class SCR_DestructionUtility METAL_HEAVY
class SCR_DestructionUtility BREAK_WATERHYDRANT
class SCR_DestructionUtility SANDBAG
class SCR_DestructionUtility METAL_HUGE
class SCR_DestructionUtility PLASTIC_HOLLOW
class SCR_DestructionUtility METAL_HUGE_SQUARE
Definition Math.c:13
Main replication API.
Definition Replication.c:14
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
void GetNavmeshRebuildAreas(IEntity entity, out notnull array< ref Tuple2< vector, vector > > outAreas, out notnull array< bool > redoRoads)
void RequestNavmeshRebuildAreas(notnull array< ref Tuple2< vector, vector > > areas, notnull array< bool > redoRoads)
static string SanitizeRemapString(string originalRemap, string newRemap)
static void SetDamagePhaseSignal(notnull IEntity owner, int damagePhaseIndex=0)
static const int MIN_MOMENTUM_RESPONSE_INDEX
static float GetDestructibleSize(notnull IEntity owner)
static void SpawnDestroyObjects(notnull IEntity owner, notnull array< ref SCR_BaseSpawnable > spawnList, notnull SCR_DestructionHitInfo destructionHitInfo)
Spawns objects that are meant to be created when the object is destroyed (particles,...
static void SetModel(notnull IEntity owner, notnull VObject model, string remap)
static void PlaySound(notnull IEntity owner, SCR_EMaterialSoundTypeBreak materialSoundType, int numDamagePhases, int damagePhaseIndex)
static float CalculateMomentum(notnull Contact contact, float ownerMass, float otherMass)
static void UpdateResponseIndex(notnull Physics physics, float health, float maxHealth)
static void SetModel(notnull IEntity owner, ResourceName modelName)
static const float SIMULATION_IMPRECISION_MULTIPLIER
static const int MAX_MOMENTUM_RESPONSE_INDEX
static const int MAX_DESTRUCTION_RESPONSE_INDEX
static const int MIN_DESTRUCTION_RESPONSE_INDEX
static const string DAMAGE_PHASE_SIGNAL_NAME
static void RegenerateNavmeshDelayed(notnull IEntity owner)
static void SetModel(notnull IEntity owner, notnull VObject model)
static void SetModel(notnull IEntity owner, ResourceName modelName, string remap)
static VObject GetModel(ResourceName modelName, out Resource resource)
static SCR_MPDestructionManager GetInstance()
Returns the instance of the destruction manager.
SCR_AudioSourceConfiguration GetAudioSourceConfiguration()
Visual object.
Definition VObject.c:14
@ NONE
When Shape is created and not initialized yet.
Definition ShapeType.c:15