Beispiel #1
0
        /// <param name="damage">Not used for now but could be used as a multiplier instead of random decal size</param>
        public static void HandleAddDecal(IMyEntity entity, MyHitInfo hitInfo, MyStringHash source = default(MyStringHash), float damage = -1)
        {
            if (entity == null)
                DebugNullEntity();

            IMyDecalProxy proxy = entity as IMyDecalProxy;
            if (proxy != null)
            {
                AddDecal(proxy, ref hitInfo, damage, source);
                return;
            }

            MyCubeGrid grid = entity.GetTopMostParent() as MyCubeGrid;
            if (grid != null)
            {
                var block = grid.GetTargetedBlock(hitInfo.Position);
                if (block != null)
                {
                    var compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                    if (compoundBlock == null)
                        proxy = block;
                    else
                        proxy = compoundBlock;
                }
            }

            if (proxy != null)
                AddDecal(proxy, ref hitInfo, damage, source);
        }
        /// <param name="damage">Not used for now but could be used as a multiplier instead of random decal size</param>
        public static void HandleAddDecal(IMyEntity entity, MyHitInfo hitInfo, MyStringHash source = default(MyStringHash), object customdata = null, float damage = -1)
        {
            IMyDecalProxy proxy = entity as IMyDecalProxy;
            if (proxy != null)
            {
                AddDecal(proxy, ref hitInfo, damage, source, customdata);
                return;
            }

            MyCubeGrid grid = entity as MyCubeGrid;
            if (grid != null)
            {
                var block = grid.GetTargetedBlock(hitInfo.Position);
                if (block != null)
                {
                    var compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                    if (compoundBlock == null)
                        proxy = block;
                    else
                        proxy = compoundBlock;
                }
            }

            if (proxy == null)
                return;

            AddDecal(proxy, ref hitInfo, damage, source, customdata);
        }
        private static void AddDecal(IMyDecalProxy proxy, ref MyHitInfo hitInfo, float damage, MyStringHash source, object customdata)
        {
            bool skip = DefaultFilterProxy(proxy);
            if (skip)
                return;

            m_handler.Source = source;
            m_handler.Enabled = true;
            proxy.AddDecals(hitInfo, source, customdata, m_handler);
            m_handler.Enabled = false;
            m_handler.Source = MyStringHash.NullOrEmpty;
        }
Beispiel #4
0
        private static void AddDecal(IMyDecalProxy proxy, ref MyHitInfo hitInfo, float damage, MyStringHash source)
        {
            bool skip = DefaultFilterProxy(proxy);
            if (skip)
                return;

            MyDecalRenderData data;
            proxy.GetDecalRenderData(hitInfo, out data);
            if (data.Skip)
                return;

            MyDecalMaterial material;
            bool found = MyDecalMaterials.TryGetDecalMaterial(data.Material.String, source.String, out material);
            if (!found)
            {
                if (MyFakes.ENABLE_USE_DEFAULT_DAMAGE_DECAL)
                    found = MyDecalMaterials.TryGetDecalMaterial(DEFAULT, DEFAULT, out material);

                if (!found)
                    return;
            }

            var perp = Vector3.CalculatePerpendicularVector(data.Normal);

            float rotation = material.Rotation;
            if (material.Rotation == float.PositiveInfinity)
                rotation = MyRandom.Instance.NextFloat() * MathHelper.TwoPi;

            if (rotation != 0)
            {
                // Rotate around normal
                Quaternion q = Quaternion.CreateFromAxisAngle(data.Normal, rotation);
                perp = new Vector3((new Quaternion(perp, 0) * q).ToVector4());
            }

            var pos = MatrixD.CreateWorld(data.Position, data.Normal, perp);

            var size = material.MinSize;
            if (material.MaxSize > material.MinSize)
                size += MyRandom.Instance.NextFloat() * (material.MaxSize - material.MinSize);

            pos = Matrix.CreateScale(new Vector3(size, size, material.Depth)) * pos;

            var decalId = MyRenderProxy.CreateDecal(data.RenderObjectId, pos, material.GetStringId());
            proxy.OnAddDecal(decalId, ref data);
        }
Beispiel #5
0
        /// <param name="damage">Not used for now but could be used as a multiplier instead of random decal size</param>
        public static void HandleAddDecal(IMyEntity entity, MyHitInfo hitInfo, MyStringHash source = default(MyStringHash), object customdata = null, float damage = -1)
        {
            IMyDecalProxy proxy = entity as IMyDecalProxy;
            if (proxy != null)
            {
                AddDecal(proxy, ref hitInfo, damage, source, customdata);
                return;
            }

            MyCubeGrid grid = entity as MyCubeGrid;
            if (grid != null)
            {
                MyCubeGridHitInfo info = customdata as MyCubeGridHitInfo;
                MySlimBlock block;
                if (info == null)
                {
                    block = grid.GetTargetedBlock(hitInfo.Position);
                }
                else
                {
                    // If info is provided, lookup for the cube using provided position
                    MyCube cube;
                    bool found = grid.TryGetCube(info.Position, out cube);
                    if (!found)
                        return;

                    block = cube.CubeBlock;
                }

                var compoundBlock = block != null ? block.FatBlock as MyCompoundCubeBlock : null;
                if (compoundBlock == null)
                    proxy = block;
                else
                    proxy = compoundBlock;
            }

            if (proxy == null)
                return;

            AddDecal(proxy, ref hitInfo, damage, source, customdata);
        }
 void IMyDecalProxy.GetDecalRenderData(MyHitInfo hitInfo, out MyDecalRenderData renderable)
 {
     // TODO
     renderable = new MyDecalRenderData();
     renderable.Skip = true;
 }
        void IMyDecalProxy.AddDecals(MyHitInfo hitInfo, MyStringHash source, object customdata, IMyDecalHandler decalHandler)
        {
            MyCharacterHitInfo charHitInfo = customdata as MyCharacterHitInfo;
            if (charHitInfo == null || charHitInfo.BoneIndex == -1)
                return;

            MyDecalRenderInfo renderable = new MyDecalRenderInfo();
            renderable.Position = charHitInfo.Triangle.IntersectionPointInObjectSpace;
            renderable.Normal = charHitInfo.Triangle.NormalInObjectSpace;
            renderable.RenderObjectId = Render.GetRenderObjectID();
            renderable.Material = MyStringHash.GetOrCompute(m_characterDefinition.PhysicalMaterial);

            var decalId = decalHandler.AddDecal(ref renderable);
            if (decalId == null)
                return;

            AddBoneDecal(decalId.Value, charHitInfo.HitPositionBindingPose, charHitInfo.HitNormalBindingPose, charHitInfo.BoneIndex);
        }
