예제 #1
0
 public MyDamageInformation(bool isDeformation, float amount, MyDamageType type, long attackerId)
 {
     IsDeformation = isDeformation;
     Amount = amount;
     Type = type;
     AttackerId = attackerId;
 }
예제 #2
0
        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;
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
 public void DoDamage(float damage, MyDamageType damageType, bool sync)
 {
     if (sync)
     {
         if (Sync.IsServer)
             MySyncHelper.DoDamageSynced(this, damage, damageType);
     }
     else
         Explode();
 }
예제 #6
0
 public void DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo, long attackerId)
 {
     GameLogic.DoDamage(damage, damageType, sync, hitInfo, attackerId);
 }
예제 #7
0
        /// <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;
        }
예제 #8
0
        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;
        }
예제 #9
0
        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;
        }
예제 #10
0
            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);
        }
예제 #12
0
        /// <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;
        }
예제 #13
0
        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;
        }
예제 #14
0
 public void DoDamage(float damage, MyDamageType damageType, bool sync)
 {
     GameLogic.DoDamage(damage, damageType, sync);
 }
예제 #15
0
            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;
            }
예제 #16
0
 void IMyDestroyableObject.DoDamage(float damage, MyDamageType damageType, bool sync)
 {
     DoDamage(damage, damageType, sync);
 }
예제 #17
0
 public void DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo)
 {
     GameLogic.DoDamage(damage, damageType, sync, hitInfo);
 }
예제 #18
0
        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();
            }
        }
예제 #19
0
        //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;
        }
예제 #20
0
 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;
 }
예제 #21
0
 void IMyDestroyableObject.DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo, long attackerId)
 {
     DoDamage(damage, damageType, sync, attackerId);
 }
예제 #22
0
 /// 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) { }
예제 #23
0
 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;
 }
예제 #24
0
        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);
            }
        }
예제 #25
0
        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;
        }
예제 #26
0
        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);
        }