// Mod actions

        public static void checkDamage(object block, ref MyDamageInformation info)
        {
            if (info.Type != MyDamageType.Bullet && info.Type != MyDamageType.Rocket)
            {
                return;
            }
            var slimBlock = block as IMySlimBlock;                              if (slimBlock == null)
            {
                return;
            }
            var dmgBlock = slimBlock as IMyDestroyableObject;   if (dmgBlock == null || dmgBlock.Integrity > info.Amount)
            {
                return;
            }
            var grid = slimBlock.CubeGrid as IMyCubeGrid;       if (grid == null)
            {
                return;
            }
            var deltaDamage = info.Amount - dmgBlock.Integrity;

            info.Amount = dmgBlock.Integrity;
            Vector3D        pos    = grid.GridIntegerToWorld(slimBlock.Position);
            BoundingSphereD sphere = new BoundingSphereD(pos, deltaDamage / 500f);
            MyExplosionInfo bomb   = new MyExplosionInfo(deltaDamage * 0.8f, deltaDamage * 0.8f, sphere, MyExplosionTypeEnum.BOMB_EXPLOSION, false, true);

            bomb.CreateParticleEffect = true;
            MyExplosions.AddExplosion(ref bomb, true);
        }
Beispiel #2
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);
                    }
                }
            }
        }
        private void DamageHandler(IMySlimBlock block, MyDamageInformation damage)
        {
            //if (AiSessionCore.WarDeclared) return;
            //if (Damaged) return;
            //Damaged = true;

            IMyPlayer damager;

            ReactOnDamage(damage, out damager);

            if (_fighterSetup.DelayedAiEnable)
            {
                LoadKeenAi();
            }

            foreach (IMyTimerBlock timer in Term.GetBlocksOfType <IMyTimerBlock>(collect: x => x.IsFunctional && x.Enabled &&
                                                                                 x.CustomName.Contains("Damage")))
            {
                timer.Trigger();
            }

            if (!_fighterSetup.CallHelpOnDamage)
            {
                return;
            }

            foreach (IMyTimerBlock timer in Term.GetBlocksOfType <IMyTimerBlock>(collect: x => x.IsFunctional && x.Enabled &&
                                                                                 x.CustomName.Contains("Security")))
            {
                timer.Trigger();
            }
        }
Beispiel #4
0
        private void DamageHandler(IMySlimBlock Block, MyDamageInformation Damage)
        {
            if (Damaged)
            {
                return;
            }
            Damaged = true;

            IMyPlayer Damager;

            ReactOnDamage(Block, Damage, CalmdownTime, out Damager);

            if (FighterSetup.DelayedAIEnable)
            {
                LoadKeenAI();
            }

            foreach (IMyTimerBlock Timer in Term.GetBlocksOfType <IMyTimerBlock>(collect: x => x.IsFunctional && x.Enabled &&
                                                                                 x.CustomName.Contains("Damage")))
            {
                Timer.Trigger();
            }

            if (!FighterSetup.CallHelpOnDamage)
            {
                return;
            }

            foreach (IMyTimerBlock Timer in Term.GetBlocksOfType <IMyTimerBlock>(collect: x => x.IsFunctional && x.Enabled &&
                                                                                 x.CustomName.Contains("Security")))
            {
                Timer.Trigger();
            }
        }
Beispiel #5
0
        private static void AfterDamageHandler(object obj, MyDamageInformation damageInfo)
        {
            if (!(obj is IMySlimBlock))
            {
                return;
            }

            // grind damage is handled by OnBlockIntegrityChanged, which is faster
            if (damageInfo.Type == MyDamageType.Grind)
            {
                return;
            }

            IMySlimBlock block  = (IMySlimBlock)obj;
            long         gridId = block.CubeGrid.EntityId;

            Registrar.ForEach((Projector proj) => {
                SeenHolo sh;
                if (!proj.m_holoEntities.TryGetValue(gridId, out sh) || !sh.Holo.Render.Visible || !sh.ColouredByIntegrity)
                {
                    return;
                }
                ColourBlock(block, (IMyCubeGrid)sh.Holo);
            });
        }