Beispiel #8
0
        void IMyDecalProxy.AddDecals(MyHitInfo hitInfo, MyStringHash source, object customdata, IMyDecalHandler decalHandler)
        {
            MyDecalRenderInfo renderable = new MyDecalRenderInfo();
            MyCubeGridHitInfo gridHitInfo = customdata as MyCubeGridHitInfo;
            renderable.Flags = BlockDefinition.PhysicalMaterial.Transparent ? MyDecalFlags.Transparent : MyDecalFlags.None;
            if (FatBlock == null)
            {
                renderable.Position = Vector3D.Transform(hitInfo.Position, CubeGrid.PositionComp.WorldMatrixInvScaled);
                renderable.Normal = Vector3D.TransformNormal(hitInfo.Normal, CubeGrid.PositionComp.WorldMatrixInvScaled);
                renderable.RenderObjectId = CubeGrid.Render.GetRenderObjectID();
            }
            else
            {
                renderable.Position = Vector3D.Transform(hitInfo.Position, FatBlock.PositionComp.WorldMatrixInvScaled);
                renderable.Normal = Vector3D.TransformNormal(hitInfo.Normal, FatBlock.PositionComp.WorldMatrixInvScaled);
                renderable.RenderObjectId = FatBlock.Render.GetRenderObjectID();
            }
            renderable.Material = MyStringHash.GetOrCompute(BlockDefinition.PhysicalMaterial.Id.SubtypeName);

            if (gridHitInfo != null)
            {
                VertexBoneIndicesWeights? boneIndicesWeights = gridHitInfo.Triangle.GetAffectingBoneIndicesWeights(ref m_boneIndexWeightTmp);
                if (boneIndicesWeights.HasValue)
                {
                    renderable.BoneIndices = boneIndicesWeights.Value.Indices;
                    renderable.BoneWeights = boneIndicesWeights.Value.Weights;

            var decalId = decalHandler.AddDecal(ref renderable);
            if (decalId != null)
                        CubeGrid.RenderData.AddDecal(Position, gridHitInfo, decalId.Value);

                    return;
        }
            }

            decalHandler.AddDecal(ref renderable);
        }
Beispiel #9
0
        public void DoDamage(float damage, MyStringHash damageType, MyHitInfo? hitInfo = null, bool addDirtyParts = true, long attackerId = 0)
        {
            if (!CubeGrid.BlocksDestructionEnabled && !ForceBlockDestructible)
                return;

            var compoundBlock = FatBlock as MyCompoundCubeBlock;
            if (compoundBlock != null) //jn: TODO think of something better
            {
                compoundBlock.DoDamage(damage, damageType, hitInfo, attackerId);
                return;
            }

            if (IsMultiBlockPart)
            {
                var multiBlockInfo = CubeGrid.GetMultiBlockInfo(MultiBlockId);
                Debug.Assert(multiBlockInfo != null);
                if (multiBlockInfo != null)
                {
                    Debug.Assert(m_tmpMultiBlocks.Count == 0);
                    m_tmpMultiBlocks.AddRange(multiBlockInfo.Blocks);

                    float totalMaxIntegrity = multiBlockInfo.GetTotalMaxIntegrity();
                    foreach (var multiBlockPart in m_tmpMultiBlocks)
                        multiBlockPart.DoDamageInternal(damage * (multiBlockPart.MaxIntegrity / totalMaxIntegrity), damageType, addDirtyParts: addDirtyParts, hitInfo: hitInfo, attackerId: attackerId);

                    m_tmpMultiBlocks.Clear();
                }
            }
            else
            {
                DoDamageInternal(damage, damageType, addDirtyParts: addDirtyParts, hitInfo: hitInfo, attackerId: attackerId);
            }
        }
