1 [
EntityEditorProps(
category:
"GameScripted/Buildings", description:
"The main entity for a destructible building.", visible:
false, dynamicBox:
true)]
6 [
Attribute(
"1", UIWidgets.EditBox,
"Minimum damage above which the building switches to damaged state from the undamaged state",
"0 1000000 0.5",
category:
"Destruction Building")]
7 protected float m_fMinUndamagedThreshold;
10 [
Attribute(
"0", UIWidgets.CheckBox,
"Check to update various data in the config (must be defined)",
category:
"EDITOR: Destruction Building")]
11 bool m_bUpdateConfigData;
14 bool UpdateConfigData()
16 return m_bUpdateConfigData;
27 float GetMinUndamagedThreshold()
29 return m_fMinUndamagedThreshold;
49 [
Attribute(
"", UIWidgets.ResourceNamePicker,
"The building configuration object to use for this building",
"conf",
category:
"Destruction Building")]
50 protected ResourceName m_BuildingConfig;
62 void SetBuildingId(
int id)
67 #ifdef ENABLE_BUILDING_DESTRUCTION
69 [
Attribute(
"0", UIWidgets.CheckBox,
"Check to update various data in the config (must be defined)",
category:
"EDITOR: Destruction Building")]
70 bool UpdateConfigData;
73 override bool _WB_OnKeyChanged(BaseContainer src,
string key, BaseContainerList ownerContainers, IEntity parent)
75 WorldEditorAPI api = _WB_GetEditorAPI();
76 if (!api || api.UndoOrRedoIsRestoring())
79 if (key !=
"UpdateConfigData")
82 IEntitySource entSrc = src.ToEntitySource();
83 entSrc.ClearVariable(
"UpdateConfigData");
84 BaseContainerTools.WriteToInstance(
this, entSrc);
86 if (m_BuildingConfig ==
string.Empty)
88 Print(
"SCR_DestructibleBuildingEntity: Trying to update data in config, but config not defined!");
95 Print(
"SCR_DestructibleBuildingEntity: Trying to update data in config, but config not loaded!");
99 Print(
"SCR_DestructibleBuildingEntity: Updating data in config...");
101 m_BuildingSetup.FillDamagedModels();
103 Resource configResource = BaseContainerTools.LoadContainer(m_BuildingConfig);
104 BaseResourceObject configSource = configResource.GetResource();
105 BaseContainer configBase = configSource.ToBaseContainer();
106 configBase.Set(
"m_DamagedRegionModels", m_BuildingSetup.m_DamagedRegionModels);
107 configBase.Set(
"m_DamagedRegionIntersectDebrisModels", m_BuildingSetup.m_DamagedRegionIntersectDebrisModels);
108 if (BaseContainerTools.SaveContainer(configBase, m_BuildingConfig))
109 Print(
"SCR_DestructibleBuildingEntity: Success! Config data updated and stored.");
111 Print(
"SCR_DestructibleBuildingEntity: Failed! Config data was not successfully stored!!");
128 protected bool m_bDestroyed =
false;
134 protected ref map<int, float> m_RegionDamage =
null;
137 protected BaseWorld
m_World =
null;
144 ref array<SCR_BuildingRegionEntity> m_RegionEntities =
null;
147 static ref array<IEntity> s_aQueryPropsList =
new array<IEntity>();
152 #ifdef BUILDING_DEBUG_TEMP
154 static ref array<ref Shape> debugShapes =
new array<ref Shape>();
158 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
159 private void RPC_OnRegionDestroyed(
int regionNumber,
bool destroyed,
bool doStructuralIntegrityCheck,
bool doDamageEffects)
162 SetRegionDamage01(regionNumber, 1, doStructuralIntegrityCheck, doDamageEffects,
false);
164 SetRegionDamage01(regionNumber, 0, doStructuralIntegrityCheck, doDamageEffects,
false);
169 override bool RplLoad(ScriptBitReader reader)
172 reader.Read(undamaged, 1);
177 SetDestroyedState(
false);
182 reader.Read(destroyed, 1);
187 SetDestroyedState(
true);
192 SetDestroyedState(
false);
195 int numRegions, regionIndex;
196 reader.Read(numRegions, 16);
197 for (
int i = 0; i < numRegions; i++)
199 reader.Read(regionIndex, 16);
200 SetRegionDamage01(regionIndex, 1,
false,
false,
false);
208 override bool RplSave(ScriptBitWriter writer)
228 autoptr array<int> destroyedRegions =
new array<int>();
229 int numRegions = GetRegionsCount();
230 for (
int i = 0; i < numRegions; i++)
232 if (GetRegionDestroyed(i))
233 destroyedRegions.Insert(i);
235 numRegions = destroyedRegions.Count();
236 writer.Write(numRegions, 16);
237 for (
int i = 0; i < numRegions; i++)
239 writer.Write(destroyedRegions.Get(i), 16);
246 override void OnDamage(
float damage,
EDamageType type, IEntity pHitEntity, inout vector outMat[3], IEntity damageSource, notnull
Instigator instigator,
int colliderID,
float speed)
248 if (!m_BuildingSetup)
254 if (RplSession.Mode() == RplMode.Client)
266 if (damage < prefabData.GetMinUndamagedThreshold())
272 vector hitPos = outMat[0];
273 vector hitDir = outMat[1];
276 autoptr TraceParam param =
new TraceParam;
278 param.Start = hitPos + hitDir * -10;
279 param.End = hitPos + hitDir * 10;
280 param.Flags = TraceFlags.WORLD | TraceFlags.ENTS;
281 param.LayerMask = -1;
286 float traceDist =
m_World.TraceMove(param,
SCR_Global.FilterCallback_IgnoreNotInList);
291 hitRegion = regionEnt.GetRegionNumber();
295 if (hitRegion == -1 && m_BuildingSetup)
296 hitRegion = m_BuildingSetup.GetBoundingRegionNumber(CoordToLocal(hitPos));
303 AddRegionDamage(hitRegion, damage);
308 #ifdef BUILDING_DESTRUCTION_DEBUG
311 bool GetCameraViewIntersect()
313 if (!m_BuildingSetup)
317 GetWorld().GetCurrentCamera(camMat);
319 vector from = CoordToLocal(camMat[3]);
320 vector to = VectorToLocal(camMat[2]);
321 to = to * 1000 + from;
322 float intersect = Math3D.IntersectRayBox(from, to, m_BuildingSetup.m_vBuildingMins, m_BuildingSetup.m_vBuildingMaxs);
331 override void _WB_AfterWorldUpdate(
float timeSlice)
333 if (m_BuildingConfig !=
string.Empty)
341 override protected void EOnFrame(IEntity owner,
float timeSlice)
349 if (!m_BuildingSetup)
353 if (!GetCameraViewIntersect())
361 GetWorld().GetCurrentCamera(textMat);
362 textMat[3] =
GetOrigin() + Vector(0, m_BuildingSetup.m_vBuildingMaxs[1] + 2, 0);
365 CreateSimpleText(
"DESTROYED", textMat, 0.5, ARGB(0, 255, 0, 0), ShapeFlags.ONCE|ShapeFlags.NOZBUFFER,
null, 0.7);
366 else if (GetDamaged())
368 CreateSimpleText(
"DAMAGED", textMat, 0.5, ARGB(0, 255, 128, 0), ShapeFlags.ONCE|ShapeFlags.NOZBUFFER,
null, 0.7);
370 for (
int i = 0; i < GetRegionsCount(); i++)
372 dmgPct += GetRegionDamage01(i) / GetRegionsCount();
374 textMat[3] = textMat[1] * -0.6 + textMat[3];
375 CreateSimpleText(Math.Floor(dmgPct * 100).ToString() +
"%", textMat, 0.5, ARGB(0, 255, 128, 0), ShapeFlags.ONCE|ShapeFlags.NOZBUFFER,
null, 0.7);
378 CreateSimpleText(
"UNDAMAGED", textMat, 0.5, ARGB(0, 0, 255, 0), ShapeFlags.ONCE|ShapeFlags.NOZBUFFER,
null, 0.7);
383 void DisplayRegions()
385 if (!m_BuildingSetup)
389 GetWorld().GetCurrentCamera(textMat);
390 vector camDir = textMat[2];
391 vector camPos = textMat[3];
393 int highlightRegion = -1;
394 float highlightDist = -1;
397 for (
int i = 0; i < GetRegionsCount(); i++)
403 vector regionPos = CoordToParent(regionStruct.GetRegionPos());
405 vector intersectScreenDiff = regionPos.InvMultiply4(textMat);
406 intersectScreenDiff[2] = 0;
408 float distScale = vector.Distance(camPos, regionPos) * 0.1;
409 distScale = Math.Clamp(distScale, 0.5, 5);
411 float distToCircle = intersectScreenDiff.Length() / distScale;
412 if (distToCircle < 0.75 && (distToCircle < highlightDist || highlightDist == -1))
415 highlightDist = distToCircle;
419 for (
int i = 0; i < GetRegionsCount(); i++)
425 vector regionPos = CoordToParent(regionStruct.GetRegionPos());
427 float distScale = vector.Distance(camPos, regionPos) * 0.1;
428 distScale = Math.Clamp(distScale, 0.5, 3);
430 textMat[3] = textMat[1] * 0.05 * distScale + regionPos;
433 if (i == highlightRegion)
435 int color = ARGBF(1, 1, 1, 1);
436 CreateSimpleText(
"Region " + i.ToString(), textMat, 0.17 * distScale, color, ShapeFlags.ONCE | ShapeFlags.TRANSP | ShapeFlags.NOZBUFFER,
null, 0.7,
true, ARGB(128, 0, 0, 0));
437 textMat[3] = textMat[1] * -0.3 * distScale + textMat[3];
438 CreateSimpleText(GetRegionDamage(i).ToString() +
"/" + GetRegionMaxDamage(i).ToString(), textMat, 0.17 * distScale, color, ShapeFlags.ONCE | ShapeFlags.TRANSP | ShapeFlags.NOZBUFFER,
null, 0.7,
true, ARGB(128, 0, 0, 0));
439 CreateCircle(regionPos, textMat[2], 0.75 * distScale, ARGBF(0.25, 1, 1, 1), 24, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER | ShapeFlags.TRANSP);
440 CreateCircle(regionPos, textMat[2], ((1 - GetRegionDamage01(i)) * 0.25 + 0.75) * distScale, color, 24, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER);
441 CreateCircle(regionPos, textMat[2], distScale, ARGBF(0.25, 1, 1, 1), 24, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER | ShapeFlags.TRANSP);
445 int color = ARGBF(0.1, 1, 1 - GetRegionDamage01(i), 1 - GetRegionDamage01(i));
446 CreateCircle(regionPos, textMat[2], 0.15 * distScale, color, 24, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER | ShapeFlags.TRANSP);
447 CreateCircle(regionPos, textMat[2], 0.01 * distScale, color, 4, ShapeFlags.ONCE | ShapeFlags.NOZBUFFER | ShapeFlags.TRANSP);
448 textMat[3] = textMat[1] * 0.18 * distScale + textMat[3];
449 CreateSimpleText(i.ToString(), textMat, 0.17 * distScale, color, ShapeFlags.ONCE | ShapeFlags.TRANSP | ShapeFlags.NOZBUFFER);
453 for (
int s = 0; s < regionStruct.GetConnectionNumOut(); s++)
456 if (!suppRegionStruct)
459 int suppRegion = suppRegionStruct.GetRegionIndex();
460 vector suppRegionPos = CoordToParent(suppRegionStruct.GetRegionPos());
462 int arrowsColor = ARGBF(0.02, 1, 1, 1);
463 if (i == highlightRegion || suppRegion == highlightRegion)
464 arrowsColor = ARGB(255, 128, 128, 64);
466 int numArrows = Math.Ceil(vector.Distance(suppRegionPos, regionPos) * 5 / distScale);
469 CreateArrowLinkLines(regionPos, suppRegionPos, camDir, 0.08 * distScale, numArrows, arrowsColor, ShapeFlags.ONCE | ShapeFlags.TRANSP | ShapeFlags.NOZBUFFER);
477 protected void OnRegionDestroyed(
int region,
bool doDamageEffects)
480 if (m_RegionEntities && m_RegionEntities.Count() > region)
481 regionEnt = m_RegionEntities.Get(region);
488 buildingDebris = SpawnFallingRegionDebris(region);
490 DestroyPropsForRegion(regionEnt, buildingDebris);
494 vector camMat[4], regionMat[4];
495 GetWorld().GetCurrentCamera(camMat);
496 regionEnt.GetTransform(regionMat);
506 protected void OnRegionRepaired(
int region)
512 vector GetRegionPosition(
int regionNumber)
514 if (!m_BuildingSetup)
521 return CoordToParent(regionStruct.GetRegionPos());
540 vector regionDir = buildingDebris.CoordToParent(regionStruct.GetRegionPos()) - buildingDebris.GetOrigin();
541 buildingDebris.SetLinearVelocity(buildingDebris.GetLinearVelocity() + regionDir * Math.RandomFloat(0, 0.1));
542 buildingDebris.SetAngularVelocity(buildingDebris.GetAngularVelocity() + Vector(Math.RandomFloat(-1, 1), Math.RandomFloat(-1, 1), Math.RandomFloat(-1, 1)) * 2);
544 return buildingDebris;
549 protected void CheckStructuralIntegrity(
int region)
551 if (!m_BuildingSetup)
555 if (!GetRegionDestroyed(region))
563 autoptr array<int> toCheckRegionsList =
new array<int>;
564 toCheckRegionsList.Insert(region);
566 while (toCheckRegionsList.Count() > 0)
569 int checkRegion = toCheckRegionsList.Get(0);
570 toCheckRegionsList.Remove(0);
578 if (checkRegion != region)
581 int numSupportingRegions = regionStruct.GetConnectionNumIn();
582 int numOKSupportingRegions = 0;
583 for (
int n = 0; n < numSupportingRegions; n++)
587 if (GetRegionDestroyed(regionSupportingStruct.GetRegionIndex()))
590 numOKSupportingRegions++;
594 float heldPct = (float)numOKSupportingRegions / (
float)numSupportingRegions;
595 if (heldPct >= regionStruct.GetStructuralSupportPercentage())
599 SetRegionDamage01(checkRegion, 1,
false,
true,
false);
603 for (
int i = 0; i < regionStruct.GetConnectionNumOut(); i++)
607 int r = regionSupportedStruct.GetRegionIndex();
608 if (toCheckRegionsList.Find(r) > -1)
611 if (GetRegionDestroyed(r))
614 toCheckRegionsList.Insert(r);
630 if (!m_bDestroyed && !m_RegionMask && !m_RegionDamage)
657 bool GetRegionDestroyed(
int regionNumber)
665 return m_RegionMask.GetBit(regionNumber);
670 int GetRegionsCount()
672 if (!m_BuildingSetup)
675 return m_BuildingSetup.GetRegionNum();
680 float GetRegionMaxDamage(
int regionNumber)
682 if (!m_BuildingSetup)
685 if (regionNumber < 0)
688 if (regionNumber >= GetRegionsCount())
695 return regionStruct.GetMaxHealth();
700 float GetRegionDamage(
int regionNumber)
708 return GetRegionMaxDamage(regionNumber);
711 if (m_RegionMask && m_RegionMask.GetBit(regionNumber))
712 return GetRegionMaxDamage(regionNumber);
719 return m_RegionDamage.Get(regionNumber);
724 float GetRegionDamage01(
int regionNumber)
726 if (regionNumber >= GetRegionsCount())
729 float maxDamage = GetRegionMaxDamage(regionNumber);
733 return GetRegionDamage(regionNumber) / maxDamage;
738 protected void SetRegionDamage(
int regionNumber,
float damage,
bool doStructuralIntegrityCheck =
true,
bool doDamageEffects =
true,
bool sendRPC =
true)
740 if (!m_BuildingSetup)
743 if (regionNumber >= GetRegionsCount())
746 float maxDamage = GetRegionMaxDamage(regionNumber);
763 damage = Math.Clamp(damage, 0, maxDamage);
764 float curDam = GetRegionDamage(regionNumber);
767 if (curDam == damage)
772 if (damage >= maxDamage)
773 Rpc(RPC_OnRegionDestroyed, regionNumber,
true, doStructuralIntegrityCheck, doDamageEffects);
774 else if (damage <= 0)
775 Rpc(RPC_OnRegionDestroyed, regionNumber,
false, doStructuralIntegrityCheck, doDamageEffects);
781 SetDestroyedState(
false,
false);
782 SetAllZonesDestroyed();
786 if (damage == 0 || damage == maxDamage)
793 m_RegionMask.SetBit(regionNumber,
false);
794 if (m_RegionMask.GetEmpty())
798 OnRegionRepaired(regionNumber);
800 else if (damage == maxDamage)
805 m_RegionMask.SetBit(regionNumber,
true);
807 OnRegionDestroyed(regionNumber, doDamageEffects);
813 for (
int i = 0; i < m_RegionDamage.Count(); i++)
815 if (m_RegionDamage.GetKey(i) == regionNumber)
817 m_RegionDamage.RemoveElement(i);
823 if (m_RegionDamage.Count() == 0)
824 delete m_RegionDamage;
832 m_RegionMask.SetBit(regionNumber,
false);
833 if (m_RegionMask.GetEmpty())
839 m_RegionDamage =
new map<int, float>;
841 if (m_RegionDamage.Contains(regionNumber))
842 m_RegionDamage.Set(regionNumber, damage);
844 m_RegionDamage.Insert(regionNumber, damage);
848 if (GetAllZonesAtMaxDamage())
849 SetDestroyedState(
true,
false);
859 if (newState != state)
860 UpdateBuildingModel();
865 UpdateBuildingRegions();
866 if (doStructuralIntegrityCheck)
867 CheckStructuralIntegrity(regionNumber);
873 void SetRegionDamage01(
int regionNumber,
float damagePct,
bool doStructuralIntegrityCheck =
true,
bool doDamageEffects =
true,
bool sendRPC =
true)
875 SetRegionDamage(regionNumber, GetRegionMaxDamage(regionNumber) * damagePct, doStructuralIntegrityCheck, doDamageEffects, sendRPC);
880 void AddRegionDamage(
int regionNumber,
float damage,
bool doStructuralIntegrityCheck =
true,
bool doDamageEffects =
true,
bool sendRPC =
true)
882 SetRegionDamage(regionNumber, GetRegionDamage(regionNumber) + damage, doStructuralIntegrityCheck, doDamageEffects, sendRPC);
887 void SetDestroyedState(
bool destroyed,
bool updateModel =
true)
891 delete m_RegionDamage;
897 m_bDestroyed = destroyed;
900 UpdateBuildingModel();
907 if (!m_RegionEntities)
910 if (m_RegionEntities.Count() > regionNumber)
911 return m_RegionEntities.Get(regionNumber);
920 if (!m_RegionEntities)
921 m_RegionEntities =
new array<SCR_BuildingRegionEntity>;
924 if (m_RegionEntities.Count() > regionNumber)
925 regionEnt = m_RegionEntities.Get(regionNumber);
930 vector buildingMat[4];
931 GetTransform(buildingMat);
938 regionEnt.SetBuildingAndIndex(
this, regionNumber);
939 regionEnt.LoadRegionModel();
941 AddChild(regionEnt, -1, EAddChildFlags.NONE);
942 regionEnt.SetTransform(buildingMat);
944 m_RegionEntities.InsertAt(regionEnt, regionNumber);
951 bool GetPropDestructible(notnull IEntity prop)
958 if (genEnt.FindComponent(SCR_DestructionDamageManagerComponent))
962 if (genEnt.FindComponent(LadderComponent))
971 bool QueryRegionProp(IEntity prop,
bool propIsChild =
false,
float traceUp = 0.1,
float traceDown = 0.1)
985 if (prop.GetParent() && prop.GetParent() !=
this)
989 if (!propIsChild && !GetPropDestructible(prop))
993 if (s_aQueryPropsList.Find(prop) >= 0)
996 vector mins, maxs, mat[4];
997 prop.GetWorldTransform(mat);
1011 prop.GetBounds(mins, maxs);
1012 for (
int a = 0; a < 3; a++)
1014 float min = mins[a] + 0.2;
1015 float max = maxs[a] - 0.2;
1026 autoptr TraceOBB param =
new TraceOBB;
1027 param.Mat[0] = mat[0];
1028 param.Mat[1] = mat[1];
1029 param.Mat[2] = mat[2];
1030 param.Flags = TraceFlags.ENTS | TraceFlags.WORLD;
1031 param.LayerMask = EPhysicsLayerDefs.Default;
1035 param.Mins = -vector.One;
1036 param.Maxs = vector.One;
1038 param.Start = mat[3] + vector.Up * 1;
1039 param.End = mat[3] - vector.Up * 1;
1041 SCR_Global.g_TraceFilterEnt = s_QueryBuildingRegion;
1042 float traced =
m_World.TraceMove(param,
SCR_Global.FilterCallback_IgnoreAllButEntity);
1046 if (traced < 1 && param.TraceEnt == s_QueryBuildingRegion)
1047 s_aQueryPropsList.Insert(prop);
1049 #ifdef BUILDING_DEBUG_TEMP
1052 int color = ARGB(255, 255, 0, 0);
1054 color = ARGB(255, 0, 255, 0);
1056 int color2 = ARGB(255, 0, 0, 255);
1058 vector mins2 = param.Mins - vector.One * 0.025;
1059 vector maxs2 = param.Maxs + vector.One * 0.025;
1062 shp = Shape.Create(ShapeType.BBOX, color2, ShapeFlags.VISIBLE | ShapeFlags.NOZBUFFER | ShapeFlags.WIREFRAME, param.Mins, param.Maxs);
1063 mat[3] = param.Start;
1065 debugShapes.Insert(shp);
1068 shp = Shape.Create(ShapeType.BBOX, color2, ShapeFlags.VISIBLE | ShapeFlags.NOZBUFFER | ShapeFlags.WIREFRAME, param.Mins, param.Maxs);
1071 debugShapes.Insert(shp);
1074 shp = Shape.Create(ShapeType.LINE, color2, ShapeFlags.VISIBLE | ShapeFlags.NOZBUFFER, param.Start, param.End);
1075 debugShapes.Insert(shp);
1078 shp = Shape.Create(ShapeType.BBOX, color, ShapeFlags.VISIBLE | ShapeFlags.NOZBUFFER | ShapeFlags.WIREFRAME, mins2, maxs2);
1079 mat[3] = param.Start;
1081 debugShapes.Insert(shp);
1084 shp = Shape.Create(ShapeType.BBOX, color, ShapeFlags.VISIBLE | ShapeFlags.NOZBUFFER | ShapeFlags.WIREFRAME, mins2, maxs2);
1085 mat[3] = (param.End - param.Start) * traced + param.Start;
1087 debugShapes.Insert(shp);
1090 shp = Shape.Create(ShapeType.LINE, color, ShapeFlags.VISIBLE | ShapeFlags.NOZBUFFER, param.Start + vector.One * 0.025, (param.End - param.Start) * traced + param.Start + vector.One * 0.025);
1091 debugShapes.Insert(shp);
1093 CreateSimpleText(
"REGION: " + s_QueryBuildingRegion.GetRegionNumber().ToString(), mat, 0.2, ARGB(255, 255, 255, 255), ShapeFlags.NOZBUFFER, debugShapes, 0.7);
1095 PrintFormat(
"REGION: %1", s_QueryBuildingRegion.GetRegionNumber());
1101 bool QueryRegionPropCallback(IEntity e)
1103 return QueryRegionProp(e);
1110 #ifdef BUILDING_DEBUG_TEMP
1111 debugShapes.Clear();
1114 s_aQueryPropsList.Clear();
1115 s_QueryBuildingRegion = regionEnt;
1117 if (!s_QueryBuildingRegion)
1124 IEntity prop = child;
1125 child = child.GetSibling();
1127 QueryRegionProp(prop,
true);
1134 vector regionMins, regionMaxs, regionMat[4];
1135 s_QueryBuildingRegion.GetWorldBounds(regionMins, regionMaxs);
1137 m_World.QueryEntitiesByAABB(regionMins, regionMaxs, QueryRegionPropCallback);
1142 protected void CopyPropToBuildingDebris(
SCR_DebrisBuildingEntity buildingDebris, IEntity prop, vector debrisMat[4])
1144 if (!buildingDebris)
1151 IEntity propChild = prop.GetChildren();
1154 CopyPropToBuildingDebris(buildingDebris, propChild, debrisMat);
1155 propChild = propChild.GetSibling();
1159 VObject obj = prop.GetVObject();
1164 vector propMat[4], localPropMat[4];
1165 prop.GetWorldTransform(propMat);
1166 Math3D.MatrixInvMultiply4(debrisMat, propMat, localPropMat);
1170 propCopy.SetObject(obj,
string.Empty);
1171 propCopy.SetTransform(localPropMat);
1172 buildingDebris.AddChild(propCopy, -1, EAddChildFlags.AUTO_TRANSFORM);
1182 GetPropsForRegion(regionEnt);
1184 vector debrisMat[4];
1186 buildingDebris.GetWorldTransform(debrisMat);
1188 int numProps = s_aQueryPropsList.Count();
1189 for (
int i = numProps - 1; i >= 0; i--)
1191 IEntity prop = s_aQueryPropsList.Get(i);
1199 SCR_DestructionDamageManagerComponent
destructible = SCR_DestructionDamageManagerComponent.Cast(genProp.FindComponent(SCR_DestructionDamageManagerComponent));
1203 Math3D.MatrixIdentity3(mat);
1209 CopyPropToBuildingDebris(buildingDebris, prop, debrisMat);
1222 private void DeleteRegionEntity(
int regionNumber)
1224 if (!m_RegionEntities || m_RegionEntities.Count() <= regionNumber)
1234 for (
int i = 0; i < m_RegionEntities.Count(); i++)
1236 regionEnt = m_RegionEntities.Get(i);
1242 delete m_RegionEntities;
1243 m_RegionEntities =
null;
1248 private void DeleteAllRegionEntities()
1250 if (!m_RegionEntities)
1253 for (
int i = m_RegionEntities.Count() - 1; i > -1; i--)
1256 m_RegionEntities.Remove(i);
1260 delete m_RegionEntities;
1261 m_RegionEntities =
null;
1266 private void SpawnAllRegionEntities(
bool addRegionsToTraceIgnoreList =
false)
1268 if (addRegionsToTraceIgnoreList)
1271 DeleteAllRegionEntities();
1273 for (
int i = 0; i < GetRegionsCount(); i++)
1276 if (addRegionsToTraceIgnoreList && region)
1283 private void UpdateBuildingModel(
int forceState = -1,
bool addRegionsToTraceIgnoreList =
false)
1285 if (!m_BuildingSetup)
1295 if (forceState != -1)
1296 buildingState = forceState;
1298 ResourceName assetPath = m_BuildingSetup.m_ModelUndamaged;
1300 assetPath = m_BuildingSetup.m_ModelDestroyed;
1312 child = child.GetSibling();
1323 if (child.GetFlags() & EntityFlags.PROXY)
1325 child.ClearFlags(EntityFlags.PROXY,
false);
1330 child = child.GetSibling();
1335 Physics phys = GetPhysics();
1340 if (assetPath ==
"")
1342 SetObject(
null,
"");
1343 ClearFlags(EntityFlags.VISIBLE,
false);
1347 Resource resource = Resource.Load(assetPath);
1348 VObject asset = resource.GetResource().ToVObject();
1349 SetObject(asset,
"");
1350 SetFlags(EntityFlags.VISIBLE,
false);
1352 Physics.CreateStatic(
this, -1);
1357 ClearFlags(EntityFlags.VISIBLE,
false);
1364 SpawnAllRegionEntities(addRegionsToTraceIgnoreList);
1366 DeleteAllRegionEntities();
1371 private void UpdateBuildingRegions()
1373 if (!m_BuildingSetup)
1376 int regionNum = GetRegionsCount();
1377 for (
int i = 0; i < regionNum; i++)
1379 if (GetRegionDestroyed(i))
1381 DeleteRegionEntity(i);
1391 for (
int n = 0; n < regionNum; n++)
1397 if (GetRegionDestroyed(n))
1398 regionEnt.CreateIntersectDebris(n);
1400 regionEnt.DeleteIntersectDebris(n);
1407 private void SetAllZonesDestroyed()
1411 delete m_RegionDamage;
1413 for (
int i = 0; i < GetRegionsCount(); i++)
1418 m_RegionMask.SetBit(i,
true);
1424 bool GetAllZonesAtMaxDamage()
1430 for (
int i = 0; i < GetRegionsCount(); i++)
1433 if (m_RegionMask.GetBit(i))
1444 protected override void EOnInit(IEntity owner)
1447 RplComponent rplComponent = RplComponent.Cast(FindComponent(RplComponent));
1450 rplComponent.InsertToReplication();
1454 m_SoundComponent = BaseSoundComponent.Cast(FindComponent(BaseSoundComponent));
1465 #ifdef BUILDING_DESTRUCTION_DEBUG
1466 SetEventMask(EntityEvent.FRAME);
1468 SetEventMask(EntityEvent.INIT);
1470 if (m_BuildingConfig !=
string.Empty)
1480 DeleteAllRegionEntities();