Beispiel #6
0
 public void GenericDamageHandler(object DamagedObject, MyDamageInformation Damage)
 {
     try
     {
         if (DamagedObject == null)
         {
             return;
         }
         if (!(DamagedObject is IMySlimBlock))
         {
             return;
         }
         IMySlimBlock DamagedBlock = DamagedObject as IMySlimBlock;
         IMyCubeGrid  DamagedGrid  = DamagedBlock.CubeGrid;
         long         GridID       = DamagedGrid.GetTopMostParent().EntityId;
         if (DamageHandlers.ContainsKey(GridID))
         {
             try
             {
                 DamageHandlers[GridID].Invoke(DamagedBlock, Damage);
             }
             catch (Exception Scrap)
             {
                 LogError("DamageHandler.Invoke", Scrap);
             }
         }
     }
     catch (Exception Scrap)
     {
         LogError("GenericDamageHandler", Scrap);
     }
 }
Beispiel #7
0
        internal void BeforeDamageHandler(object o, ref MyDamageInformation info)
        {
            var slim = o as IMySlimBlock;

            if (slim != null)
            {
                var cube = slim.FatBlock as MyCubeBlock;
                var grid = (MyCubeGrid)slim.CubeGrid;

                if (info.IsDeformation && info.AttackerId > 0 && DeformProtection.Contains(grid))
                {
                    Log.Line($"BeforeDamageHandler1");
                    info.Amount = 0f;
                    return;
                }

                CoreComponent comp;
                if (cube != null && ArmorCubes.TryGetValue(cube, out comp))
                {
                    Log.Line($"BeforeDamageHandler2");
                    info.Amount = 0f;
                    if (info.IsDeformation && info.AttackerId > 0)
                    {
                        DeformProtection.Add(cube.CubeGrid);
                        LastDeform = Tick;
                    }
                }
            }
        }
 private void BattleDamage(object target, ref MyDamageInformation info)
 {
     if (target is IMyCharacter || Instance._lobbyRunning)
     {
         info.Amount = 0;
     }
 }
 /// <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>
        /// Determines if damage was done by player.
        /// </summary>
        /// <param name="Damager">Provides player who did the damage. Null if damager object is not a player.</param>
        public static bool IsDoneByPlayer(this MyDamageInformation Damage, out IMyPlayer Damager)
        {
            Damager = null;
            try
            {
                IMyEntity AttackerEntity = MyAPIGateway.Entities.GetEntityById(Damage.AttackerId);
                if (AttackerEntity == null)
                {
                    AISessionCore.DebugWrite("Damage.IsDoneByPlayer", "Attacker entity was not found.", AntiSpam: false);
                    return(false);
                }

                if (AttackerEntity is IMyMeteor)
                {
                    return(false);
                }
                if (AttackerEntity is IMyWarhead)
                {
                    return(IsDamagedByPlayerWarhead(AttackerEntity as IMyWarhead, out Damager));
                }
                if (AttackerEntity is IMyGunBaseUser)
                {
                    return(IsDamagedByPlayer(AttackerEntity as IMyGunBaseUser, out Damager));
                }
                if (AttackerEntity is IMyEngineerToolBase)
                {
                    return(IsDamagedByPlayer(AttackerEntity as IMyEngineerToolBase, out Damager));
                }

                AttackerEntity = AttackerEntity.GetTopMostParent();

                if (AttackerEntity == null)
                {
                    AISessionCore.DebugWrite("Damage.IsDoneByPlayer", "Cannot acquire the attacker's topmost entity", AntiSpam: false);
                    return(false);
                }

                if (AttackerEntity is IMyCubeGrid)
                {
                    IMyCubeGrid Grid = AttackerEntity as IMyCubeGrid;
                    if (Grid.IsPirate())
                    {
                        return(false);
                    }
                    if (Grid.IsOwnedByNobody())
                    {
                        return(IsDamagedByPlayerInNeutralGrid(Grid, out Damager));
                    }

                    return(IsDamagedByPlayerGrid(Grid, out Damager));
                }

                return(false);
            }
            catch (Exception Scrap)
            {
                AISessionCore.LogError("Damage.IsDoneByPlayer", new Exception("General crash.", Scrap));
                return(false);
            }
        }
        public void GenericDamageHandler(object target, MyDamageInformation info)
        {
            if (target == null || !(target is IMySlimBlock))
            {
                return;
            }
            IMySlimBlock block          = target as IMySlimBlock;
            IMyCubeGrid  grid           = block.CubeGrid;
            long         gridId         = grid.GetTopMostParent().EntityId;
            IMyFaction   damageeFaction = grid.GetOwningFaction();

            IMyPlayer   damagerPlayer;
            IMyFaction  damagerFaction;
            IMyCubeGrid damagerShip;

            if (damageeFaction != null &&
                info.GetSource(out damagerPlayer, out damagerFaction, out damagerShip))
            {
                if (damagerFaction == null)
                {
                    return;
                }
                EmpireData damagerEmpire = damagerFaction.GetEmpire();
                foreach (EmpireManager empire in m_empireManagers)
                {
                    if (empire.GetData().empireTag == damageeFaction.Tag)
                    {
                        empire.TakeStandingsHit(damagerEmpire);
                        break;
                    }
                }
            }
        }
 /// <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);
     }
 }
 /// <summary>
 /// Damage Handler: Prevent Damage from BuildAndRepairSystem
 /// </summary>
 public void BeforeDamageHandlerNoDamageByBuildAndRepairSystem(object target, ref MyDamageInformation info)
 {
     try
     {
         if (info.Type == MyDamageType.Weld)
         {
             if (target is IMyCharacter)
             {
                 var logicalComponent = BuildAndRepairSystems.GetValueOrDefault(info.AttackerId);
                 if (logicalComponent != null)
                 {
                     var terminalBlock = logicalComponent.Entity as IMyTerminalBlock;
                     if (Mod.Log.ShouldLog(Logging.Level.Communication))
                     {
                         Mod.Log.Write(Logging.Level.Communication, "BuildAndRepairSystemMod: Prevent Damage from BuildAndRepairSystem={0} Amount={1}", terminalBlock != null ? terminalBlock.CustomName : logicalComponent.Entity.DisplayName, info.Amount);
                     }
                     info.Amount = 0;
                 }
             }
         }
     }
     catch (Exception e)
     {
         Mod.Log.Error("BuildAndRepairSystemMod: Exception in BeforeDamageHandlerNoDamageByBuildAndRepairSystem: Source={0}, Message={1}", e.Source, e.Message);
     }
 }
 private static void GodModeDamageHandler_Server(object target, ref MyDamageInformation info)
 {
     if (target is IMyCharacter && _players.Any(p => target == p.Character))
     {
         info.Amount = 0;
     }
 }
 private void GodModeDamageHandler_Client(object target, ref MyDamageInformation info)
 {
     if (GodModeEnabled && target is IMyCharacter && target == MyAPIGateway.Session.Player.Character)
     {
         info.Amount = 0;
     }
 }