Beispiel #10
0
        bool IMyDestroyableObject.DoDamage(float damage, MyStringHash damageType, bool sync, MyHitInfo? hitInfo, long attackerId)
        {
            if (MarkedToExplode || (!MySession.Static.DestructibleBlocks))
                return false;
            //if (!IsFunctional)
            //    return false;

            if (sync)
            {
                if (Sync.IsServer)
                    MySyncDamage.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 true;
        }
        private void DoDamage(float damage, MyHitInfo hitInfo, object customdata, IMyEntity damagedEntity)
        {
            //damage tracking
            MyEntity ent = (MyEntity)MySession.Static.ControlledEntity;
            if (this.OwnerEntityAbsolute != null && this.OwnerEntityAbsolute.Equals(MySession.Static.ControlledEntity) && (damagedEntity is IMyDestroyableObject || damagedEntity is MyCubeGrid))
            {
                MySession.Static.TotalDamageDealt += (uint)damage;
            }

            MyDecals.HandleAddDecal(damagedEntity, hitInfo, m_projectileAmmoDefinition.PhysicalMaterial, customdata, damage);

            if (!Sync.IsServer)
                return;

            if (m_projectileAmmoDefinition.PhysicalMaterial == m_hashBolt)
            {
                IMyDestroyableObject destroyable = damagedEntity as IMyDestroyableObject;
                if (destroyable != null && damagedEntity is MyCharacter)
                    destroyable.DoDamage(damage, MyDamageType.Bolt, true, hitInfo, m_weapon != null ? GetSubpartOwner(m_weapon).EntityId : 0);
            }
            else
            {
                var grid = damagedEntity as MyCubeGrid;
                IMyDestroyableObject destroyable;
                if (grid != null)
                {
                    if (grid.Physics != null && grid.Physics.Enabled && (grid.BlocksDestructionEnabled || MyFakes.ENABLE_VR_FORCE_BLOCK_DESTRUCTIBLE))
                    {
                        bool causeDeformation = false;
                        var block = grid.GetTargetedBlock(hitInfo.Position);
                        if (block != null && (grid.BlocksDestructionEnabled || block.ForceBlockDestructible))
                        {
                            block.DoDamage(damage, MyDamageType.Bullet, true, hitInfo, m_weapon != null ? GetSubpartOwner(m_weapon).EntityId : 0);
                            if (block.FatBlock == null)
                                causeDeformation = true;
                        }

                        if (grid.BlocksDestructionEnabled && causeDeformation)
                            ApllyDeformationCubeGrid(hitInfo.Position, grid);
                    }
                }
                //By Gregory: When MyEntitySubpart (e.g. extended parts of pistons and doors) damage the whole parent component
                //Temporary fix! Maybe other solution? MyEntitySubpart cannot implement IMyDestroyableObject cause is on dependent namespace
                else if (damagedEntity is MyEntitySubpart)
                {
                    if (damagedEntity.Parent != null && damagedEntity.Parent.Parent is MyCubeGrid)
                    {
                        hitInfo.Position = damagedEntity.Parent.WorldAABB.Center;
                        DoDamage(damage, hitInfo, customdata, damagedEntity.Parent.Parent);
                    }
                }
                else if ((destroyable = damagedEntity as IMyDestroyableObject) != null)
                    destroyable.DoDamage(damage, MyDamageType.Bullet, true, hitInfo, m_weapon != null ? GetSubpartOwner(m_weapon).EntityId : 0);
            }

            //Handle damage ?? some WIP code by Ondrej
            //MyEntity damagedObject = entity;
            //damagedObject.DoDamage(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_ammoProperties.DamageType, m_ammoProperties.AmmoType, m_ignorePhysObject);
            //if (MyMultiplayerGameplay.IsRunning)
            //    MyMultiplayerGameplay.Static.ProjectileHit(damagedObject, intersectionValue.IntersectionPointInWorldSpace, this.m_directionNormalized, MyAmmoConstants.FindAmmo(m_ammoProperties), this.OwnerEntity);

        }
        //  Update position, check collisions, etc.
        //  Return false if projectile dies/timeouts in this tick.
        public bool Update()
        {
            //  Projectile was killed , but still not last time drawn, so we don't need to do update (we are waiting for last draw)
            if (m_state == MyProjectileStateEnum.KILLED)
                return true;
            //  Projectile was killed and last time drawn, so we can finally remove it from buffer
            if (m_state == MyProjectileStateEnum.KILLED_AND_DRAWN)
            {
                StopEffect();
                return false;
            }

            Vector3D position = m_position;
            m_position += m_velocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * MyFakes.SIMULATION_SPEED;

            //  Distance timeout
            Vector3 positionDelta = m_position - m_origin;
            if (Vector3.Dot(positionDelta, positionDelta) >= m_maxTrajectory * m_maxTrajectory)
            {
                StopEffect();
                m_state = MyProjectileStateEnum.KILLED;
                return true;
            }

            m_checkIntersectionIndex = ++m_checkIntersectionIndex % CHECK_INTERSECTION_INTERVAL;
            if (m_checkIntersectionIndex != 0 && m_positionChecked) //check only each n-th intersection
                return true;

            //  Calculate hit point, create decal and throw debris particles
            Vector3D lineEndPosition = position + CHECK_INTERSECTION_INTERVAL * (m_velocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * MyFakes.SIMULATION_SPEED);

            LineD line = new LineD(m_positionChecked ? position : m_origin, lineEndPosition);
            m_positionChecked = true;

            IMyEntity entity;
            Vector3D hitPosition;
            Vector3 hitNormal;
            MyCharacterHitInfo charHitInfo;
            GetHitEntityAndPosition(line, out entity, out hitPosition, out hitNormal, out charHitInfo);
            if (entity == null || entity == m_ignoreEntity || entity.Physics == null)
                return true;

            if (IsIgnoredEntity(entity))
            {
                return true; // prevent player shooting himself
            }

            ProfilerShort.Begin("Projectile.Update");

            bool headShot = false;
            MyCharacter hitCharacter = entity as MyCharacter;
            if (hitCharacter != null)
            {
                IStoppableAttackingTool stoppableTool = hitCharacter.CurrentWeapon as IStoppableAttackingTool;
                if (stoppableTool != null)
                    stoppableTool.StopShooting(OwnerEntity);

                headShot = charHitInfo.HitHead && m_projectileAmmoDefinition.HeadShot; // allow head shots only for ammo supporting it in definition
            }

            m_position = hitPosition;

            bool isProjectileGroupKilled = false;

            if (!isProjectileGroupKilled)
            {
                MySurfaceImpactEnum surfaceImpact;
                MyStringHash materialType;
                GetSurfaceAndMaterial(entity, ref  hitPosition, out surfaceImpact, out materialType);

                PlayHitSound(materialType, entity, hitPosition, m_projectileAmmoDefinition.PhysicalMaterial);

                MyHitInfo hitInfo = new MyHitInfo();
                hitInfo.Normal = hitNormal;
                hitInfo.Position = hitPosition;
                hitInfo.Velocity = m_velocity;

                float damage = headShot ? m_projectileAmmoDefinition.ProjectileHeadShotDamage : m_projectileAmmoDefinition.ProjectileMassDamage;
                DoDamage(damage, hitInfo, charHitInfo, entity);

                //particle effect defined in materialProperties.sbc
                Vector3D particleHitPosition = hitPosition + line.Direction * -0.2;
                if (MyMaterialPropertiesHelper.Static.TryCreateCollisionEffect(MyMaterialPropertiesHelper.CollisionType.Hit, particleHitPosition, hitNormal, m_projectileAmmoDefinition.PhysicalMaterial, materialType) == false)
                {
                    //default effect when none other was found
                    if (surfaceImpact != MySurfaceImpactEnum.CHARACTER)
                        MyParticleEffects.CreateBasicHitParticles(m_projectileAmmoDefinition.ProjectileOnHitEffectName, ref hitPosition, ref hitNormal, ref line.Direction, entity, m_weapon, 1, OwnerEntity);
                }

                CreateDecal(materialType);

                if (m_weapon == null || (entity.GetTopMostParent() != m_weapon.GetTopMostParent()))
                    ApplyProjectileForce(entity, hitPosition, m_directionNormalized, false, m_projectileAmmoDefinition.ProjectileHitImpulse * m_impulseMultiplier);

                StopEffect();
                m_state = MyProjectileStateEnum.KILLED;
            }
            ProfilerShort.End();
            return true;
        }
        /// <summary>
        /// Updates resource.
        /// </summary>
        public override void UpdateBeforeSimulation()
        {
            try
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation");

                if (m_isExploded)
                {
                    if (Sandbox.Game.Multiplayer.Sync.IsServer)
                    {
                        //  Create explosion
                        float radius = m_missileAmmoDefinition.MissileExplosionRadius;
                        BoundingSphereD explosionSphere = new BoundingSphereD(m_collisionPoint.HasValue ? m_collisionPoint.Value : PositionComp.GetPosition(), radius);

                        MyEntity ownerEntity = null;
                        var ownerId = Sync.Players.TryGetIdentity(m_owner);
                        if (ownerId != null)
                            ownerEntity = ownerId.Character;
                        //MyEntities.TryGetEntityById(m_owner, out ownerEntity);
                        

                        //  Call main explosion starter
                        MyExplosionInfo info = new MyExplosionInfo()
                        {
                            PlayerDamage = 0,
                            //Damage = m_ammoProperties.Damage,
                            Damage = MyFakes.ENABLE_VOLUMETRIC_EXPLOSION ? m_missileAmmoDefinition.MissileExplosionDamage : 200,
                            ExplosionType = m_explosionType,
                            ExplosionSphere = explosionSphere,
                            LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN,
                            CascadeLevel = CascadedExplosionLevel,
                            HitEntity = m_collidedEntity,
                            ParticleScale = 0.2f,
                            OwnerEntity = ownerEntity,

                            Direction = WorldMatrix.Forward,
                            VoxelExplosionCenter = explosionSphere.Center + radius * WorldMatrix.Forward * 0.25f,

                            ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION,
                            VoxelCutoutScale = 0.3f,
                            PlaySound = true,
                            ApplyForceAndDamage = true
                        };
                        if (!MarkedToDestroy)
                            info.ExplosionFlags |= MyExplosionFlags.CREATE_PARTICLE_EFFECT;
                        MyExplosions.AddExplosion(ref info);

                        if (m_collidedEntity != null && !(m_collidedEntity is MyAmmoBase))
                        {
                            if (!m_collidedEntity.Physics.IsStatic)
                            {
                                m_collidedEntity.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE,
                                    100 * Physics.LinearVelocity, m_collisionPoint, null);
                            }
                        }
                    }

                    //by Gregory: added null check. Decal won't be added if m_collidedEntity not found
                    if (m_collisionPoint.HasValue && m_collidedEntity != null)
                    {
                        MyHitInfo hitInfo = new MyHitInfo();
                        hitInfo.Position = m_collisionPoint.Value;
                        hitInfo.Normal = new Vector3D(1, 0, 0); // FIXME

                        MyDecals.HandleAddDecal(m_collidedEntity, hitInfo, MyDamageType.Rocket);
                    }

                    Close();

                    return;
                }

                base.UpdateBeforeSimulation();

                if (m_missileAmmoDefinition.MissileSkipAcceleration)
                    Physics.LinearVelocity = WorldMatrix.Forward * m_missileAmmoDefinition.DesiredSpeed * 0.7f;
                else
                    Physics.LinearVelocity += PositionComp.WorldMatrix.Forward * m_missileAmmoDefinition.MissileAcceleration * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;

                if (m_smokeEffect == null)
                {
                    // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150)
                    {
                        if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile, out m_smokeEffect))
                        {
                            m_smokeEffect.UserScale = 0.3f;
                            
                            var matrix = PositionComp.WorldMatrix;
                            matrix.Translation -= matrix.Forward * m_smokeEffectOffsetMultiplier;
                            m_smokeEffect.WorldMatrix = matrix;
                            //m_smokeEffect.WorldMatrix = PositionComp.WorldMatrix;
                            m_smokeEffect.AutoDelete = false;
                            m_smokeEffect.CalculateDeltaMatrix = true;
                        }
                    }
                }
                Physics.AngularVelocity = Vector3.Zero;

                if ((Vector3.Distance(PositionComp.GetPosition(), m_origin) >= m_maxTrajectory))
                {
                    Explode();
                    return;
                }
            }
            finally
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
        internal void DoDamage(float damage, MyStringHash damageType, MyHitInfo? hitInfo, long attackerId)
        {
            float integrity = 0;
            foreach(var block in m_mapIdToBlock)
            {
                integrity += block.Value.MaxIntegrity;
            }

            for (int i = m_blocks.Count - 1; i >= 0; --i)
            {
                var block = m_blocks[i];
                block.DoDamage(damage * (block.MaxIntegrity / integrity), damageType, hitInfo, true, attackerId);
            }
        }
        void IMyDecalProxy.AddDecals(MyHitInfo hitInfo, MyStringHash source, object customdata, IMyDecalHandler decalHandler)
        {
            Debug.Assert(m_mapIdToBlock.Count > 0);
            MySlimBlock block = m_mapIdToBlock.First().Value;
            MyPhysicalMaterialDefinition physicalMaterial = block.BlockDefinition.PhysicalMaterial;
            MyDecalRenderInfo renderable = new MyDecalRenderInfo();
            renderable.Flags = physicalMaterial.Transparent ? MyDecalFlags.Transparent : MyDecalFlags.None;
            renderable.Position = Vector3D.Transform(hitInfo.Position, CubeGrid.PositionComp.WorldMatrixInvScaled);
            renderable.Normal = Vector3D.TransformNormal(hitInfo.Normal, CubeGrid.PositionComp.WorldMatrixInvScaled);
            renderable.RenderObjectId = CubeGrid.Render.GetRenderObjectID();
            renderable.Material = MyStringHash.GetOrCompute(physicalMaterial.Id.SubtypeName);

            var decalId = decalHandler.AddDecal(ref renderable);
            if (decalId != null)
                CubeGrid.RenderData.AddDecal(Position, decalId.Value);
        }
