Ejemplo n.º 1
0
        void Grind(IMySlimBlock Block, float SpeedRatio)
        {
            Block.DecreaseMountLevel(SpeedRatio, ToolCargo, useDefaultDeconstructEfficiency: true);
            Block.MoveItemsFromConstructionStockpile(ToolCargo);
            Block.DoDamage(0, VRage.Utils.MyStringHash.GetOrCompute("Grind"), true, null, Tool.EntityId);

            if (Block.FatBlock?.IsFunctional == false && Block.FatBlock?.HasInventory == true)
            {
                foreach (var Inventory in Block.FatBlock.GetInventories())
                {
                    if (Inventory.CurrentVolume == VRage.MyFixedPoint.Zero)
                    {
                        continue;
                    }
                    foreach (var Item in Inventory.GetItems())
                    {
                        var Amount = Inventory.ComputeAmountThatFits(Item);
                        ToolCargo.TransferItemFrom(Inventory, (int)Item.ItemId, null, null, Amount, false);
                    }
                }
            }
            if (Block.IsFullyDismounted)
            {
                Block.CubeGrid.RazeBlock(Block.Position);
            }
        }
Ejemplo n.º 2
0
        public static void ApplyRegularDamage(IMyCubeGrid cubeGrid, Vector3D startCoords, Vector3D endCoords, float damageAmount, long damageOwner)
        {
            var newStartCoords = Vector3D.Normalize(startCoords - endCoords) * 50 + endCoords;
            var newEndCoords   = Vector3D.Normalize(endCoords - startCoords) * 50 + endCoords;
            var cellList       = new List <Vector3I>();

            cubeGrid.RayCastCells(newStartCoords, newEndCoords, cellList);

            IMySlimBlock closestBlock     = null;
            double       closestBlockDist = 0;

            foreach (var cell in cellList)
            {
                var block = cubeGrid.GetCubeBlock(cell);

                if (block == null)
                {
                    continue;
                }

                var blockPosition = Vector3D.Zero;
                block.ComputeWorldCenter(out blockPosition);
                var thisBlockDist = Vector3D.Distance(blockPosition, endCoords);

                if (closestBlock == null)
                {
                    closestBlock     = block;
                    closestBlockDist = thisBlockDist;
                }

                if (thisBlockDist < closestBlockDist)
                {
                    closestBlock     = block;
                    closestBlockDist = thisBlockDist;
                }
            }

            if (closestBlock == null)
            {
                return;
            }

            closestBlock.DoDamage(damageAmount, MyStringHash.GetOrCompute("Laser"), true, null, damageOwner);
        }
Ejemplo n.º 3
0
        private void SendHeatNotifications()
        {
            if (m_heat > 0f)
            {
                Debug.Write($"Heat:{m_heat}/{m_maxHeat}", 2, debug);
            }

            var overrideMsg   = " Overriding safeties.";
            var heat          = m_heat / m_maxHeat;
            var safetyMessage = SafetySwitch ? " Reducing thrust." : overrideMsg;
            var heatPercent   = (int)(heat * 100);

            if (heat > 0.8f && heat <= 1f && m_maxIntervalThrust > 0f && Debug.Write("Sending thrusters overheating message ...", 1, debug))
            {
                SendOverheatedMessageToPlayer($"WARNING: Thrusters overheating! ({heatPercent}%)", "White", heatPercent);
            }

            else if (!SafetySwitch && m_heat > m_damageHeat && Debug.Write("Sending thrusters critical message ...", 1, debug))
            {
                int randDmg = rand.Next(0, 2);
                if (randDmg > 0)
                {
                    MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                    {
                        try
                        { m_slimBlock.DoDamage((m_heat / m_damageHeat) * 0.01f * randDmg * m_maxHeat, MyDamageType.Deformation, true); }
                        catch (Exception e)
                        { Debug.HandleException(e); }
                    });
                }

                SendOverheatedMessageToPlayer($"WARNING: THRUSTERS CRITICAL! MELTDOWN IMMINENT! ({heatPercent}%)", "Red", heatPercent * 4);
            }
            else if (m_heat > m_maxHeat && Debug.Write("Sending thrusters overheated message ...", 1, debug))
            {
                int w = 2; if (safetyMessage == overrideMsg)
                {
                    w = 3;
                }
                SendOverheatedMessageToPlayer($"WARNING: Thrusters overheated ({heatPercent}%)!{safetyMessage}", "Red", heatPercent * w);
            }
        }
