public static void DamageHandler( object target, ref MyDamageInformation info )
        {
            if ( !PluginSettings.Instance.ProtectedEnabled )
                return;

            IMySlimBlock block = target as IMySlimBlock;
            if ( block == null )
                return;

            IMyCubeGrid grid = block.CubeGrid;
                        ulong steamId = PlayerMap.Instance.GetSteamId( info.AttackerId );

            foreach ( ProtectedItem item in PluginSettings.Instance.ProtectedItems )
            {
                if ( item.Enabled && item.EntityId == grid.EntityId )
                {
                    //TODO: figure out how to get owner of a grinder
                    /*
                    if ( info.Type == MyDamageType.Grind || info.Type == MyDamageType.Weld )
                    {
                        
                        IMyEntity weapon;
                        if ( !MyAPIGateway.Entities.TryGetEntityById( info.AttackerId, out weapon ) )
                            return;

                        
                        Wrapper.GameAction( ( ) =>
                         {
                             if(weapon.GetObjectBuilder() == MyObjectBuilder_AngleGrinderDefinition )
                            {
                                var grinder = (MyObjectBuilder_AngleGrinderDefinition)weapon;
                                grinder.own
                         } );


                        if ( PlayerManager.Instance.IsUserAdmin( steamId ) || grid.BigOwners.Contains( info.AttackerId ) )
                            return;
                    }
                    //grid owners and admins can grind or weld protected grids
                    */

                    //else
                    //{
                        info.Amount = 0;
                        if ( DateTime.Now - _lastLog > TimeSpan.FromSeconds( 1 ) )
                        {
                            _lastLog = DateTime.Now;
                            Essentials.Log.Info( "Protected entity {0}.", grid.DisplayName );
                            //Essentials.Log.Info( "Protected entity \"{0}\" from player \"{1}\".", grid.DisplayName, PlayerMap.Instance.GetFastPlayerNameFromSteamId( steamId ) );
                        }
                    //}
                }
            }
        }
示例#2
0
        public static void DamageHandler(Object obj, ref MyDamageInformation info)
        {
            try
            {
                IMySlimBlock targetBlock = obj as IMySlimBlock;
                IMyCubeGrid targetGrid = targetBlock.CubeGrid;

                if (Storage.Data.Grids.Grids.Find(g => g.Id == targetGrid.EntityId) != null)
                {
                    info.Amount = 0f;
                }

                return;
            }
            catch { }
        }
示例#3
0
        protected override bool Activate(HashSet<MySlimBlock> targets)
        {
            m_otherGrid = null;
            if (targets.Count > 0)
            {
                m_otherGrid = targets.FirstElement().CubeGrid;
            }
            if (Sync.IsServer)
            {             
                float coefficient = (MyShipGrinderConstants.GRINDER_COOLDOWN_IN_MILISECONDS * 0.001f) / targets.Count;             
                foreach (var block in targets)
                {
                    if ((MySession.Static.IsScenario || MySession.Static.Settings.ScenarioEditMode) && !block.CubeGrid.BlocksDestructionEnabled)
                        continue;

                    m_otherGrid = block.CubeGrid;

                    float damage = MySession.Static.GrinderSpeedMultiplier * MyShipGrinderConstants.GRINDER_AMOUNT_PER_SECOND * coefficient;
                    MyDamageInformation damageInfo = new MyDamageInformation(false, damage, MyDamageType.Grind, EntityId);

                    if (block.UseDamageSystem)
                        MyDamageSystem.Static.RaiseBeforeDamageApplied(block, ref damageInfo);

                    block.DecreaseMountLevel(damageInfo.Amount, Inventory);
                    block.MoveItemsFromConstructionStockpile(Inventory);

                    if (block.UseDamageSystem)
                        MyDamageSystem.Static.RaiseAfterDamageApplied(block, damageInfo);
                    
                    if (block.IsFullyDismounted)
                    {
                        if (block.FatBlock is IMyInventoryOwner) EmptyBlockInventories(block.FatBlock as IMyInventoryOwner);

                        if(block.UseDamageSystem)
                            MyDamageSystem.Static.RaiseDestroyed(block, damageInfo);

                        block.SpawnConstructionStockpile();
                        block.CubeGrid.RazeBlock(block.Min);
                    }
                }
                
            }
            m_wantsToShake = targets.Count != 0;
            return targets.Count != 0;
        }