Beispiel #16
0
            public void DoDamage(float damage, MyStringHash damageType, bool sync, MyHitInfo? hitInfo, long attackerId)
            {
                if (sync)
                {
                    if (Sync.IsServer)
                        MySyncDamage.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 && Sync.IsServer)
                    {
                        m_closeAfterSimulation = Sync.IsServer;

                        if (Entity.UseDamageSystem)
                            MyDamageSystem.Static.RaiseDestroyed(Entity, info);

                        return;
                    }
                }
                return;
            }
        public bool DoDamage(float damage, MyStringHash damageType, bool sync, MyHitInfo? hitInfo, long attackerId)
        {
            if (Sync.IsServer)
            {
                MyDamageInformation info = new MyDamageInformation(false, damage, damageType, attackerId);
                if (UseDamageSystem)
                    MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref info);

                m_hitPoints -= info.Amount;

                if (UseDamageSystem)
                    MyDamageSystem.Static.RaiseAfterDamageApplied(this, info);

                if (m_hitPoints <= 0)
                {
                    MyFracturedPiecesManager.Static.RemoveFracturePiece(this, 2);

                    if (UseDamageSystem)
                        MyDamageSystem.Static.RaiseDestroyed(this, info);
                }
            }
            return true;
        }
Beispiel #18
0
 void IMyDecalProxy.AddDecals(MyHitInfo hitInfo, MyStringHash source, object customdata, IMyDecalHandler decalHandler)
 {
     MyDecalRenderInfo info = new MyDecalRenderInfo();
     info.Position = hitInfo.Position;
     info.Normal = hitInfo.Normal;
     info.RenderObjectId = -1;
     info.Flags = MyDecalFlags.World;
     info.Material = Physics.MaterialType;
     decalHandler.AddDecal(ref info);
 }
        private void GetHitEntityAndPosition(LineD line, out IMyEntity entity, out Vector3D hitPosition, out Vector3 hitNormal, out MyCharacterHitInfo charHitInfo)
        {
            entity = null;
            hitPosition = hitNormal = Vector3.Zero;
            charHitInfo = null;

            // 1. rough raycast
            int raycastListIndex = 0;

            do
            {

                if (entity == null)
                {
                    if (raycastListIndex == 0) // cast only the first iteration
                    {
                        ProfilerShort.Begin("MyGamePruningStructure::CastProjectileRay");
                        MyPhysics.CastRay(line.From, line.To, m_raycastResult,
                            MyPhysics.CollisionLayers.DefaultCollisionLayer);
                        ProfilerShort.End();
                    }

                    if (raycastListIndex < m_raycastResult.Count)
                    {
                        MyPhysics.HitInfo hitInfo = m_raycastResult[raycastListIndex];

                        entity = hitInfo.HkHitInfo.GetHitEntity() as MyEntity;
                    	hitPosition = hitInfo.Position;
                    	hitNormal = hitInfo.HkHitInfo.Normal;
                    }
                }

                // 2. prevent shooting through characters, retest trajectory between entity and player
                if (!(entity is MyCharacter) || entity == null)
                {
                    // first: raycast, get all entities in line, limit distance if possible
                    LineD lineLimited = new LineD(line.From, entity == null ? line.To : hitPosition);
                    if (m_entityRaycastResult == null)
                    {
                        m_entityRaycastResult = new List<MyLineSegmentOverlapResult<MyEntity>>(16);
                    }
                    else
                    {
                        m_entityRaycastResult.Clear();
                    }
                    MyGamePruningStructure.GetAllEntitiesInRay(ref lineLimited, m_entityRaycastResult);
                    // second: precise tests, find best result
                    double bestDistanceSq = double.MaxValue;
                    IMyEntity entityBest = null;
                    for (int i = 0; i < m_entityRaycastResult.Count; i++)
                    {
                        if (m_entityRaycastResult[i].Element is MyCharacter)
                        {
                            MyCharacter hitCharacter = m_entityRaycastResult[i].Element as MyCharacter;
                            bool intersection = hitCharacter.GetIntersectionWithLine(ref line, ref m_charHitInfo);
                            if (intersection)
                            {
                                double distanceSq =
                                    Vector3D.DistanceSquared(m_charHitInfo.Triangle.IntersectionPointInWorldSpace,
                                        line.From);
                                if (distanceSq < bestDistanceSq && !IsIgnoredEntity(hitCharacter))
                                {
                                    bestDistanceSq = distanceSq;
                                    entityBest = hitCharacter;
                                    hitPosition = m_charHitInfo.Triangle.IntersectionPointInWorldSpace;
                                    hitNormal = m_charHitInfo.Triangle.NormalInWorldSpace;
                                    charHitInfo = m_charHitInfo;
                                }
                            }
                        }
                    }
                    // finally: do we have best result? then return it
                    if (entityBest != null)
                    {
                        entity = entityBest;
                        return; // this was precise result, so return
                    }
                }

                // 3. nothing found in the precise test? then fallback to already found results
                if (entity == null)
                    return; // no fallback results

                if (entity is MyCharacter) // retest character found in fallback
                {
                    MyCharacter hitCharacter = entity as MyCharacter;
                    bool intersection = hitCharacter.GetIntersectionWithLine(ref line, ref m_charHitInfo);
                    if (intersection)
                    {
                        hitPosition = m_charHitInfo.Triangle.IntersectionPointInWorldSpace;
                        hitNormal = m_charHitInfo.Triangle.NormalInWorldSpace;
                        charHitInfo = m_charHitInfo;
                    }
                    else
                    {
                        entity = null; // no hit.
                    }
                }
                else if (entity is MyGhostCharacter)
                {
                    MyHitInfo info = new MyHitInfo();
                    info.Position = hitPosition;
                    info.Normal = hitNormal;
                }
                else
                {
                    MyCubeGrid grid = entity as MyCubeGrid;
                    if (grid != null)
                    {
                        MyIntersectionResultLineTriangleEx? result;
                        bool success = grid.GetIntersectionWithLine(ref line, out result);
                        if (success && result.HasValue)
                        {
                            hitPosition = result.Value.IntersectionPointInWorldSpace;
                            hitNormal = result.Value.NormalInWorldSpace;
                            if (Vector3.Dot(hitNormal, line.Direction) > 0)
                                hitNormal = -hitNormal;
                        }

                        MyHitInfo info = new MyHitInfo();
                        info.Position = hitPosition;
                        info.Normal = hitNormal;
                    }
                }

            } while (entity == null && ++raycastListIndex < m_entityRaycastResult.Count);
        }