Beispiel #16
0
        private void DamageHandler(object target, ref MyDamageInformation info)
        {
            if (!PluginSettings.Instance.ProtectedEnabled)
            {
                return;
            }

            MySlimBlock block = target as MySlimBlock;

            if (block == null)
            {
                return;
            }

            MyCubeGrid grid = block.CubeGrid;

            foreach (ProtectedItem item in PluginSettings.Instance.ProtectedItems)
            {
                if (!item.Enabled || !item.ProtectDamage || item.EntityId != grid.EntityId)
                {
                    continue;
                }

                if (DateTime.Now - _lastLog > TimeSpan.FromSeconds(1))
                {
                    _lastLog = DateTime.Now;
                    Essentials.Log.Info($"Protected entity {grid.DisplayName}:{grid.EntityId}.");
                }
                if (!item.LogOnly)
                {
                    info.Amount = 0;
                }
            }
        }
 /// <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);
     }
 }
Beispiel #18
0
        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 ) );
                    }
                    //}
                }
            }
        }
 private void GenericDamageHandler(object damagedObject, MyDamageInformation damage)
 {
     try
     {
         if (!(damagedObject is IMySlimBlock))
         {
             return;
         }
         IMySlimBlock damagedBlock = (IMySlimBlock)damagedObject;
         IMyCubeGrid  damagedGrid  = damagedBlock.CubeGrid;
         long         gridId       = damagedGrid.EntityId;
         if (!DamageHandlers.ContainsKey(gridId))
         {
             return;
         }
         try
         {
             DamageHandlers[gridId].Invoke(damagedBlock, damage);
         }
         catch (Exception Scrap)
         {
             LogErrorInDebugLog("GenericDamageHandler", "Grid damage handler threw: ", Scrap);
         }
     }
     catch (Exception Scrap)
     {
         LogErrorInDebugLog("GenericDamageHandler", "Damage handler procedure bugged out: ", Scrap);
     }
 }
Beispiel #20
0
        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);
        }
        private void BeforeDamage(object target, ref MyDamageInformation info)
        {
            if (info.Amount == 0)
            {
                return;
            }

            var slim = target as IMySlimBlock;

            if (slim == null)
            {
                return;
            }

            // if any of the protection blocks are on this grid then protect it
            foreach (var block in ProtectionBlocks)
            {
                // checks for same grid-group to extend protection to piston/rotors/wheels but no connectors (change link type to Physical to include those)
                // same grid only check: block.CubeGrid == slim.CubeGrid
                if (MyAPIGateway.GridGroups.HasConnection(block.CubeGrid, slim.CubeGrid, GridLinkTypeEnum.Mechanical))
                {
                    info.Amount = 0;
                    return;
                }
            }
        }