Ejemplo n.º 4
0
        private void Check()
        {
            Vector3D End = Position + Velocity * Tools.Tick;

            IHitInfo hit;

            MyAPIGateway.Physics.CastRay(Position, End, out hit);
            if (hit != null)
            {
                Expired = true;

                //apply recoil
                if (Ammo.ProjectileHitImpulse > 0)
                {
                    Vector3 forceVector = -hit.Normal * Ammo.ProjectileHitImpulse;
                    hit.HitEntity.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, forceVector, hit.Position, Vector3.Zero);
                }

                if (!MyAPIGateway.Session.IsServer)
                {
                    return;
                }

                if (hit.HitEntity is IMyDestroyableObject)
                {
                    (hit.HitEntity as IMyDestroyableObject).DoDamage(Ammo.ProjectileMassDamage, MyStringHash.GetOrCompute(Ammo.SubtypeId), false, null, ShooterId);
                }
                else if (hit.HitEntity is IMyCubeGrid)
                {
                    IMyCubeGrid grid   = hit.HitEntity as IMyCubeGrid;
                    Vector3I?   hitPos = grid.RayCastBlocks(hit.Position, hit.Position + Direction);
                    if (hitPos.HasValue)
                    {
                        IMySlimBlock block = grid.GetCubeBlock(hitPos.Value);
                        block.DoDamage(Ammo.ProjectileMassDamage, MyStringHash.GetOrCompute(Ammo.SubtypeId), false, null, ShooterId);
                    }
                }
            }
        }
        void Grind(IMySlimBlock Block, float SpeedRatio, bool Raze = true)
        {
            if (Block == null)
            {
                return;
            }
            try
            {
                Stopwatch watch = Stopwatch.StartNew();
                Block.DecreaseMountLevel(SpeedRatio, ToolCargo);
                watch.Stop();
                //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Decreasing mount level took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                watch.Restart();
                Block.MoveItemsFromConstructionStockpile(ToolCargo);
                watch.Stop();
                //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Moving items took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                watch.Restart();
                // This is necessary for compatibility with EEM and other mods which react to damage to their grids
                Block.DoDamage(0, MyStringHash.GetOrCompute("Grind"), true, null, MyKernel.Block.EntityId);
                watch.Stop();
                //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Doing damage took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                watch.Restart();

                if (Block.FatBlock?.IsFunctional == false && Block.FatBlock?.HasInventory == true)
                {
                    foreach (IMyInventory Inventory in Block.FatBlock.GetInventories())
                    {
                        if (Inventory.CurrentVolume == VRage.MyFixedPoint.Zero)
                        {
                            continue;
                        }
                        List <MyInventoryItem> Items = new List <MyInventoryItem>();
                        Inventory.GetItems(Items);

                        foreach (MyInventoryItem Item in Items)
                        {
                            VRage.MyFixedPoint Amount = (VRage.MyFixedPoint)Math.Min((float)(Inventory as Sandbox.Game.MyInventory).ComputeAmountThatFits(Item.Type), (float)Item.Amount);
                            if ((float)Amount > 0)
                            {
                                ToolCargo.TransferItemFrom(Inventory, (int)Item.ItemId, null, null, Amount, false);
                            }
                        }
                    }
                    watch.Stop();
                    //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Block has an inventory; cleaning took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                    watch.Reset();
                }

                if (Raze && Block.IsFullyDismounted)
                {
                    watch.Restart();
                    Block.CubeGrid.RazeBlock(Block.Position);
                    watch.Stop();
                    //WriteToLog($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Razing the block took {Math.Round(watch.Elapsed.TotalMilliseconds, 3)}ms", EemRdx.SessionModules.LoggingLevelEnum.ProfilingLog);
                }
            }
            catch (Exception Scrap)
            {
                LogError($"GrindBlocks[{MyKernel.Block.CustomName}]", $"Grinding of the block {Extensions.GeneralExtensions.GetTypeName(Block)} failed", Scrap);
            }
        }