Beispiel #20
0
        void IMyDecalProxy.AddDecals(MyHitInfo hitInfo, MyStringHash source, object customdata, IMyDecalHandler decalHandler)
        {
            MyDecalRenderInfo renderable = new MyDecalRenderInfo();
            renderable.Flags = BlockDefinition.PhysicalMaterial.Transparent ? MyDecalFlags.Transparent : MyDecalFlags.None;
            if (FatBlock == null)
            {
                renderable.Position = Vector3D.Transform(hitInfo.Position, CubeGrid.PositionComp.WorldMatrixInvScaled);
                renderable.Normal = Vector3D.TransformNormal(hitInfo.Normal, CubeGrid.PositionComp.WorldMatrixInvScaled);
                renderable.RenderObjectId = CubeGrid.Render.GetRenderObjectID();
            }
            else
            {
                renderable.Position = Vector3D.Transform(hitInfo.Position, FatBlock.PositionComp.WorldMatrixInvScaled);
                renderable.Normal = Vector3D.TransformNormal(hitInfo.Normal, FatBlock.PositionComp.WorldMatrixInvScaled);
                renderable.RenderObjectId = FatBlock.Render.GetRenderObjectID();
            }
            renderable.Material = MyStringHash.GetOrCompute(BlockDefinition.PhysicalMaterial.Id.SubtypeName);

            var decalId = decalHandler.AddDecal(ref renderable);
            if (decalId != null)
                CubeGrid.RenderData.AddDecal(Position, decalId.Value);
        }
        void RigidBody_ContactPointCallback_Destruction(ref HkContactPointEvent value)
        {
            ProfilerShort.Begin("Grid Contact counter");
            ProfilerShort.End();
            MyGridContactInfo info = new MyGridContactInfo(ref value, m_grid);

            if (info.IsKnown)
                return;

            var myEntity = info.CurrentEntity;//value.Base.BodyA.GetEntity() == m_grid.Components ? value.Base.BodyA.GetEntity() : value.Base.BodyB.GetEntity();
            if (myEntity == null || myEntity.Physics == null || myEntity.Physics.RigidBody == null)
            {
                return;
            }
            var myBody = myEntity.Physics.RigidBody;

            // CH: DEBUG
            var physicsBody1 = value.GetPhysicsBody(0);
            var physicsBody2 = value.GetPhysicsBody(1);
            if (physicsBody1 == null || physicsBody2 == null)
                return;

            var entity1 = physicsBody1.Entity;
            var entity2 = physicsBody2.Entity;
            if (entity1 == null || entity2 == null || entity1.Physics == null || entity2.Physics == null)
                return;

            if (entity1 is MyFracturedPiece && entity2 is MyFracturedPiece)
                return;

            var rigidBody1 = value.Base.BodyA;
            var rigidBody2 = value.Base.BodyB;

            info.HandleEvents();
            if (rigidBody1.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT) || rigidBody2.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT))
                return;

            if (info.CollidingEntity is Sandbox.Game.Entities.Character.MyCharacter || info.CollidingEntity == null || info.CollidingEntity.MarkedForClose)
                return;

            var grid1 = entity1 as MyCubeGrid;
            var grid2 = entity2 as MyCubeGrid;

            // CH: TODO: This is a hack Instead, the IMyDestroyableObject should be used and the subpart DoDamage code could delegate it to the grid
            // The thing is, this approach would probably need a rewrite of this whole method...
            if (grid2 == null && entity2 is MyEntitySubpart)
            {
                while (entity2 != null && !(entity2 is MyCubeGrid))
                {
                    entity2 = entity2.Parent;
                }

                if (entity2 != null)
                {
                    physicsBody2 = entity2.Physics as MyPhysicsBody;
                    rigidBody2 = physicsBody2.RigidBody;
                    grid2 = entity2 as MyCubeGrid;
                }
            }

            if (grid1 != null && grid2 != null && (MyCubeGridGroups.Static.Physical.GetGroup(grid1) == MyCubeGridGroups.Static.Physical.GetGroup(grid2)))
                return;

            ProfilerShort.Begin("Grid contact point callback");

            {
                var vel = Math.Abs(value.SeparatingVelocity);
                bool enoughSpeed = vel > 3;
                //float dot = Vector3.Dot(Vector3.Normalize(LinearVelocity), Vector3.Normalize(info.CollidingEntity.Physics.LinearVelocity));


                Vector3 velocity1 = rigidBody1.GetVelocityAtPoint(info.Event.ContactPoint.Position);
                Vector3 velocity2 = rigidBody2.GetVelocityAtPoint(info.Event.ContactPoint.Position);

                float speed1 = velocity1.Length();
                float speed2 = velocity2.Length();

                Vector3 dir1 = speed1 > 0 ? Vector3.Normalize(velocity1) : Vector3.Zero;
                Vector3 dir2 = speed2 > 0 ? Vector3.Normalize(velocity2) : Vector3.Zero;

                float mass1 = MyDestructionHelper.MassFromHavok(rigidBody1.Mass);
                float mass2 = MyDestructionHelper.MassFromHavok(rigidBody2.Mass);

                float impact1 = speed1 * mass1;
                float impact2 = speed2 * mass2;

                float dot1withNormal = speed1 > 0 ? Vector3.Dot(dir1, value.ContactPoint.Normal) : 0;
                float dot2withNormal = speed2 > 0 ? Vector3.Dot(dir2, value.ContactPoint.Normal) : 0;

                speed1 *= Math.Abs(dot1withNormal);
                speed2 *= Math.Abs(dot2withNormal);

                bool is1Static = mass1 == 0;
                bool is2Static = mass2 == 0;

                bool is1Small = entity1 is MyFracturedPiece || (grid1 != null && grid1.GridSizeEnum == MyCubeSize.Small);
                bool is2Small = entity2 is MyFracturedPiece || (grid2 != null && grid2.GridSizeEnum == MyCubeSize.Small);


                float dot = Vector3.Dot(dir1, dir2);

                float maxDestructionRadius = 0.5f;

                impact1 *= info.ImpulseMultiplier;
                impact2 *= info.ImpulseMultiplier;

                MyHitInfo hitInfo = new MyHitInfo();
                var hitPos = info.ContactPosition;
                hitInfo.Normal = value.ContactPoint.Normal;

                //direct hit
                if (dot1withNormal < 0.0f)
                {
                    if (entity1 is MyFracturedPiece)
                        impact1 /= 10;

                    impact1 *= Math.Abs(dot1withNormal); //respect angle of hit

                    if ((impact1 > 2000 && speed1 > 2 && !is2Small) ||
                        (impact1 > 500 && speed1 > 10)) //must be fast enought to destroy fracture piece (projectile)
                    {  //1 is big hitting

                        if (is2Static || impact1 / impact2 > 10)
                        {
                            hitInfo.Position = hitPos + 0.1f * hitInfo.Normal;
                            impact1 -= mass1;

                            if (Sync.IsServer && impact1 > 0)
                            {
                                if (grid1 != null)
                                {
                                    var blockPos = GetGridPosition(value.ContactPoint, rigidBody1, grid1, 0);
                                    grid1.DoDamage(impact1, hitInfo, blockPos, grid2 != null ? grid2.EntityId : 0);
                                }
                                else
                                    MyDestructionHelper.TriggerDestruction(impact1, (MyPhysicsBody)entity1.Physics, info.ContactPosition, value.ContactPoint.Normal, maxDestructionRadius);
                                hitInfo.Position = hitPos - 0.1f * hitInfo.Normal;
                                if (grid2 != null)
                                {
                                    var blockPos = GetGridPosition(value.ContactPoint, rigidBody2, grid2, 1);
                                    grid2.DoDamage(impact1, hitInfo, blockPos, grid1 != null ? grid1.EntityId : 0);
                                }
                                else
                                    MyDestructionHelper.TriggerDestruction(impact1, (MyPhysicsBody)entity2.Physics, info.ContactPosition, value.ContactPoint.Normal, maxDestructionRadius);

                                ReduceVelocities(info);
                            }

                            MyDecals.HandleAddDecal(entity1, hitInfo);
                            MyDecals.HandleAddDecal(entity2, hitInfo);
                        }
                    }
                }

                if (dot2withNormal < 0.0f)
                {
                    if (entity2 is MyFracturedPiece)
                        impact2 /= 10;

                    impact2 *= Math.Abs(dot2withNormal); //respect angle of hit

                    if (impact2 > 2000 && speed2 > 2 && !is1Small ||
                        (impact2 > 500 && speed2 > 10)) //must be fast enought to destroy fracture piece (projectile)
                    {  //2 is big hitting

                        if (is1Static || impact2 / impact1 > 10)
                        {
                            hitInfo.Position = hitPos + 0.1f * hitInfo.Normal;
                            impact2 -= mass2;

                            if (Sync.IsServer && impact2 > 0)
                            {
                                if (grid1 != null)
                                {
                                    var blockPos = GetGridPosition(value.ContactPoint, rigidBody1, grid1, 0);
                                    grid1.DoDamage(impact2, hitInfo, blockPos, grid2 != null ? grid2.EntityId : 0);
                                }
                                else
                                    MyDestructionHelper.TriggerDestruction(impact2, (MyPhysicsBody)entity1.Physics, info.ContactPosition, value.ContactPoint.Normal, maxDestructionRadius);
                                hitInfo.Position = hitPos - 0.1f * hitInfo.Normal;
                                if (grid2 != null)
                                {
                                    var blockPos = GetGridPosition(value.ContactPoint, rigidBody2, grid2, 1);
                                    grid2.DoDamage(impact2, hitInfo, blockPos, grid1 != null ? grid1.EntityId : 0);
                                }
                                else
                                    MyDestructionHelper.TriggerDestruction(impact2, (MyPhysicsBody)entity2.Physics, info.ContactPosition, value.ContactPoint.Normal, maxDestructionRadius);

                                ReduceVelocities(info);
                            }

                            MyDecals.HandleAddDecal(entity1, hitInfo);
                            MyDecals.HandleAddDecal(entity2, hitInfo);
                        }
                    }
                }

                //float destructionImpact = vel * (MyDestructionHelper.MassFromHavok(Mass) + MyDestructionHelper.MassFromHavok(info.CollidingEntity.Physics.Mass));
                //destructionImpact *= info.ImpulseMultiplier;

                //if (destructionImpact > 2000 && enoughSpeed)
                //{
                //    CreateDestructionFor(destructionImpact, LinearVelocity + info.CollidingEntity.Physics.LinearVelocity, this, info, value.ContactPoint.Normal);
                //    CreateDestructionFor(destructionImpact, LinearVelocity + info.CollidingEntity.Physics.LinearVelocity, info.CollidingEntity.Physics, info, value.ContactPoint.Normal);

                //    ReduceVelocities(info);
                //}
            }

            ProfilerShort.End();
        }