Beispiel #22
0
        /// <summary>
        /// Handles the damage in ProtectionAreas if Protection is enabled. This method is desinged for server side use and will notify the players if they tried to damage the wrong block.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="info"></param>
        private static void DamageHandler_Server(object target, ref MyDamageInformation info)
        {
            if (!Config.ProtectionEnabled)
            {
                return;
            }

            IMySlimBlock block = target as IMySlimBlock;

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

                info.Amount = 0;

                // notify player
                DateTime time;
                if (player != null && (!_sentFailedMessage.TryGetValue(player, out time) || DateTime.Now - time >= TimeSpan.FromMilliseconds(GrindFailedMessageInterval)))
                {
                    MessageClientNotification.SendMessage(player.SteamUserId, "You are not allowed to damage this block.", GrindFailedMessageInterval, MyFontEnum.Red);
                    _sentFailedMessage.Update(player, DateTime.Now);
                }

                return;
            }

            // disable pvp in PAs
            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;
            }
        }
Beispiel #23
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, this.GetInventory());
                    block.MoveItemsFromConstructionStockpile(this.GetInventory());

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

                    if (block.IsFullyDismounted)
                    {
                        if (block.FatBlock != null && block.FatBlock.HasInventory)
                        {
                            EmptyBlockInventories(block.FatBlock);
                        }

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

                        block.SpawnConstructionStockpile();
                        block.CubeGrid.RazeBlock(block.Min);
                    }
                }
                if (targets.Count > 0)
                {
                    SetBuildingMusic(200);
                }
            }
            m_wantsToShake = targets.Count != 0;
            return(targets.Count != 0);
        }
Beispiel #24
0
        private void Grind()
        {
            var block = GetTargetBlock();

            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 == 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)
            {
                //HACK to not grind yourself
                if (targetDestroyable is MyCharacter && (targetDestroyable as MyCharacter) == Owner)
                {
                    return;
                }

                targetDestroyable.DoDamage(20, MyDamageType.Grind, true, attackerId: Owner != null ? Owner.EntityId : 0);
            }
        }
Beispiel #25
0
        /// <summary>
        /// Determines if damage was done by player.
        /// </summary>
        /// <param name="damage"></param>
        /// <param name="damager">Provides player who did the damage. Null if damager object is not a player.</param>
        public static bool IsDoneByPlayer(this MyDamageInformation damage, out IMyPlayer damager)
        {
            damager = null;

            try
            {
                IMyEntity attackerEntity = MyAPIGateway.Entities.GetEntityById(damage.AttackerId);
                if (damage.IsDeformation || damage.AttackerId == 0 || attackerEntity == null)
                {
                    return(false);
                }

                if (attackerEntity is IMyMeteor)
                {
                    return(false);
                }
                if (attackerEntity is IMyWarhead)
                {
                    return(IsDamagedByPlayerWarhead(attackerEntity as IMyWarhead, out damager));
                }
                if (attackerEntity is IMyEngineerToolBase)
                {
                    return(IsDamagedByPlayer(attackerEntity as IMyEngineerToolBase, out damager));
                }
                if (attackerEntity is IMyGunBaseUser)
                {
                    return(IsDamagedByPlayer(attackerEntity as IMyGunBaseUser, out damager));
                }

                attackerEntity = attackerEntity.GetTopMostParent();

                if (attackerEntity == null)
                {
                    AiSessionCore.DebugLog?.WriteToLog("IsDoneByPlayer", $"attackerEntity was NULL");
                    AiSessionCore.DebugWrite("Damage.IsDoneByPlayer", "Cannot acquire the attacker's topmost entity", antiSpam: false);
                    return(false);
                }

                if (!(attackerEntity is IMyCubeGrid))
                {
                    return(false);
                }
                IMyCubeGrid grid = attackerEntity as IMyCubeGrid;
                if (grid.IsPirate())
                {
                    return(false);
                }
                //grid.GetOwnerFaction()
                return(grid.IsOwnedByNobody() ? IsDamagedByPlayerInNeutralGrid(grid, out damager) : IsDamagedByPlayerGrid(grid, out damager));
            }
            catch (Exception scrap)
            {
                AiSessionCore.LogError("Damage.IsDoneByPlayer", new Exception("General crash.", scrap));
                return(false);
            }
        }
    /**
     * Determine the source Player and Ship associated with a damage event.
     * Returns false if the event was environmental, or no player/ship can be determined.
     */
    public static bool GetSource(
        this MyDamageInformation info,
        out IMyPlayer damagePlayer,
        out IMyFaction damageFaction,
        out IMyCubeGrid damageShip) {
      damagePlayer = null;
      damageFaction = null;
      damageShip = null;

      IMyEntity entity = MyAPIGateway.Entities.GetEntityById(info.AttackerId);
      if (entity == null) {
        return false;
      }
      if (entity is IMyMeteor) {
        return false;
      }
      if (entity is IMyThrust) {
        return false;
      }
      if (entity is IMyWarhead) {
        return GetPlayerByWarhead(
            entity as IMyWarhead,
            out damagePlayer,
            out damageFaction);
      }

      entity = entity.GetTopMostParent();
      if (entity == null) {
        return false;
      }

      if (entity is IMyCubeGrid) {
        damageShip = entity as IMyCubeGrid;
        damagePlayer = damageShip.GetControllingPlayer();
        if (damagePlayer == null) {
          damagePlayer = damageShip.GetOwningPlayer();
        }
        damageFaction = damageShip.GetOwningFaction();
      } else {
        if (entity is IMyEngineerToolBase) {
          return GetPlayerByTool(
              entity as IMyEngineerToolBase,
              out damagePlayer,
              out damageFaction);
        }

        if (entity is IMyGunBaseUser) {
          return GetPlayerByWeapon(
              entity as IMyGunBaseUser,
              out damagePlayer,
              out damageFaction);
        }
      }

      return damageShip != null || damageFaction != null || damagePlayer != null;
    }
