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