Ejemplo n.º 6
0
        public void Check(Projectile p)
        {
            Vector3D End = p.Position + p.Velocity * Tools.Tick;

            IHitInfo hit;

            MyAPIGateway.Physics.CastRay(p.Position, End, out hit);
            if (hit != null)
            {
                Tools.Debug($"----- ricochet check start -----");
                if (hit.HitEntity is IMyDestroyableObject)
                {
                    p.Expired = true;
                    (hit.HitEntity as IMyDestroyableObject).DoDamage(p.Ammo.ProjectileMassDamage, MyStringHash.GetOrCompute(p.Ammo.SubtypeId), false, null, p.ShooterId);
                }
                else if (hit.HitEntity is IMyCubeGrid)
                {
                    Tools.Debug($"hit cube grid");
                    IMyCubeGrid grid = hit.HitEntity as IMyCubeGrid;

                    Vector3I?hitPos = grid.RayCastBlocks(hit.Position, hit.Position + Vector3D.Normalize(p.Velocity));  // p.Direction
                    if (hitPos.HasValue)
                    {
                        Tools.Debug($"hit block");
                        IMySlimBlock block = grid.GetCubeBlock(hitPos.Value);

                        Vector3 hitObjectVelocity = Vector3.Zero;
                        if (hit.HitEntity.Physics != null)
                        {
                            hitObjectVelocity = hit.HitEntity.Physics.LinearVelocity;
                        }

                        Vector3D relativeV      = p.Velocity - hitObjectVelocity;
                        float    NotHitAngle    = (float)Tools.AngleBetween(-Vector3D.Normalize(relativeV), hit.Normal);
                        float    HitAngle       = (90f - NotHitAngle);
                        float    NotHitFraction = NotHitAngle / 90f;

                        float random = (float)Tools.Random.NextDouble();

                        if (HitAngle < DeflectionAngle && RicochetChance > random)
                        {
                            Tools.Debug($"angle {HitAngle} < {DeflectionAngle}");
                            // Apply impulse
                            float impulse = p.Ammo.ProjectileHitImpulse * NotHitFraction * MaxVelocityTransfer;
                            if (hit.HitEntity.Physics != null)
                            {
                                hit.HitEntity.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, p.Velocity * impulse * -hit.Normal, hit.Position, null);
                            }

                            // apply partial damage
                            float damage = p.Ammo.ProjectileMassDamage * NotHitFraction * MaxDamageTransfer;
                            if (block != null && MyAPIGateway.Session.IsServer)
                            {
                                Tools.Debug($"damage {damage}");
                                block.DoDamage(damage, MyStringHash.GetOrCompute(p.Ammo.SubtypeId), false, null, p.ShooterId);
                            }

                            // reduce velocity
                            p.Velocity -= p.Velocity * NotHitFraction * MaxVelocityTransfer;

                            // reflect
                            p.Velocity = Vector3.Reflect(p.Velocity, hit.Normal);

                            // calculate new direction
                            p.Direction      = Vector3D.Normalize(p.Velocity);
                            p.Position       = hit.Position + (p.Direction * 0.5f);
                            p.Origin         = p.Position;
                            p.DrawFullTracer = false;

                            //if (!MyAPIGateway.Utilities.IsDedicated)
                            //{
                            //    MatrixD world = MatrixD.CreateFromDir(hit.Normal);
                            //    world.Translation = hit.Position;

                            //    MyParticleEffect effect;
                            //    MyParticlesManager.TryCreateParticleEffect("Collision_Sparks_Directional", world, out effect);

                            //    effect.Loop = false;
                            //    effect.UserScale = 0.5f;
                            //    effect.UserEmitterScale = 16f;
                            //    effect.UserRadiusMultiplier = 0.1f;
                            //    effect.UserBirthMultiplier = 20f;
                            //    effect.DurationMin = 0.015f;
                            //    effect.DurationMax = 0.025f;
                            //    effect.SetRandomDuration();
                            //}
                        }
                        else
                        {
                            Tools.Debug($"obsorb damage");
                            if (block != null && MyAPIGateway.Session.IsServer)
                            {
                                block.DoDamage(p.Ammo.ProjectileMassDamage, MyStringHash.GetOrCompute(p.Ammo.SubtypeId), true);
                            }

                            p.Expired = true;
                        }
                    }
                }

                Tools.Debug($"----- ricochet check end -----");
            }
        }