Beispiel #27
0
        private void GridDamaged(IMyEntity grid, MyDamageInformation info)
        {
            IDamageObserver observer;

            if (damageObservers.TryGetValue(grid.EntityId, out observer))
            {
                //MyAPIGateway.Utilities.ShowNotification("Attacker ID: " + info.AttackerId);
                observer.MaliciouslyDamaged();
            }
        }
        public void CheckDamage(object block, ref MyDamageInformation info)
        {
            if (info.Type == MyDamageType.Deformation) // fix
            {
            }

            if (Shields.Count == 0 || info.Type != MyDamageType.Bullet)
            {
                return;
            }

            var generator = Shields[0];
            var ent       = block as IMyEntity;
            var slimBlock = block as IMySlimBlock;

            if (slimBlock != null)
            {
                ent = slimBlock.CubeGrid;
            }
            var dude = block as IMyCharacter;

            if (dude != null)
            {
                ent = dude;
            }
            if (ent == null)
            {
                return;
            }
            var isProtected = false;

            foreach (var shield in Shields)
            {
                if (shield.InHash.Contains(ent))
                {
                    isProtected = true;
                    generator   = shield;
                }
            }
            if (!isProtected)
            {
                return;
            }
            IMyEntity attacker;

            if (!MyAPIGateway.Entities.TryGetEntityById(info.AttackerId, out attacker))
            {
                return;
            }
            if (generator.InHash.Contains(attacker))
            {
                return;
            }
            info.Amount = 0f;
        }
Beispiel #29
0
        void DestroyHandler(object target, MyDamageInformation damage)
        {
            if (damage.Type == MyDamageType.Grind)
            {
                MyDefinitionId blockId = new MyDefinitionId();
                MyRelationsBetweenPlayerAndBlock relation = new MyRelationsBetweenPlayerAndBlock();
                string      faction = "none";
                IMyFaction  plFaction;
                List <long> owners  = new List <long>();
                long        ownerID = -1;

                IMyEntity ent;

                MyAPIGateway.Entities.TryGetEntityById(damage.AttackerId, out ent);
                var       hand = ent as IMyHandheldGunObject <MyToolBase>;
                IMyPlayer pl;
                if (hand != null && hand.DefinitionId.TypeId == typeof(MyObjectBuilder_AngleGrinder))
                {
                    var players = new List <IMyPlayer>();
                    MyAPIGateway.Players.GetPlayers(players);
                    pl        = players.FirstOrDefault(p => p.IdentityId.Equals(hand.OwnerIdentityId));
                    plFaction = MyAPIGateway.Session.Factions.TryGetPlayerFaction(pl.IdentityId);
                }
                else
                {
                    //If nothing was returned from Entity
                    return;
                }

                if (target is IMySlimBlock)
                {
                    IMySlimBlock slim = target as IMySlimBlock;
                    blockId  = slim.BlockDefinition.Id;
                    relation = slim.FatBlock.GetUserRelationToOwner(pl.IdentityId);
                    faction  = slim.FatBlock.GetOwnerFactionTag();
                    owners   = slim.CubeGrid.SmallOwners;
                    ownerID  = slim.OwnerId;
                }
                else if (target is IMyCubeBlock) //just in cause
                {
                    var fat = target as IMyCubeBlock;
                    blockId  = fat.BlockDefinition;
                    relation = fat.GetUserRelationToOwner(pl.IdentityId);
                    faction  = fat.GetOwnerFactionTag();
                    owners   = fat.CubeGrid.SmallOwners;
                    ownerID  = fat.OwnerId;//fat.OwnerBlock.BuiltBy;
                }
                MyLog.Default.WriteLine($"OwnerID {ownerID} Owner {relation.ToString()} - Player {pl.IdentityId} Faction {faction} - Player Faction {plFaction.Tag} Built By {owners.Count}");
                if (owners.Count > 0 && faction != plFaction.Tag && !owners.Contains(pl.IdentityId))
                {
                    CalculatePlayers(blockId, ent, pl);
                }
            }
        }