Beispiel #22
0
        private void GetHitEntityAndPosition(LineD line, out IMyEntity entity, out Vector3D hitPosition, out Vector3 hitNormal, out bool hitHead)
        {
            entity = null;
            hitPosition = hitNormal = Vector3.Zero;
            hitHead = false;

            // 1. rough raycast
            if (entity == null)
            {
                ProfilerShort.Begin("MyGamePruningStructure::CastProjectileRay");
                MyPhysics.HitInfo? hitInfo = MyPhysics.CastRay(line.From, line.To, MyPhysics.CollisionLayers.DefaultCollisionLayer);
                ProfilerShort.End();
                if (hitInfo.HasValue)
                {
                    entity = hitInfo.Value.HkHitInfo.GetHitEntity() as MyEntity;
                    hitPosition = hitInfo.Value.Position;
                    hitNormal = hitInfo.Value.HkHitInfo.Normal;
                }
            }

            // 2. prevent shooting through characters, retest trajectory between entity and player
            if (!(entity is MyCharacter) || entity == null)
            {
                // first: raycast, get all entities in line, limit distance if possible
                LineD lineLimited = new LineD(line.From, entity == null ? line.To : hitPosition);
                if (m_entityRaycastResult == null)
                {
                    m_entityRaycastResult = new List<MyLineSegmentOverlapResult<MyEntity>>(16);
                }
                else
                {
                    m_entityRaycastResult.Clear();
                }
                MyGamePruningStructure.GetAllEntitiesInRay(ref lineLimited, m_entityRaycastResult);
                // second: precise tests, find best result
                double bestDistanceSq = double.MaxValue;
                IMyEntity entityBest = null;
                for (int i = 0; i < m_entityRaycastResult.Count; i++)
                {
                    if (m_entityRaycastResult[i].Element is MyCharacter)
                    {
                        MyCharacter hitCharacter = m_entityRaycastResult[i].Element as MyCharacter;
                        VRage.Game.Models.MyIntersectionResultLineTriangleEx? t;
                        hitCharacter.GetIntersectionWithLine(ref line, out t, out hitHead);

                        if (t != null)
                        {
                            double distanceSq = Vector3D.DistanceSquared(t.Value.IntersectionPointInWorldSpace, line.From);
                            if (distanceSq < bestDistanceSq)
                            {
                                bestDistanceSq = distanceSq;
                                entityBest = hitCharacter;
                                hitPosition = t.Value.IntersectionPointInWorldSpace;
                                hitNormal = t.Value.NormalInWorldSpace;
                            }
                        }
                    }
                }
                // finally: do we have best result? then return it
                if (entityBest != null)
                {
                    entity = entityBest; 
                    return; // this was precise result, so return
                }
            }

            // 3. nothing found in the precise test? then fallback to already found results
            if (entity == null)
                return; // no fallback results

            if (entity is MyCharacter) // retest character found in fallback
            {
                MyCharacter hitCharacter = entity as MyCharacter;
                VRage.Game.Models.MyIntersectionResultLineTriangleEx? t;
                hitCharacter.GetIntersectionWithLine(ref line, out t, out hitHead);
                if (t == null)
                {
                    entity = null; // no hit.
                }
                else
                {
                    hitPosition = t.Value.IntersectionPointInWorldSpace;
                    hitNormal = t.Value.NormalInWorldSpace;
                    hitHead = hitHead && m_projectileAmmoDefinition.HeadShot; // allow head shots only for ammo supporting it in definition
                }
            }
            else
            {
                MyCubeGrid grid = entity as MyCubeGrid;
                if (grid != null)
                {
                    MyIntersectionResultLineTriangleEx? result;
                    bool success = grid.GetIntersectionWithLine(ref line, out result);
                    if (success)
                    {
                        hitPosition = result.Value.IntersectionPointInWorldSpace;
                        hitNormal = result.Value.NormalInWorldSpace;
                    }

                    MyHitInfo info = new MyHitInfo();
                    info.Position = hitPosition;
                    info.Normal = hitNormal;
                }
            }
        }