示例#4
0
        public void DamageHandler(object entity, ref MyDamageInformation info)
        {
            try
            {
                long attacker = info.AttackerId;
                MyAPIGateway.Utilities.ShowMessage("", info.AttackerId.ToString());

                
                MDInfo sourceDriver = Data.Drivers.Find(d => d.Id == attacker);
                if (sourceDriver != null)
                {
                    info.Amount = info.Amount * sourceDriver.DamageMultiplier;
                }
            }
            catch
            {

            }
        }
        private static void DamageHandler(object target, ref MyDamageInformation info)
        {
            if (!Config.ProtectionEnabled)
                return;

            IMySlimBlock block = target as IMySlimBlock;

            if (block != null)
            {
                if (CanDamageBlock(info.AttackerId, block, info.Type))
                    return;

                info.Amount = 0;
                return;
            }

            IMyCharacter character = target as IMyCharacter;
            if (character != null)
            {
                var players = new List<IMyPlayer>();
                MyAPIGateway.Players.GetPlayers(players, p => p != null && p.Controller.ControlledEntity != null && p.Controller.ControlledEntity.Entity != null);

                var player = players.FirstOrDefault(p => p.GetCharacter() == character);
                if (player == null)
                    return;

                if (!IsProtected(player.Controller.ControlledEntity.Entity))
                    return;

                if (info.Type == MyDamageType.LowPressure || info.Type == MyDamageType.Asphyxia ||
                    info.Type == MyDamageType.Environment || info.Type == MyDamageType.Fall ||
                    info.Type == MyDamageType.Fire || info.Type == MyDamageType.Radioactivity ||
                    info.Type == MyDamageType.Suicide || info.Type == MyDamageType.Unknown)
                    return;

                info.Amount = 0;
            }
        }
示例#6
0
		public static void KillCharacter(MyCharacter character, MyDamageInformation damageInfo)
		{
			Debug.Assert(Sync.IsServer, "KillCharacter called from client");
			KillCharacterMsg msg = new KillCharacterMsg()
			{
				entityId = character.EntityId,
                DamageInfo = damageInfo
			};

			character.Kill(false, damageInfo);
			Sync.Layer.SendMessageToAll<KillCharacterMsg>(ref msg);
		}
 /// <summary>
 /// Raised before damage is applied.  Can be modified.
 /// </summary>
 /// <param name="target">The target object</param>
 /// <param name="info">Information about the damage.  Can be modified</param>
 public void RaiseBeforeDamageApplied(object target, ref MyDamageInformation info)
 {
     foreach (var item in m_beforeDamageHandlers)
         item.Item2(target, ref info);
 }
 /// <summary>
 /// Raised after damage is applied
 /// </summary>
 /// <param name="target">The target object</param>
 /// <param name="info">Information about the damage</param>
 public void RaiseAfterDamageApplied(object target, MyDamageInformation info)
 {
     foreach (var item in m_afterDamageHandlers)
         item.Item2(target, info);
 }