Beispiel #30
0
 private void CauseKeenHacks(object target, MyDamageInformation info)
 {
     // Missles apply damage by blowing up. it is considered a damage by player...
     if (target.GetType().Name == "MyMissile")
     {
         IMyEntity entity = MyAPIGateway.Entities.GetEntityById(info.AttackerId);
         if (entity != null)
         {
             entity.Name = (target as IMyEntity).Name; // more hacks
         }
     }
 }
Beispiel #31
0
        private void BeforeDamageApplied(object target, ref MyDamageInformation info)
        {
            IMySlimBlock slim = target as IMySlimBlock;
            if (slim == null)
                return;

            IMyVoxelBase voxel;
            if (!miners.TryGetValue(slim.CubeGrid, out voxel))
                return;

            if (voxel.EntityId == info.AttackerId)
                info.Amount = 0f;
        }
Beispiel #32
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);
 }
Beispiel #33
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;
        }
        private void DamageHandler( object target, ref MyDamageInformation info )
        {
            if ( !PluginSettings.Instance.ProtectedEnabled )
                return;

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

            MyCubeGrid grid = block.CubeGrid;

            foreach ( ProtectedItem item in PluginSettings.Instance.ProtectedItems )
            {
                if ( !item.Enabled || !item.ProtectDamage || item.EntityId != grid.EntityId )
                    continue;

                if ( DateTime.Now - _lastLog > TimeSpan.FromSeconds( 1 ) )
                {
                    _lastLog = DateTime.Now;
                    Essentials.Log.Info( $"Protected entity {grid.DisplayName}:{grid.EntityId}." );
                }
                    if ( !item.LogOnly )
                        info.Amount = 0;
            }
        }
Beispiel #35
0
 /// <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);
 }
Beispiel #36
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, this.GetInventory());
                    block.MoveItemsFromConstructionStockpile(this.GetInventory());

                    if (block.UseDamageSystem)
                        MyDamageSystem.Static.RaiseAfterDamageApplied(block, damageInfo);
                    
                    if (block.IsFullyDismounted)
                    {
                        if (block.FatBlock != null && block.FatBlock.HasInventory)
                        {
                            EmptyBlockInventories(block.FatBlock);
                        }

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

                        block.SpawnConstructionStockpile();
                        block.CubeGrid.RazeBlock(block.Min);
                    }
                }
                if (targets.Count > 0)
                    SetBuildingMusic(200);
            }
            m_wantsToShake = targets.Count != 0;
            return targets.Count != 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;
        }
        public bool DoDamage(float damage, MyStringHash damageType, bool updateSync, long attackerId = 0)
        {
            if (damageType != MyDamageType.Suicide && ControllerInfo.IsLocallyControlled())
            {
                const float maxShake = 5.0f;
                MySector.MainCamera.CameraShake.AddShake(maxShake * damage / (damage + maxShake));
            }

            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!
                    }
                }

                if (damage >= 0f && MySession.Static != null && MyMusicController.Static != null)
                {
                    if (this == MySession.Static.LocalCharacter && attacker is MyVoxelPhysics == false && attacker is MyCubeGrid == false)
                        MyMusicController.Static.Fighting(false, (int)damage * 3);//not fall damage
                    else if (attacker == MySession.Static.LocalCharacter)
                        MyMusicController.Static.Fighting(false, (int)damage * 2);//attack other character
                    else if (attacker is IMyGunBaseUser && (attacker as IMyGunBaseUser).Owner as MyCharacter == MySession.Static.LocalCharacter)
                        MyMusicController.Static.Fighting(false, (int)damage * 2);//attack other character with gun
                    else if (MySession.Static.ControlledEntity == attacker)
                        MyMusicController.Static.Fighting(false, (int)damage);//attack other character with turret
            }
            }

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

            if (updateSync)
                TriggerCharacterAnimationEvent("hurt", true);
            else
                AnimationController.TriggerAction(MyAnimationVariableStorageHints.StrIdActionHurt);

            return true;
        }
