public MyDamageInformation(bool isDeformation, float amount, MyDamageType type, long attackerId) { IsDeformation = isDeformation; Amount = amount; Type = type; AttackerId = attackerId; }
public override void DoDamage(float damage, int itemInstanceId, Vector3D position, Vector3 normal, MyDamageType type) { // CH: TODO: Move the particle effect to definitions MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.ChipOff_Wood, out effect)) { effect.WorldMatrix = MatrixD.CreateWorld(position, Vector3.CalculatePerpendicularVector(normal), normal); effect.AutoDelete = true; } if (!Sync.IsServer) { return; } MyCutTreeInfo cutTreeInfo = default(MyCutTreeInfo); int index = -1; for (int i = 0; i < m_cutTreeInfos.Count; ++i) { cutTreeInfo = m_cutTreeInfos[i]; if (itemInstanceId == cutTreeInfo.ItemInstanceId) { index = i; break; } } if (index == -1) { cutTreeInfo = new MyCutTreeInfo(); cutTreeInfo.ItemInstanceId = itemInstanceId; index = m_cutTreeInfos.Count; m_cutTreeInfos.Add(cutTreeInfo); } cutTreeInfo.LastHit = MySandboxGame.TotalGamePlayTimeInMilliseconds; cutTreeInfo.Progress += damage; if (cutTreeInfo.Progress >= 1) { if (type != MyDamageType.Drill) { position.Y = m_itemsData[itemInstanceId].Transform.Position.Y; } CutTree(itemInstanceId, position, normal); m_cutTreeInfos.RemoveAtFast(index); } else { m_cutTreeInfos[index] = cutTreeInfo; } return; }
internal static void DoDamageSynced(MySlimBlock block, float damage, MyDamageType damageType) { Debug.Assert(Sync.IsServer); var msg = new DoDamageSlimBlockMsg(); msg.GridEntityId = block.CubeGrid.EntityId; msg.Position = block.Position; msg.Damage = damage; block.DoDamage(damage, damageType); Sync.Layer.SendMessageToAll<DoDamageSlimBlockMsg>(ref msg); }
public static void DoDamageSynced(MyEntity destroyable, float damage, MyDamageType type) { Debug.Assert(Sync.IsServer || destroyable.SyncObject is MySyncEntity || (destroyable.SyncObject as MySyncEntity).ResponsibleForUpdate(Sync.Clients.LocalClient)); if (!(destroyable is IMyDestroyableObject)) return; var msg = new DoDamageMsg(); msg.DestroyableEntityId = destroyable.EntityId; msg.Damage = damage; msg.Type = type; (destroyable as IMyDestroyableObject).DoDamage(damage, type, false); Sync.Layer.SendMessageToAll<DoDamageMsg>(ref msg); }
public void DoDamage(float damage, MyDamageType damageType, bool sync) { if (sync) { if (Sync.IsServer) MySyncHelper.DoDamageSynced(this, damage, damageType); } else Explode(); }
public void DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { GameLogic.DoDamage(damage, damageType, sync, hitInfo, attackerId); }
/// <summary> /// Returns true when block is destroyed /// </summary> public void DoDamage(float damage, MyDamageType damageType, bool addDirtyParts = true) { if (!MySession.Static.DestructibleBlocks) return; damage *= DamageRatio; // Low-integrity blocks get more damage ProfilerShort.Begin("FatBlock.DoDamage"); try { if (FatBlock != null && CubeGrid.Physics != null && CubeGrid.Physics.Enabled) //Fatblock dont have physics { var destroyable = FatBlock as IMyDestroyableObject; if (destroyable != null) destroyable.DoDamage(damage, damageType, false); } } finally { ProfilerShort.End(); } MySession.Static.NegativeIntegrityTotal += damage; AccumulatedDamage += damage; if (m_componentStack.Integrity - AccumulatedDamage <= MyComponentStack.MOUNT_THRESHOLD) { CubeGrid.RemoveFromDamageApplication(this); ApplyAccumulatedDamage(addDirtyParts); } else if (MyFakes.SHOW_DAMAGE_EFFECTS && FatBlock != null && BlockDefinition.RationEnoughForDamageEffect((Integrity-damage) / MaxIntegrity)) FatBlock.SetDamageEffect(true); return; }
public void DoDamage(float damage, MyDamageType damageType, bool addDirtyParts = true, MyHitInfo? hitInfo = null, bool createDecal = true) { if (!CubeGrid.BlocksDestructionEnabled) return; if(FatBlock is MyCompoundCubeBlock) //jn: TODO think of something better { (FatBlock as MyCompoundCubeBlock).DoDamage(damage, damageType, hitInfo); return; } damage *= DamageRatio; // Low-integrity blocks get more damage if (MyPerGameSettings.Destruction) { damage *= DeformationRatio; } ProfilerShort.Begin("FatBlock.DoDamage"); try { if (FatBlock != null && CubeGrid.Physics != null && CubeGrid.Physics.Enabled) //Fatblock dont have physics { var destroyable = FatBlock as IMyDestroyableObject; if (destroyable != null) destroyable.DoDamage(damage, damageType, false); } } finally { ProfilerShort.End(); } MySession.Static.NegativeIntegrityTotal += damage; AccumulatedDamage += damage; if (m_componentStack.Integrity - AccumulatedDamage <= MyComponentStack.MOUNT_THRESHOLD) { if (MyPerGameSettings.Destruction && hitInfo.HasValue) { AccumulatedDamage = 0; var gridPhysics = CubeGrid.Physics; float maxDestructionRadius = CubeGrid.GridSizeEnum == MyCubeSize.Small ? 0.5f : 3; if(Sync.IsServer) Sandbox.Engine.Physics.MyDestructionHelper.TriggerDestruction(damage - m_componentStack.Integrity, gridPhysics, hitInfo.Value.Position, hitInfo.Value.Normal, maxDestructionRadius); } else { ApplyAccumulatedDamage(addDirtyParts); } CubeGrid.RemoveFromDamageApplication(this); } else { if (MyFakes.SHOW_DAMAGE_EFFECTS && FatBlock != null && BlockDefinition.RationEnoughForDamageEffect((Integrity - damage) / MaxIntegrity)) FatBlock.SetDamageEffect(true); if (hitInfo.HasValue && createDecal) CubeGrid.RenderData.AddDecal(Position, Vector3D.Transform(hitInfo.Value.Position, CubeGrid.PositionComp.WorldMatrixInvScaled), Vector3D.TransformNormal(hitInfo.Value.Normal, CubeGrid.PositionComp.WorldMatrixInvScaled), BlockDefinition.PhysicalMaterial.DamageDecal); } return; }
public void DoDamage(float damage, MyDamageType damageType, bool sync, long attackerId) { if (MarkedForClose) return; if (sync) { if (!Sync.IsServer) return; else { MySyncHelper.DoDamageSynced(this, damage, damageType, attackerId); return; } } MyDamageInformation damageinfo = new MyDamageInformation(false, damage, damageType, attackerId); if(UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref damageinfo); var typeId = Item.Content.TypeId; if (typeId == typeof(MyObjectBuilder_Ore) || typeId == typeof(MyObjectBuilder_Ingot)) { if (Item.Amount < 1) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; MyFloatingObjects.RemoveFloatingObject(this); } } else { if (Sync.IsServer) MyFloatingObjects.RemoveFloatingObject(this, (MyFixedPoint)damageinfo.Amount); } } else { m_health -= (10 + 90 * DamageMultiplier) * damageinfo.Amount; if(UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageinfo); if (m_health < 0) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; } if (Sync.IsServer) MyFloatingObjects.RemoveFloatingObject(this); //TODO: dont compare to string? if (Item.Content.SubtypeId == m_explosives && Sync.IsServer) { var expSphere = new BoundingSphere(WorldMatrix.Translation, (float)Item.Amount * 0.01f + 0.5f);// MathHelper.Clamp((float)Item.Amount, 0, 300) * 0.5f); MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, Damage = 800, ExplosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_15, ExplosionSphere = expSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = this, ParticleScale = 1, OwnerEntity = this, Direction = WorldMatrix.Forward, VoxelExplosionCenter = expSphere.Center, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.5f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); } if (MyFakes.ENABLE_SCRAP && Sync.IsServer) { if (Item.Content.SubtypeId == ScrapBuilder.SubtypeId) return; var contentDefinitionId = Item.Content.GetId(); if (contentDefinitionId.TypeId == typeof(MyObjectBuilder_Component)) { var definition = MyDefinitionManager.Static.GetComponentDefinition((Item.Content as MyObjectBuilder_Component).GetId()); if (MyRandom.Instance.NextFloat() < definition.DropProbability) MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(Item.Amount * 0.8f, ScrapBuilder), PositionComp.GetPosition(), WorldMatrix.Forward, WorldMatrix.Up); } } if(UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, damageinfo); } } return; }
public void DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo) { if (sync) { if (Sync.IsServer) MySyncHelper.DoDamageSynced(Entity, damage, damageType); } else { m_integrity -= damage; if (m_integrity <= 0) { m_closeAfterSimulation = true; return; } } return; }
public override void DoDamage(float damage, int instanceId, Vector3D position, Vector3 normal, MyDamageType type) { if (!Sync.IsServer) return; RemoveItem(instanceId, sync: true); }
/// <summary> /// Returns true when block is destroyed /// </summary> public void DoDamage(float damage, MyDamageType damageType, bool addDirtyParts = true, MyDestructionHelper.HitInfo? hitInfo = null) { if (!MySession.Static.DestructibleBlocks) return; damage *= DamageRatio; // Low-integrity blocks get more damage ProfilerShort.Begin("FatBlock.DoDamage"); try { if (FatBlock != null && CubeGrid.Physics != null && CubeGrid.Physics.Enabled) //Fatblock dont have physics { var destroyable = FatBlock as IMyDestroyableObject; if (destroyable != null) destroyable.DoDamage(damage, damageType, false); } } finally { ProfilerShort.End(); } MySession.Static.NegativeIntegrityTotal += damage; AccumulatedDamage += damage; if (m_componentStack.Integrity - AccumulatedDamage <= MyComponentStack.MOUNT_THRESHOLD) { if (MyPerGameSettings.Destruction && hitInfo.HasValue) { AccumulatedDamage = 0; var gridPhysics = CubeGrid.Physics; float maxDestructionRadius = CubeGrid.GridSizeEnum == MyCubeSize.Small ? 0.5f : 3; Sandbox.Engine.Physics.MyDestructionHelper.TriggerDestruction(damage, gridPhysics, hitInfo.Value.Position, hitInfo.Value.Normal, maxDestructionRadius); } else { ApplyAccumulatedDamage(addDirtyParts); } CubeGrid.RemoveFromDamageApplication(this); } else if (MyFakes.SHOW_DAMAGE_EFFECTS && FatBlock != null && BlockDefinition.RationEnoughForDamageEffect((Integrity-damage) / MaxIntegrity)) FatBlock.SetDamageEffect(true); return; }
void IMyDestroyableObject.DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo) { if (MarkedToExplode || (!MySession.Static.DestructibleBlocks)) return; //if (!IsFunctional) // return false; if (sync) { if (Sync.IsServer) MySyncHelper.DoDamageSynced(this, damage, damageType); } else { m_damageType = damageType; if (damage > 0) OnDestroy(); } return; }
public void DoDamage(float damage, MyDamageType damageType, bool sync) { GameLogic.DoDamage(damage, damageType, sync); }
public void DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { if (sync) { if (Sync.IsServer) MySyncHelper.DoDamageSynced(Entity, damage, damageType, attackerId); } else { MyDamageInformation info = new MyDamageInformation(false, damage, damageType, attackerId); if (Entity.UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(Entity, ref info); m_integrity -= info.Amount; if (Entity.UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(Entity, info); if (m_integrity <= 0) { m_closeAfterSimulation = true; if (Entity.UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(Entity, info); return; } } return; }
void IMyDestroyableObject.DoDamage(float damage, MyDamageType damageType, bool sync) { DoDamage(damage, damageType, sync); }
public void DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo) { GameLogic.DoDamage(damage, damageType, sync, hitInfo); }
public void DoDamage(float damage, MyDamageType damageType, bool sync, long attackerId) { if (sync) { if (Sync.IsServer) MySyncHelper.DoDamageSynced(this, damage, damageType, attackerId); } else { if (UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, new MyDamageInformation(false, damage, damageType, attackerId)); Explode(); } }
//public List<object> m_debugBones = new List<object>(); /// <summary> /// Applies deformation, returns true when block was destroyed (explosion should be generated) /// </summary> /// <param name="deformationOffset">Amount of deformation in the localPos</param> /// <param name="offsetThreshold">When deformation offset for bone is lower then threshold, it won't move the bone at all or do damage</param> public bool ApplyDeformation(float deformationOffset, float softAreaPlanar, float softAreaVertical, Vector3 localPos, Vector3 localNormal, MyDamageType damageType, float offsetThreshold = 0, float lowerRatioLimit = 0) { offsetThreshold /= m_grid.GridSizeEnum == MyCubeSize.Large ? 1 : 5; float roundSize = m_grid.GridSize / m_grid.Skeleton.BoneDensity; Vector3I roundedPos = Vector3I.Round((localPos + new Vector3(m_grid.GridSize / 2)) / roundSize); Vector3I gridPos = Vector3I.Round((localPos + new Vector3(m_grid.GridSize / 2)) / m_grid.GridSize); Vector3I gridOffset = roundedPos - gridPos * m_grid.Skeleton.BoneDensity; float breakOffset = m_grid.GridSize * 0.9f; float breakOffsetDestruction = breakOffset; Vector3I min = Vector3I.MaxValue; Vector3I max = Vector3I.MinValue; bool isDirty = false; bool destructionDone = false; Vector3 absNormal = Vector3.Abs(localNormal); float maxNorm = Math.Max(Math.Max(absNormal.X, absNormal.Y), absNormal.Z); float maxDef = maxNorm * deformationOffset; float destructionPotencial = (1 - breakOffsetDestruction / maxDef); float minDeformationRatio = 1; // When we're sure that there will be destroyed blocks, it's not necessary to do deformations, just do destruction if (destructionPotencial > 0) { float critVertical = destructionPotencial * softAreaVertical; float critPlanar = destructionPotencial * softAreaPlanar; float maxCritDist = Math.Max(critPlanar, critVertical); Vector3I distCubes = new Vector3I((int)Math.Ceiling(maxCritDist / m_grid.GridSize)); Vector3I minOffset = gridPos - distCubes; Vector3I maxOffset = gridPos + distCubes; minOffset = Vector3I.Max(minOffset, m_grid.Min); maxOffset = Vector3I.Min(maxOffset, m_grid.Max); ProfilerShort.Begin("Update destruction"); Vector3I offset; for (offset.X = minOffset.X; offset.X <= maxOffset.X; offset.X++) { for (offset.Y = minOffset.Y; offset.Y <= maxOffset.Y; offset.Y++) { for (offset.Z = minOffset.Z; offset.Z <= maxOffset.Z; offset.Z++) { Vector3 closestCorner = m_grid.GetClosestCorner(offset, localPos); float soften = 1.0f; if (offset != gridPos) { soften = CalculateSoften(softAreaPlanar, softAreaVertical, ref localNormal, closestCorner - localPos); } float deformation = maxNorm * deformationOffset * soften; if (deformation > breakOffsetDestruction) { var block = m_grid.GetCubeBlock(offset); if (block != null) { minDeformationRatio = Math.Min(minDeformationRatio, block.DeformationRatio); if (Math.Max(lowerRatioLimit, block.DeformationRatio) * deformation > breakOffsetDestruction) { ProfilerShort.Begin("Remove destroyed blocks"); min = Vector3I.Min(min, block.Min - Vector3I.One); max = Vector3I.Max(max, block.Max + Vector3I.One); isDirty = true; m_grid.RemoveDestroyedBlock(block); ProfilerShort.End(); destructionDone = true; } } } } } } ProfilerShort.End(); // When there was no destruction, reduce area and do deformation minDeformationRatio = Math.Max(minDeformationRatio, 0.2f); softAreaPlanar *= minDeformationRatio; softAreaVertical *= minDeformationRatio; } if (!destructionDone) { //m_debugBones.Clear(); ProfilerShort.Begin("Update deformation"); float softArea = Math.Max(softAreaPlanar, softAreaVertical); var distBones = new Vector3I((int)Math.Ceiling(softArea / m_grid.GridSize * m_grid.Skeleton.BoneDensity)); // TODO: clamp to grid Min/Max Vector3I minOffset = gridOffset - distBones; Vector3I maxOffset = gridOffset + distBones; Vector3I minDirtyBone = Vector3I.MaxValue; Vector3I maxDirtyBone = Vector3I.MinValue; ProfilerShort.Begin("Get bones"); m_tmpBoneList.Clear(); m_grid.GetExistingBones(gridPos * m_grid.Skeleton.BoneDensity + minOffset, gridPos * m_grid.Skeleton.BoneDensity + maxOffset, m_tmpBoneList); ProfilerShort.End(); ProfilerShort.Begin("Deform bones"); Vector3 bone; Vector3I offset; foreach (var b in m_tmpBoneList) { var boneIndex = b.Key; offset = boneIndex - gridPos * m_grid.Skeleton.BoneDensity; var baseBonePos = boneIndex * m_grid.GridSize / m_grid.Skeleton.BoneDensity - new Vector3(m_grid.GridSize / 2); m_grid.Skeleton.GetBone(ref boneIndex, out bone); var bonePos = bone + baseBonePos; float soften = CalculateSoften(softAreaPlanar, softAreaVertical, ref localNormal, bonePos - localPos); if (soften == 0) continue; min = Vector3I.Min(min, Vector3I.Floor(bonePos / m_grid.GridSize - Vector3.One / m_grid.Skeleton.BoneDensity)); max = Vector3I.Max(max, Vector3I.Ceiling(bonePos / m_grid.GridSize + Vector3.One / m_grid.Skeleton.BoneDensity)); isDirty = true; float deformationRatio = 1.0f; bool doDeformation = true; var block2 = b.Value; { Debug.Assert(block2 != null, "Block cannot be null"); deformationRatio = Math.Max(lowerRatioLimit, block2.DeformationRatio); // + some deformation coeficient based on integrity float maxAxisDeformation = maxNorm * deformationOffset * soften; doDeformation = block2.UsesDeformation; ProfilerShort.Begin("Apply damage"); if (block2.IsDestroyed) // || block2.DoDamage(maxAxisDeformation / m_grid.GridSize, damageType, addDirtyParts: false)) { destructionDone = true; } ProfilerShort.End(); } if (deformationOffset * deformationRatio < offsetThreshold) continue; float deformationLength = deformationOffset * soften * deformationRatio; var deformation = localNormal * deformationLength; bool canDeform = damageType != MyDamageType.Bullet || (Math.Abs(bone.X + deformation.X) < breakOffset && Math.Abs(bone.Y + deformation.Y) < breakOffset && Math.Abs(bone.Z + deformation.Z) < breakOffset); float minLength = Math.Min(m_grid.GridSize / 256.0f, deformationOffset * 0.06f); if (canDeform && deformationLength > minLength) { bone += deformation; //m_debugBones.Add(new Tuple<Vector3, float>(bonePos, deformationRatio)); if (Math.Abs(bone.X) > breakOffset || Math.Abs(bone.Y) > breakOffset || Math.Abs(bone.Z) > breakOffset) { m_tmpCubeList.Clear(); Vector3I wrappedBoneOffset = offset; Vector3I wrappedGridPos = gridPos; m_grid.Skeleton.Wrap(ref wrappedGridPos, ref wrappedBoneOffset); m_grid.Skeleton.GetAffectedCubes(wrappedGridPos, wrappedBoneOffset, m_tmpCubeList, m_grid); foreach (var c in m_tmpCubeList) { var block = m_grid.GetCubeBlock(c); if (block != null) { ProfilerShort.Begin("Remove destroyed blocks"); m_grid.RemoveDestroyedBlock(block); AddDirtyBlock(block); ProfilerShort.End(); destructionDone = true; } } } else if (doDeformation && Sync.IsServer) { minDirtyBone = Vector3I.Min(minDirtyBone, boneIndex); maxDirtyBone = Vector3I.Max(maxDirtyBone, boneIndex); m_grid.Skeleton.SetBone(ref boneIndex, ref bone); m_grid.AddDirtyBone(gridPos, offset); m_grid.BonesToSend.AddInput(boneIndex); } } } ProfilerShort.End(); ProfilerShort.End(); } if (isDirty) { m_dirtyCubesInfo.DirtyParts.Add(new BoundingBoxI() { Min = min, Max = max }); } return destructionDone; }
void IMyDestroyableObject.DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { if (sync) { Debug.Assert(Sync.IsServer); if (Sync.IsServer) MySyncHelper.DoDamageSynced(this, damage, damageType, hitInfo, attackerId); } else this.DoDamage(damage, damageType, hitInfo: hitInfo, attackerId: attackerId); return; }
void IMyDestroyableObject.DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { DoDamage(damage, damageType, sync, attackerId); }
/// Default implementation does nothing. If you want env. items to react to damage, subclass this public virtual void DoDamage(float damage, int instanceId, Vector3D position, Vector3 normal, MyDamageType type = MyDamageType.Unknown) { }
void IMyDestroyableObject.DoDamage(float damage, MyDamageType damageType, bool sync) { if (sync) { Debug.Assert(Sync.IsServer); if (Sync.IsServer) MySyncHelper.DoDamageSynced(this, damage, damageType); } else this.DoDamage(damage, damageType); return; }
internal void DoDamage(float damage, MyDamageType damageType, MyHitInfo? hitInfo, long attackerId) { float integrity = 0; foreach(var block in m_blocks) { integrity += block.Value.MaxIntegrity; } if (hitInfo.HasValue) { Debug.Assert(m_blocks.Count > 0); CubeGrid.RenderData.AddDecal(Position, Vector3D.Transform(hitInfo.Value.Position, CubeGrid.PositionComp.WorldMatrixInvScaled), Vector3D.TransformNormal(hitInfo.Value.Normal, CubeGrid.PositionComp.WorldMatrixInvScaled), m_blocks.First().Value.BlockDefinition.PhysicalMaterial.DamageDecal); } foreach (var block in m_blocks) { block.Value.DoDamage(damage * (block.Value.MaxIntegrity / integrity), damageType, true, hitInfo, false, attackerId); } }
void IMyDestroyableObject.DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { if (MarkedToExplode || (!MySession.Static.DestructibleBlocks)) return; //if (!IsFunctional) // return false; if (sync) { if (Sync.IsServer) MySyncHelper.DoDamageSynced(this, damage, damageType, attackerId); } else { MyDamageInformation damageInfo = new MyDamageInformation(false, damage, damageType, attackerId); if (UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref damageInfo); m_damageType = damageType; if (damageInfo.Amount > 0) { if (UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageInfo); OnDestroy(); if (UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, damageInfo); } } return; }
internal static void DoDamageSynced(MySlimBlock block, float damage, MyDamageType damageType, MyHitInfo? hitInfo, long attackerId) { Debug.Assert(Sync.IsServer); var msg = new DoDamageSlimBlockMsg(); msg.GridEntityId = block.CubeGrid.EntityId; msg.Position = block.Position; msg.Damage = damage; msg.HitInfo = hitInfo; msg.AttackerEntityId = attackerId; block.DoDamage(damage, damageType, hitInfo: hitInfo, attackerId: attackerId); Sync.Layer.SendMessageToAll<DoDamageSlimBlockMsg>(ref msg); }