示例#9
0
        public bool DoDamage(float damage, MyStringHash damageType, bool updateSync, long attackerId = 0)
        {
           if ((!CharacterCanDie && !(damageType == MyDamageType.Suicide && MyPerGameSettings.CharacterSuicideEnabled)) || StatComp == null)
                return false;

            MyEntity attacker;
            if (damageType != MyDamageType.Suicide && MyEntities.TryGetEntityById(attackerId, out attacker))
            {   // Checking friendly fire using faction's friendly fire settings
                var localPlayer = MyPlayer.GetPlayerFromCharacter(this);
                MyPlayer otherPlayer = null;
                if (attacker == this)
                {
                    return false;
                }
                else if (attacker is MyCharacter)
                {
                    otherPlayer = MyPlayer.GetPlayerFromCharacter(attacker as MyCharacter);
                }
                else if (attacker is IMyGunBaseUser)
                {
                    otherPlayer = MyPlayer.GetPlayerFromWeapon(attacker as IMyGunBaseUser);
                }
                else if (attacker is MyHandDrill)
                {
                    otherPlayer = MyPlayer.GetPlayerFromCharacter((attacker as MyHandDrill).Owner);
                }

                if (localPlayer != null && otherPlayer != null)
                {
                    var localPlayerFaction = MySession.Static.Factions.TryGetPlayerFaction(localPlayer.Identity.IdentityId) as MyFaction;
                    if (localPlayerFaction != null && !localPlayerFaction.EnableFriendlyFire && localPlayerFaction.IsMember(otherPlayer.Identity.IdentityId))
                    {
                        return false; // No Friendly Fire Enabled!
                    }
                }
            }

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

            if (damageInfo.Amount <= 0f)
                return false;

            StatComp.DoDamage(damage, updateSync, damageInfo);

            // Cache the last damage information for the analytics module.
            MyAnalyticsHelper.SetLastDamageInformation(damageInfo);

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

            return true;
        }
示例#10
0
 /// <summary>
 /// Raised when an object is destroyed.
 /// </summary>
 /// <param name="target">The target object</param>
 /// <param name="info">Information about the damage</param>
 public void RaiseDestroyed(object target, MyDamageInformation info)
 {
     foreach (var item in m_destroyHandlers)
         item.Item2(target, info);
 }
示例#11
0
        public void Kill(bool sync, MyDamageInformation damageInfo)
        {
            if (m_dieAfterSimulation || IsDead || (MyFakes.DEVELOPMENT_PRESET && damageInfo.Type != MyDamageType.Suicide))
                return;

            if (sync)
            {
                KillCharacter(damageInfo);
                return;
            }

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

            MyAnalyticsHelper.SetLastDamageInformation(damageInfo);

            m_dieAfterSimulation = true;
        }
示例#12
0
        public void DoDamage(float damage, Common.ObjectBuilders.Definitions.MyDamageType 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);
                }
            }
        }
示例#13
0
        private void Grind()
        {
            var block = GetTargetBlock();
            if (block != null)
            {
                float hackMultiplier = 1.0f;
                if (block.FatBlock != null && Owner != null && Owner.ControllerInfo.Controller != null && Owner.ControllerInfo.Controller.Player != null)
                {
                    var relation = block.FatBlock.GetUserRelationToOwner(Owner.ControllerInfo.Controller.Player.Identity.IdentityId);
                    if (relation == MyRelationsBetweenPlayerAndBlock.Enemies || relation == MyRelationsBetweenPlayerAndBlock.Neutral)
                        hackMultiplier = MySession.Static.HackSpeedMultiplier;
                }

                float damage = GrinderAmount;
                MyDamageInformation damageInfo = new MyDamageInformation(false, damage * hackMultiplier, MyDamageType.Grind, EntityId);

                if (block.UseDamageSystem)
                    MyDamageSystem.Static.RaiseBeforeDamageApplied(block, ref damageInfo);

                block.DecreaseMountLevel(damageInfo.Amount, CharacterInventory);
                block.MoveItemsFromConstructionStockpile(CharacterInventory);

                if (block.UseDamageSystem)
                    MyDamageSystem.Static.RaiseAfterDamageApplied(block, damageInfo);
                    
                if (block.IsFullyDismounted)
                {
                    if (block.UseDamageSystem)
                        MyDamageSystem.Static.RaiseDestroyed(block, damageInfo);

                    block.SpawnConstructionStockpile();
                    block.CubeGrid.RazeBlock(block.Min);
                }
            }

            var targetDestroyable = GetTargetDestroyable();
            if (targetDestroyable != null && Sync.IsServer)
                targetDestroyable.DoDamage(20, MyDamageType.Grind, true, attackerId: Owner != null ? Owner.EntityId : 0);
        }