Beispiel #39
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)
        {
            if (!m_grid.BlocksDestructionEnabled)
                return 0;

            int blocksDeformed = 0;
            offsetThreshold /= m_grid.GridSizeEnum == MyCubeSize.Large ? 1 : 5;
            float roundSize = m_grid.GridSize / MyGridSkeleton.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 * MyGridSkeleton.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 = MyGridSkeleton.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 * MyGridSkeleton.BoneDensity);
                maxOffset = Vector3I.Min(maxOffset, m_grid.Max * MyGridSkeleton.BoneDensity);

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

                ProfilerShort.Begin("Get bones");
                Debug.Assert(m_tmpBoneList.Count == 0, "Temporary dictionary not cleared properly");
                m_grid.GetExistingBones(minOffset, maxOffset, m_tmpBoneList, damageInfo);
                ProfilerShort.End();

                ProfilerShort.Begin("Deform bones");
                Vector3 bone;
                Vector3I baseOffset = gridPos * MyGridSkeleton.BoneDensity;
                float boneDensityR = 1.0f / MyGridSkeleton.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);
                        }
                    }
                }
                m_tmpBoneList.Clear();
                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;
        }
Beispiel #41
0
        private static void AfterDamageHandler(object obj, MyDamageInformation damageInfo)
        {
            if (!(obj is IMySlimBlock))
                return;

            // grind damage is handled by OnBlockIntegrityChanged, which is faster
            if (damageInfo.Type == MyDamageType.Grind)
                return;

            IMySlimBlock block = (IMySlimBlock)obj;
            long gridId = block.CubeGrid.EntityId;
            Registrar.ForEach((Projector proj) => {
                SeenHolo sh;
                if (!proj.m_holoEntities.TryGetValue(gridId, out sh) || !sh.Holo.Render.Visible || !sh.ColouredByIntegrity)
                    return;
                ColourBlock(block, (IMyCubeGrid)sh.Holo);
            });
        }
        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 (MySession.Static != null && Owner == MySession.Static.LocalCharacter && MyMusicController.Static != null)
                    MyMusicController.Static.Building(250);

                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;

                if (Owner != null && Owner.ControllerInfo.IsLocallyControlled() && (Owner.IsInFirstPersonView || Owner.ForceFirstPersonCamera))
                    PerformCameraShake();
            }

            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 (Owner != null && Owner.ControllerInfo.IsLocallyControlled() && (Owner.IsInFirstPersonView || Owner.ForceFirstPersonCamera))
                    PerformCameraShake();
            }

            if (block != null || targetDestroyable != null)
            {
                m_actualSound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_source, target);
            }
        }
Beispiel #43
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;
            }
        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();
                }
            }
        }
        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);
            }
        }
Beispiel #46
0
 /// <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);
 }
        void IMyCharacter.Kill(object statChangeData)
        {
            MyDamageInformation damageInfo = new MyDamageInformation();
            if (statChangeData != null)
                damageInfo = (MyDamageInformation)statChangeData;

            Kill(true, damageInfo);
        }