Beispiel #23
0
 public bool DoDamage(float damage, MyStringHash damageType, bool sync, MyHitInfo? hitInfo, long attackerId)
 {
     if (sync)
     {
         Debug.Assert(Sync.IsServer);
         if (Sync.IsServer)
             DoDamageSynced(this, damage, damageType, hitInfo, attackerId);
     }
     else
         this.DoDamage(damage, damageType, hitInfo: hitInfo, attackerId: attackerId);
     return true;
 }
Beispiel #24
0
        void IMyDecalProxy.AddDecals(MyHitInfo hitInfo, MyStringHash source, object customdata, IMyDecalHandler decalHandler)
        {
            MyDecalRenderInfo renderable = new MyDecalRenderInfo();
            renderable.Flags = MyDecalFlags.World;
            renderable.Position = hitInfo.Position;
            renderable.Normal = hitInfo.Normal;
            renderable.RenderObjectId = Render.GetRenderObjectID();
            renderable.Material = Physics.GetMaterialAt(hitInfo.Position);

            decalHandler.AddDecal(ref renderable);
        }
Beispiel #25
0
        public void DoDamageInternal(float damage, MyStringHash damageType, bool addDirtyParts = true, MyHitInfo? hitInfo = null, long attackerId = 0)
        {
            if (!CubeGrid.BlocksDestructionEnabled && !ForceBlockDestructible)
                return;

            damage *= DamageRatio; // Low-integrity blocks get more damage
            if (MyPerGameSettings.Destruction || MyFakes.ENABLE_VR_BLOCK_DEFORMATION_RATIO)
            {
                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, attackerId: attackerId);
                }
            }
            finally { ProfilerShort.End(); }

            MyDamageInformation damageInfo = new MyDamageInformation(false, damage, damageType, attackerId);
            if (UseDamageSystem)
                MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref damageInfo);

            MySession.Static.NegativeIntegrityTotal += damageInfo.Amount;
            Debug.Assert(damageInfo.Amount > 0);
            AccumulatedDamage += damageInfo.Amount;

            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(damageInfo.Amount - m_componentStack.Integrity, gridPhysics, hitInfo.Value.Position, hitInfo.Value.Normal, maxDestructionRadius);
                }
                else
                {
                    ApplyAccumulatedDamage(addDirtyParts, attackerId: attackerId);
                }
                CubeGrid.RemoveFromDamageApplication(this);
            }
            else
            {
                if (MyFakes.SHOW_DAMAGE_EFFECTS && FatBlock != null && BlockDefinition.RatioEnoughForDamageEffect(BuildIntegrity / MaxIntegrity) == false && BlockDefinition.RatioEnoughForDamageEffect((Integrity - damage) / MaxIntegrity))
                    FatBlock.SetDamageEffect(true);
            }

            if (UseDamageSystem)
                MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageInfo);

            m_lastDamage = damage;
            m_lastAttackerId = attackerId;
            m_lastDamageType = damageType;
        }