示例#14
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;
            }
示例#15
0
        private void Grind()
        {
            var block = GetTargetBlock();
            MyStringHash target = m_metal;
            if (block != null && (!(MySession.Static.IsScenario || MySession.Static.Settings.ScenarioEditMode) || block.CubeGrid.BlocksDestructionEnabled))
            {
                float hackMultiplier = 1.0f;
                if (block.FatBlock != null && Owner != null && Owner.ControllerInfo.Controller != null && Owner.ControllerInfo.Controller.Player != null)
                {
                    var relation = block.FatBlock.GetUserRelationToOwner(Owner.ControllerInfo.Controller.Player.Identity.IdentityId);
                    if (relation == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies || relation == VRage.Game.MyRelationsBetweenPlayerAndBlock.Neutral)
                        hackMultiplier = MySession.Static.HackSpeedMultiplier;
                }

                float damage = GrinderAmount;
                MyDamageInformation damageInfo = new MyDamageInformation(false, damage * hackMultiplier, MyDamageType.Grind, EntityId);

                if (block.UseDamageSystem)
                    MyDamageSystem.Static.RaiseBeforeDamageApplied(block, ref damageInfo);

                block.DecreaseMountLevel(damageInfo.Amount, CharacterInventory);
                block.MoveItemsFromConstructionStockpile(CharacterInventory);

                if (block.UseDamageSystem)
                    MyDamageSystem.Static.RaiseAfterDamageApplied(block, damageInfo);
                    
                if (block.IsFullyDismounted)
                {
                    if (block.UseDamageSystem)
                        MyDamageSystem.Static.RaiseDestroyed(block, damageInfo);

                    block.SpawnConstructionStockpile();
                    block.CubeGrid.RazeBlock(block.Min);
                }
                if (block.BlockDefinition.PhysicalMaterial.Id.SubtypeName.Length > 0)
                    target = block.BlockDefinition.PhysicalMaterial.Id.SubtypeId;
            }

            var targetDestroyable = GetTargetDestroyable();
            if (targetDestroyable != null)
            {
                //HACK to not grind yourself 
                if(targetDestroyable is MyCharacter && (targetDestroyable as MyCharacter) == Owner)
                {
                    return;
                }

                //damage tracking
                if (targetDestroyable is MyCharacter && MySession.Static.ControlledEntity == this.Owner && (targetDestroyable as MyCharacter).IsDead == false)
                    MySession.Static.TotalDamageDealt += 20;

                targetDestroyable.DoDamage(20, MyDamageType.Grind, true, attackerId: Owner != null ? Owner.EntityId : 0);
                if (targetDestroyable is MyCharacter)
                    target = MyStringHash.GetOrCompute((targetDestroyable as MyCharacter).Definition.PhysicalMaterial);
            }

            if (block != null || targetDestroyable != null)
            {
                m_actualSound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_source, target);
            }
        }
 private static void GodModeDamageHandler_Server(object target, ref MyDamageInformation info)
 {
     if (target is IMyCharacter && Players.Any(p => target == p.Controller.ControlledEntity))
         info.Amount = 0;
 }
        public static void SetLastDamageInformation(MyDamageInformation lastDamageInformation)
        {
            try
            {
                IMyAnalytics analytics = MyPerGameSettings.AnalyticsTracker;
                if (analytics == null)
                    return;
                
                // Empty message is sent from the server, we don't want it to rewrite the true damage cause.
                if (lastDamageInformation.Type == default(MyStringHash))
                    return;

                m_lastDamageInformation = lastDamageInformation;
            }
            catch (Exception ex)
            {
                MyLog.Default.WriteLine(ex);
            }
        }
示例#18
0
 void OnKillCharacter(MyDamageInformation damageInfo)
 {
     Kill(false, damageInfo);
 }