Beispiel #48
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 KillCharacter(MyDamageInformation damageInfo)
 {
     Debug.Assert(Sync.IsServer, "KillCharacter called from client");
     Kill(false, damageInfo);
     MyMultiplayer.RaiseEvent(this, x => x.OnKillCharacter, damageInfo);
 }
 void OnKillCharacter(MyDamageInformation damageInfo)
 {
     Kill(false, damageInfo);
 }
        public bool DoDamage(float damage, MyStringHash damageType, bool sync, long attackerId)
        {
            if (MarkedForClose)
                return false;

            if (sync)
            {
                if (Sync.IsServer)
                {
                    MySyncDamage.DoDamageSynced(this, damage, damageType, attackerId);
                    return true;
                }
                else
                {
                    return false;
                }

            }

            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;
                    }
                    if (Sync.IsServer)
                    {
                        MyFloatingObjects.RemoveFloatingObject(this);
                    }
                }
                else
                {
                    if (Sync.IsServer)
                    {
                        MyFloatingObjects.RemoveFloatingObject(this, (MyFixedPoint)damageinfo.Amount);
                    }
                }
            }
            else
            {
                m_health -= 10 * 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 true;

                        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 (ItemDefinition != null && ItemDefinition.DestroyedPieceId.HasValue && Sync.IsServer)
                    {
                        MyPhysicalItemDefinition pieceDefinition;
                        if (MyDefinitionManager.Static.TryGetPhysicalItemDefinition(ItemDefinition.DestroyedPieceId.Value, out pieceDefinition))
                        {
                            MyFloatingObjects.Spawn(pieceDefinition, WorldMatrix.Translation, WorldMatrix.Forward, WorldMatrix.Up, ItemDefinition.DestroyedPieces);
                        }
                        else
                        {
                            System.Diagnostics.Debug.Fail("Trying to spawn piece of the item after being destroyed, but definition wasn't found! - " + ItemDefinition.DestroyedPieceId.Value);
                        }
                    }

                    if (UseDamageSystem)
                        MyDamageSystem.Static.RaiseDestroyed(this, damageinfo);
                }
            }

            return true;
        }
Beispiel #52
0
        public static void BeforeDamageHandler(object target, ref MyDamageInformation info)
        {
            try
            {
                Logger.Log.Debug("BeaconSecurity.BeforeDamageHandler {0} - {1}, {2}, {3}", target, info.Amount, info.Type, info.AttackerId);

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

                MyCubeGrid targetGrid = targetBlock.CubeGrid as MyCubeGrid;
                if (targetGrid == null)
                    return;

                if (!targetGrid.DestructibleBlocks)
                {
                    Logger.Log.Debug(" * DestructibleBlocks {0}, so DAMAGE IGNORED...", targetGrid.DestructibleBlocks);
                    info.Amount = 0f;
                }

                bool owner = false;
                IMyFunctionalBlock targetFunctionalBlock = targetBlock.FatBlock as IMyFunctionalBlock;
                IMyEntity attackerEntity;
                Logger.Log.Debug(" targetFunctionalBlock '{0}'", targetFunctionalBlock);
                if (targetFunctionalBlock != null && MyAPIGateway.Entities.TryGetEntityById(info.AttackerId, out attackerEntity))
                {
                    if (info.Type == MyDamageType.Grind)
                    {
                        IMyPlayer player = null;
                        if (attackerEntity is IMyShipGrinder)
                            player = MyAPIGateway.Players.GetPlayerControllingEntity(attackerEntity.GetTopMostParent());

                        if (player == null)
                        {
                            List<IMyPlayer> players = new List<IMyPlayer>();
                            MyAPIGateway.Players.GetPlayers(players);

                            double nearestDistance = 5.0f;
                            foreach (var pl in players)
                            {
                                IMyEntity character = pl.Controller.ControlledEntity as IMyEntity;
                                if (character != null)
                                {
                                    var distance = (character.GetPosition() - attackerEntity.GetPosition()).LengthSquared();
                                    if (distance > nearestDistance)
                                        continue;
                                    nearestDistance = distance;
                                    player = pl;
                                }
                            }
                        }

                        if (player != null)
                        {
                            MyRelationsBetweenPlayerAndBlock relation = targetFunctionalBlock.GetUserRelationToOwner(player.IdentityId);
                            Logger.Log.Debug(" relation '{0}' is {1} == {2}", relation, player.IdentityId, targetFunctionalBlock.OwnerId);
                            owner = (relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.NoOwnership) ? true : false;
                        }
                    }
                }

                // check admins grids
                if (Core.Settings != null && Core.Settings.Indestructible.Contains(targetGrid.EntityId))
                {
                    if (owner && Core.Settings.IndestructibleGrindOwner || owner && Core.Settings.IndestructibleOverrideGrindOwner.Contains(targetGrid.EntityId))
                    {
                        // пилить можно
                        Logger.Log.Debug(" * Target '{0}' has own property, so DAMAGE permit...", targetGrid.DisplayName);
                    }
                    else
                    {
                        // пилить нельзя
                        Logger.Log.Debug(" * Target '{0}' in indestructible list, so DAMAGE IGNORED...", targetGrid.DisplayName);
                        info.Amount = 0f;
                    }
                }

            }
            catch (Exception ex)
            {
                Logger.Log.Error("Exception BeforeDamageHandler in {0}", ex.Message);
            }
        }