Beispiel #26
0
 public bool DoDamage(float damage, MyStringHash damageType, bool sync, MyHitInfo? hitInfo, long attackerId)
 {
     GameLogic.DoDamage(damage, damageType, sync, hitInfo, attackerId);
     return true;
 }
Beispiel #27
0
        static void DoDamageSynced(MySlimBlock block, float damage, MyStringHash damageType, MyHitInfo? hitInfo, long attackerId)
        {
            var msg = new DoDamageSlimBlockMsg();
            msg.GridEntityId = block.CubeGrid.EntityId;
            msg.Position = block.Position;
            msg.Damage = damage;
            msg.HitInfo = hitInfo;
            msg.AttackerEntityId = attackerId;
            msg.CompoundBlockId = 0xFFFFFFFF;

            // Get compound block id
            var blockOnPosition = block.CubeGrid.GetCubeBlock(block.Position);
            if (blockOnPosition != null && block != blockOnPosition && blockOnPosition.FatBlock is MyCompoundCubeBlock)
            {
                MyCompoundCubeBlock compound = blockOnPosition.FatBlock as MyCompoundCubeBlock;
                ushort? compoundBlockId = compound.GetBlockId(block);
                if (compoundBlockId != null)
                    msg.CompoundBlockId = compoundBlockId.Value;
            }

            block.DoDamage(damage, damageType, hitInfo: hitInfo, attackerId: attackerId);
#if !XB1_NOMULTIPLAYER
            MyMultiplayer.RaiseStaticEvent(s => MySlimBlock.DoDamageSlimBlock, msg);
#endif // !XB1_NOMULTIPLAYER
        }
Beispiel #28
0
 void IMyDecalProxy.AddDecals(MyHitInfo hitInfo, MyStringHash source, object customdata, IMyDecalHandler decalHandler)
 {
     // TODO
 }
 bool IMyDestroyableObject.DoDamage(float damage, MyStringHash damageType, bool sync, MyHitInfo? hitInfo, long attackerId)
 {
     return DoDamage(damage, damageType, sync, attackerId);
 }
Beispiel #30
0
 private Vector3D PlaceDecal()
 {
     Vector3D explosionPoint = m_collisionPoint.Value;
     MyHitInfo hitInfo = new MyHitInfo() { Position = explosionPoint, Normal = m_collisionNormal };
     MyDecals.HandleAddDecal(m_collidedEntity, hitInfo, this.m_missileAmmoDefinition.PhysicalMaterial);
     return explosionPoint;
 }