示例#19
0
 private void KillCharacter(MyDamageInformation damageInfo)
 {
     Debug.Assert(Sync.IsServer, "KillCharacter called from client");
     Kill(false, damageInfo);
     MyMultiplayer.RaiseEvent(this, x => x.OnKillCharacter, damageInfo);
 }
示例#20
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 int ApplyDeformation(float deformationOffset, float softAreaPlanar, float softAreaVertical, Vector3 localPos, Vector3 localNormal, MyStringHash damageType, float offsetThreshold = 0, float lowerRatioLimit = 0, long attackerId = 0)
        {
            int blocksDeformed = 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.7f;
            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;

            var softAreaPlanarR = 1.0f / softAreaPlanar;
            var softAreaVerticalR = 1.0f / softAreaVertical;
            var gridSizeR = 1.0f / m_grid.GridSize;
            Vector3D forward = localNormal;
            var up = MyUtils.GetRandomPerpendicularVector(ref forward);
            float minLength = Math.Min(m_grid.GridSize / 256.0f, deformationOffset * 0.06f);

            // When we're sure that there will be destroyed blocks, it's not necessary to do deformations, just do destruction
            MyDamageInformation damageInfo = new MyDamageInformation(true, 1f, MyDamageType.Deformation, attackerId);
            if (destructionPotencial > 0)
            {
                float critVertical = destructionPotencial * softAreaVertical;
                float critPlanar = destructionPotencial * softAreaPlanar;

                var he = new Vector3(critPlanar, critPlanar, critVertical);
                MyOrientedBoundingBox obb = new MyOrientedBoundingBox(gridPos,he, Quaternion.CreateFromForwardUp(forward, up));
                var aabb = obb.GetAABB();

                //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;
                var minOffset = Vector3I.Floor(aabb.Min);
                var maxOffset = Vector3I.Ceiling(aabb.Max);
                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(softAreaPlanarR, softAreaVerticalR, ref localNormal, closestCorner - localPos);
                            }
                            float deformation = maxDef * soften;

                            if (deformation > breakOffsetDestruction)
                            {
                                var block = m_grid.GetCubeBlock(offset);
                                if (block != null)
                                {
                                    if (block.UseDamageSystem)
                                    {
                                        damageInfo.Amount = 1;
                                        MyDamageSystem.Static.RaiseBeforeDamageApplied(block, ref damageInfo);
                                        if (damageInfo.Amount == 0f)
                                            continue;
                                    }

                                    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;
                                    }
                                    blocksDeformed++;
                                }
                            }
                        }
                    }
                }
                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();
                var boneDensity = m_grid.Skeleton.BoneDensity;
                ProfilerShort.Begin("Update deformation");
                MyOrientedBoundingBox obb = new MyOrientedBoundingBox(
                    gridPos * boneDensity + gridOffset,
                    new Vector3(softAreaPlanar * gridSizeR * boneDensity, softAreaPlanar * gridSizeR * boneDensity , softAreaVertical * gridSizeR * boneDensity),
                    Quaternion.CreateFromForwardUp(forward, up));
                var aabb = obb.GetAABB();

                //float softArea = Math.Max(softAreaPlanar, softAreaVertical);
                //var distBones = new Vector3I((int)Math.Ceiling(softArea / m_grid.GridSize * m_grid.Skeleton.BoneDensity));

                //Vector3I minOffset = gridPos * m_grid.Skeleton.BoneDensity + gridOffset - distBones;
                //Vector3I maxOffset = gridPos * m_grid.Skeleton.BoneDensity + gridOffset + distBones;
                var minOffset = Vector3I.Floor(aabb.Min);
                var maxOffset = Vector3I.Ceiling(aabb.Max);
                minOffset = Vector3I.Max(minOffset, m_grid.Min * m_grid.Skeleton.BoneDensity);
                maxOffset = Vector3I.Min(maxOffset, m_grid.Max * m_grid.Skeleton.BoneDensity);

                Vector3I minDirtyBone = Vector3I.MaxValue;
                Vector3I maxDirtyBone = Vector3I.MinValue;

                ProfilerShort.Begin("Get bones");
                m_tmpBoneList.Clear();
                m_grid.GetExistingBones( minOffset, maxOffset, m_tmpBoneList, damageInfo);
                ProfilerShort.End();

                ProfilerShort.Begin("Deform bones");
                Vector3 bone;
                Vector3I baseOffset = gridPos * m_grid.Skeleton.BoneDensity;
                float boneDensityR = 1.0f / m_grid.Skeleton.BoneDensity;
                var halfGridSize = new Vector3(m_grid.GridSize * 0.5f);

                ProfilerShort.CustomValue("Bone Count", m_tmpBoneList.Count,0);
                foreach (var b in m_tmpBoneList)                
                {
                    var boneIndex = b.Key;

                    var baseBonePos = boneIndex * m_grid.GridSize * boneDensityR - halfGridSize;

                    m_grid.Skeleton.GetBone(ref boneIndex, out bone);
                    var bonePos = bone + baseBonePos;

                    float soften = CalculateSoften(softAreaPlanarR, softAreaVerticalR, ref localNormal, bonePos - localPos);

                    if (soften == 0)
                        continue;

                    min = Vector3I.Min(min, Vector3I.Floor(bonePos * gridSizeR - Vector3.One * boneDensityR));
                    max = Vector3I.Max(max, Vector3I.Ceiling(bonePos *gridSizeR + Vector3.One * boneDensityR));
                    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;

                        if (block2.IsDestroyed) // ||  block2.DoDamage(maxAxisDeformation / m_grid.GridSize, damageType, addDirtyParts: false))
                        {
                            destructionDone = true;
                        }
                    }

                    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);

                    if (canDeform && deformationLength > minLength)
                    {
                        bone += deformation;

                        //m_debugBones.Add(new Tuple<Vector3, float>(bonePos, deformationRatio));
                        var offset = boneIndex - baseOffset;

                        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;
                                    blocksDeformed++;
                                }
                            }
                        }
                        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 blocksDeformed;
        }
        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;
        }
