8 [
Attribute(
"100",
UIWidgets.Slider,
"Maximum drop of falling debris (in m)",
"1 500 1")]
9 float m_fLargeDebrisDropMax;
10 [
Attribute(
"0",
UIWidgets.CheckBox,
"If true, no debris particle effects and pieces will be spawned")]
12 [
Attribute(
"",
UIWidgets.ResourcePickerThumbnail,
"Model to use when the building is undamaged")]
14 [
Attribute(
"",
UIWidgets.ResourcePickerThumbnail,
"Model to use when the building is destroyed")]
16 [
Attribute(
"",
UIWidgets.EditBox,
"Model base path to use for the damaged region parts (automatically adds index to the end, eg: m_ModelDamagedPartBase00)")]
17 string m_ModelDamagedPartBase;
18 [
Attribute(
"",
UIWidgets.EditBox,
"Model base path to use for the debris in the intersection between two region parts, when visible (m_ModelRegionIntersectDebrisBase + index + m_ModelRegionIntersectDebrisPrefix + otherIndex, eg: models/structure01/house_region00_rubble01)")]
19 string m_ModelRegionIntersectDebrisBase;
20 [
Attribute(
"_rubble",
UIWidgets.EditBox,
"Prefix to add to the base path to use for the debris in the intersection between two region parts, when visible (m_ModelRegionIntersectDebrisBase + index + m_ModelRegionIntersectDebrisPrefix + otherIndex, eg: models/structure01/house_region00_rubble01)")]
21 string m_ModelRegionIntersectDebrisPrefix;
26 [
Attribute(
"",
UIWidgets.Object,
"List of region objects defining settings for each region")]
27 ref array<ref SCR_BuildingRegionSetupMulti> m_RegionSetupOverride;
30 ref array<ref SCR_BuildingLinkRegion> m_RegionLinks;
37 ref array<ref SCR_BuildingRegion> m_Regions =
new array<ref SCR_BuildingRegion>;
40 ref array<ResourceName> m_DamagedRegionModels;
42 ref array<ref SCR_BuildingResourceList> m_DamagedRegionIntersectDebrisModels;
56 return m_Regions.Count();
62 if (regionNumber >= m_Regions.Count())
65 return m_Regions.Get(regionNumber);
69 void FillDamagedModels()
71 Print(
"SCR_BuildingSetup::FillDamagedModels: Filling damaged model lists...");
73 if (!m_DamagedRegionModels)
74 m_DamagedRegionModels =
new array<ResourceName>;
75 if (!m_DamagedRegionIntersectDebrisModels)
76 m_DamagedRegionIntersectDebrisModels =
new array<ref SCR_BuildingResourceList>;
77 m_DamagedRegionModels.Clear();
78 m_DamagedRegionIntersectDebrisModels.Clear();
80 int numRegions = GetRegionNum();
81 for (
int region = 0; region < numRegions; region++)
87 if (m_ModelDamagedPartBase !=
string.Empty)
90 resPath = Workbench.GetResourceName(m_ModelDamagedPartBase +
"0" + region.ToString() +
".xob");
92 resPath = Workbench.GetResourceName(m_ModelDamagedPartBase + region.ToString() +
".xob");
94 if (!resource.IsValid())
98 m_DamagedRegionModels.Insert(resPath);
101 resList.m_aResources =
new array<ResourceName>;
104 for (
int otherRegion = 0; otherRegion < numRegions; otherRegion++)
108 if (m_ModelRegionIntersectDebrisBase !=
string.Empty)
110 if (region != otherRegion)
114 if (otherRegion < 10)
115 resPath = Workbench.GetResourceName(m_ModelRegionIntersectDebrisBase +
"0" + region.ToString() + m_ModelRegionIntersectDebrisPrefix +
"0" + otherRegion.ToString() +
".xob");
117 resPath = Workbench.GetResourceName(m_ModelRegionIntersectDebrisBase +
"0" + region.ToString() + m_ModelRegionIntersectDebrisPrefix + otherRegion.ToString() +
".xob");
121 if (otherRegion < 10)
122 resPath = Workbench.GetResourceName(m_ModelRegionIntersectDebrisBase + region.ToString() + m_ModelRegionIntersectDebrisPrefix +
"0" + otherRegion.ToString() +
".xob");
124 resPath = Workbench.GetResourceName(m_ModelRegionIntersectDebrisBase + region.ToString() + m_ModelRegionIntersectDebrisPrefix + otherRegion.ToString() +
".xob");
128 if (!resource.IsValid())
132 resList.m_aResources.Insert(resPath);
134 m_DamagedRegionIntersectDebrisModels.Insert(resList);
141 if (m_DamagedRegionModels.IsEmpty())
143 Print(
"SCR_BuildingSetup::GetDamagedRegionModel: Models not stored for config '" + m_sConfigPath +
"', building will not function correctly in built game!",
LogLevel.WARNING);
146 if (m_DamagedRegionModels.IsEmpty())
153 return m_DamagedRegionModels[region];
157 ResourceName GetRegionIntersectDebrisModel(
int region,
int otherRegion)
159 if (m_DamagedRegionIntersectDebrisModels.IsEmpty())
161 Print(
"SCR_BuildingSetup::GetRegionIntersectDebrisModel: Models not stored for config '" + m_sConfigPath +
"', building will not function correctly in built game!",
LogLevel.WARNING);
164 if (m_DamagedRegionIntersectDebrisModels.IsEmpty())
172 return resList.m_aResources[otherRegion];
176 private void ConnectStructuralRegions(
int parentIndex,
int childIndex)
181 if (!regionParent || !regionChild)
184 regionParent.AddConnectionOut(regionChild);
185 regionChild.AddConnectionIn(regionParent);
191 while (m_Regions.Count() > 0)
200 int GetBoundingRegionNumber(
vector localPos)
202 int numRegions = GetRegionNum();
203 for (
int i = 0; i < numRegions; i++)
206 vector mins = regionStruct.GetRegionPos() + regionStruct.GetRegionSize() * -0.5;
207 vector maxs = regionStruct.GetRegionPos() + regionStruct.GetRegionSize() * 0.5;
208 if (
SCR_Global.IntersectBoxPoint(localPos, mins, maxs))
209 return regionStruct.GetRegionIndex();
216 void CalculateRegionCentersAndSize(
GenericEntity buildingMdl)
221 if (resource.IsValid())
223 asset = resource.GetResource().ToVObject();
224 buildingMdl.SetObject(asset,
"");
225 buildingMdl.
GetBounds(m_vBuildingMins, m_vBuildingMaxs);
228 int numRegions = GetRegionNum();
229 for (
int i = 0; i < numRegions; i++)
232 resource =
Resource.Load(GetDamagedRegionModel(i));
233 if (resource.GetResource())
235 asset = resource.GetResource().ToVObject();
238 buildingMdl.SetObject(asset,
"");
246 regionStruct.SetRegionPos((maxs - mins) * 0.5 + mins);
247 regionStruct.SetRegionSize(maxs - mins);
253 Print(
"BUILDING_SETUP::CalculateRegionCentersAndSize(): Failed to load model path " + GetDamagedRegionModel(i));
260 void SetNoDebrisFX(
bool noDebrisFX)
262 m_bNoDebrisFX = noDebrisFX;
266 void GetDebrisRegionMatrix(
IEntity buildingEnt,
int regionNumber, out
vector fxMat[4])
270 fxMat[3] = buildingEnt.
CoordToParent(regionStruct.GetRegionPos());
275 void SpawnDebrisForRegion(
IEntity buildingEnt,
int region,
vector baseLinVel,
vector baseAngVel)
285 GetDebrisRegionMatrix(buildingEnt, region, fxMat);
292 if (!regionStruct.GetDestructFX(ptcPath, sndPath, pfbPath))
298 spawnParams.Transform[3] = fxMat[3];
299 spawnParams.UseFrameEvent =
true;
308 if (resource.IsValid())
316 const float radius = 1.5;
318 for (
int i = 0; i < num; i++)
321 Math3D.AnglesToMatrix(
Vector(
Math.RandomFloat(-180, 180),
Math.RandomFloat(-90, 90),
Math.RandomFloat(-180, 180)), debrisMat);
322 debrisMat[3] = debrisMat[0] *
Math.RandomFloat(-radius, radius) + debrisMat[1] *
Math.RandomFloat(-radius, radius) + debrisMat[2] *
Math.RandomFloat(-radius, radius) + fxMat[3];
324 float rndScale =
Math.RandomFloat(0.8, 1.5) * 0.5;
325 debrisMat[0] = debrisMat[0] * rndScale;
326 debrisMat[1] = debrisMat[1] * rndScale;
327 debrisMat[2] = debrisMat[2] * rndScale;
331 float debrisLifetime;
336 if (
Math.RandomFloat01() < 0.4)
338 if (
Math.RandomFloat01() < 0.1)
340 debrisPath =
"{1121FA3793FC3796}Assets/Tests/A2OA/Debris/debris_K_03.xob";
342 debrisLifetime =
Math.RandomFloat(5, 10);
344 debrisSpeed =
Math.RandomFloat(2, 10);
347 else if (
Math.RandomFloat01() < 0.25)
349 debrisPath =
"{16E60066F57A8D55}Assets/Tests/A2OA/Debris/debris_K_04.xob";
351 debrisLifetime =
Math.RandomFloat(8, 12);
353 debrisSpeed =
Math.RandomFloat(2, 7);
356 else if (
Math.RandomFloat01() < 0.4)
358 debrisPath =
"{61EC68EE01D86225}Assets/Tests/A2OA/Debris/debris_K_05.xob";
360 debrisLifetime =
Math.RandomFloat(5, 10);
362 debrisSpeed =
Math.RandomFloat(5, 15);
365 else if (
Math.RandomFloat01() < 0.4)
367 debrisPath =
"{F8F2D1771C3F53B5}Assets/Tests/A2OA/Debris/debris_K_06.xob";
369 debrisLifetime =
Math.RandomFloat(5, 10);
371 debrisSpeed =
Math.RandomFloat(5, 15);
376 debrisPath =
"{F77D25D5D1322633}Assets/Tests/A2OA/Debris/debris_K_08.xob";
378 debrisLifetime =
Math.RandomFloat(10, 14);
380 debrisSpeed =
Math.RandomFloat(3, 8);
386 if (
Math.RandomFloat01() < 0.4)
388 debrisPath =
"{FF352B267AB9E976}Assets/Tests/A2OA/Debris/debris_K_01.xob";
390 debrisLifetime =
Math.RandomFloat(5, 10);
392 debrisSpeed =
Math.RandomFloat(2, 8);
395 else if (
Math.RandomFloat01() < 0.5)
397 debrisPath =
"{662B92BF675ED8E6}Assets/Tests/A2OA/Debris/debris_K_02.xob";
399 debrisLifetime =
Math.RandomFloat(8, 12);
401 debrisSpeed =
Math.RandomFloat(1, 5);
406 debrisPath =
"{8FF8B9FFE89DBCC5}Assets/Tests/A2OA/Debris/debris_K_07.xob";
408 debrisLifetime =
Math.RandomFloat(10, 14);
410 debrisSpeed =
Math.RandomFloat(1, 5);
416 rndLinVel = rndLinVel.Normalized() * debrisSpeed + baseLinVel;
417 vector rndAngVel =
Vector(
Math.RandomFloat(-1, 1),
Math.RandomFloat(-1, 1),
Math.RandomFloat(-1, 1)) *
Math.RandomFloat(90, 720) + baseAngVel;
418#ifdef ENABLE_BASE_DESTRUCTION
419 SCR_DebrisSmallEntity.SpawnDebris(buildingEnt.
GetWorld(), debrisMat, debrisPath, debrisMass, debrisLifetime, debrisMaxDist, debrisPriority, rndLinVel, rndAngVel);
428 for (
int i = 0; i < m_iNumRegions; i++)
431 regionStruct.SetRegionIndex(i);
432 m_Regions.Insert(regionStruct);
435 if (m_RegionSetupDefaults)
437 regionStruct.SetMaxHealth(m_RegionSetupDefaults.m_MaxHealth);
438 regionStruct.SetStructuralSupportPercentage(m_RegionSetupDefaults.m_StructuralSupportPct);
439 regionStruct.SetDestructFX(m_RegionSetupDefaults.m_DestructFX_PTC, m_RegionSetupDefaults.m_DestructFX_SND, m_RegionSetupDefaults.m_DestructFX_PFB);
444 int cnt = m_RegionSetupOverride.Count();
445 for (
int i = 0; i < cnt; i++)
448 int forRegionNum = setupMulti.m_aIndexes.Count();
449 for (
int n = 0; n < forRegionNum; n++)
451 int rIndex = setupMulti.m_aIndexes.Get(n);
452 if (rIndex < 0 || rIndex >= m_iNumRegions)
458 regionStruct.SetMaxHealth(setupMulti.m_MaxHealth);
459 regionStruct.SetStructuralSupportPercentage(setupMulti.m_StructuralSupportPct);
460 regionStruct.SetDestructFX(setupMulti.m_DestructFX_PTC, setupMulti.m_DestructFX_SND, setupMulti.m_DestructFX_PFB);
468 CalculateRegionCentersAndSize(buildingMdl);
477 cnt = m_Regions.Count();
478 for (
int i = 0; i < cnt; i++)
481 rgn.SetRegionIndex(i);
484 cnt = m_RegionLinks.Count();
485 for (
int i = 0; i < cnt; i++)
488 int chldCnt = link.m_aChildren.Count();
489 for (
int n = 0; n < chldCnt; n++)
491 ConnectStructuralRegions(link.m_iParent, link.m_aChildren.Get(n));