示例#22
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;
        }
示例#23
0
        void Sandbox.ModAPI.IMyCharacter.Kill(object statChangeData)
        {
            MyDamageInformation damageInfo = new MyDamageInformation();
            if (statChangeData != null)
                damageInfo = (MyDamageInformation)statChangeData;

            Kill(true, damageInfo);
        }
 private void GodModeDamageHandler_Client(object target, ref MyDamageInformation info)
 {
     if (GodModeEnabled && target is IMyCharacter && target == MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity)
         info.Amount = 0;
 }
示例#25
0
        private void ApplyVolumetriDamageToGrid(MyDamageInfo damageInfo, long attackerId)
        {
            var damagedBlocks = damageInfo.ExplosionDamage.DamagedBlocks;
            var explodedBlocks = damageInfo.AffectedCubeBlocks;
            var explodedGrids = damageInfo.AffectedCubeGrids;

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("foreach (var damagedBlock in damagedBlocks)");

            if (MyDebugDrawSettings.DEBUG_DRAW_VOLUMETRIC_EXPLOSION_COLORING)
            {
                foreach (var explodedBlock in explodedBlocks)
                {
                    explodedBlock.CubeGrid.ChangeColor(explodedBlock, new Vector3(0.66f, 1f, 1f));
                }
                foreach (var damagedBlock in damagedBlocks)
                {
                    float hue = 1f - damagedBlock.Value / damageInfo.ExplosionDamage.Damage;
                    damagedBlock.Key.CubeGrid.ChangeColor(damagedBlock.Key, new Vector3(hue / 3f, 1.0f, 0.5f));
                }
            }
            else
            {
                foreach (var damagedBlock in damagedBlocks)
                {
                    var cubeBlock = damagedBlock.Key;
                    if (cubeBlock.FatBlock != null && cubeBlock.FatBlock.MarkedForClose)
                        continue;

                    if (!cubeBlock.CubeGrid.BlocksDestructionEnabled)
                        continue;

                    // Allow mods to modify damage.  This will cause a double call.  Once here and once in the DoDamage, but only real way to do a check here
                    MyDamageInformation checkInfo = new MyDamageInformation(false, damagedBlock.Value, MyDamageType.Explosion, attackerId);
                    if (cubeBlock.UseDamageSystem)
                        MyDamageSystem.Static.RaiseBeforeDamageApplied(cubeBlock, ref checkInfo);

                    if (cubeBlock.FatBlock == null && cubeBlock.Integrity / cubeBlock.DeformationRatio < checkInfo.Amount)
                    {
                        VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("RemoveBlock");
                        cubeBlock.CubeGrid.RemoveDestroyedBlock(cubeBlock);
                        VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    }
                    else
                    {
                        VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ApplyDestructionDeformation");
                        float damage = damagedBlock.Value;
                        if (cubeBlock.FatBlock != null)
                        {
                            damage *= 7f;
                        }
                        (cubeBlock as IMyDestroyableObject).DoDamage(damage, MyDamageType.Explosion, true);
                        if (!cubeBlock.IsDestroyed)
                        {
                            cubeBlock.CubeGrid.ApplyDestructionDeformation(cubeBlock);
                        }
                        VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    }

                    foreach (var neighbour in cubeBlock.Neighbours)
                    {
                        neighbour.CubeGrid.Physics.AddDirtyBlock(neighbour);
                    }
                    cubeBlock.CubeGrid.Physics.AddDirtyBlock(cubeBlock);
                }
            }

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            var sphere = damageInfo.Sphere;
            if (!MyDebugDrawSettings.DEBUG_DRAW_VOLUMETRIC_EXPLOSION_COLORING)
            {
                foreach (var grid in explodedGrids)
                {
                    VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("UpdateDirty");
                    grid.UpdateDirty();
                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                    VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("CreateExplosionDebris");
                    if (m_explosionInfo.HitEntity == grid)
                    {
                        BoundingBoxD aabb = BoundingBoxD.CreateFromSphere(new BoundingSphereD(sphere.Center, sphere.Radius * 1.5f));
                        MyDebris.Static.CreateExplosionDebris(ref sphere, grid, ref aabb, 0.5f, false);
                    }

                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                }
            }
        }
        private void IndestructibleDamageHandler(object target, ref MyDamageInformation info)
        {
            if (Config.NoGrindIndestructible && target is IMySlimBlock)
            {
                var block = target as IMySlimBlock;
                var grid = block.CubeGrid;

                if (grid != null && !((MyObjectBuilder_CubeGrid)grid.GetObjectBuilder()).DestructibleBlocks)
                    info.Amount = 0;
            }
        }
示例#27
0
        public void DoDamage(float damage, MyDamageType damageType, bool addDirtyParts = true, MyHitInfo? hitInfo = null, bool createDecal = true, long attackerId = 0)
        {
            if (!CubeGrid.BlocksDestructionEnabled)
                return;

            if(FatBlock is MyCompoundCubeBlock) //jn: TODO think of something better
            {
                (FatBlock as MyCompoundCubeBlock).DoDamage(damage, damageType, hitInfo, attackerId);
                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, 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;
            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);
                }
                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);
            }

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

            m_lastDamage = damage;
            m_lastAttackerId = attackerId;
            m_lastDamageType = damageType;

            return;
        }
示例#28
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;
        }
示例#29
0
        public static void SetLastDamageInformation(MyDamageInformation lastDamageInformation)
        {
            try
            {
                // Empty message is sent from the server, we don't want it to rewrite the true damage cause.
                if (lastDamageInformation.Type == default(MyStringHash))
                    return;

                m_lastDamageInformation = lastDamageInformation;
            }
            catch (Exception ex)
            {
                MyLog.Default.WriteLine(ex);
            }
        }