public void GetBlocksInsideSphereBrute(MyCubeGrid grid, Vector3I center, ref BoundingSphereD sphere, bool sorted) { if (grid.PositionComp == null) { return; } if (sorted) { SlimsSortedList.Clear(); } else { _slimsSet.Clear(); } var matrixNormalizedInv = grid.PositionComp.WorldMatrixNormalizedInv; Vector3D result; Vector3D.Transform(ref sphere.Center, ref matrixNormalizedInv, out result); var localSphere = new BoundingSphere(result, (float)sphere.Radius); foreach (IMySlimBlock cube in grid.CubeBlocks) { if (new BoundingBox(cube.Min * grid.GridSize - grid.GridSizeHalf, cube.Max * grid.GridSize + grid.GridSizeHalf).Intersects(localSphere)) { var radiatedBlock = new RadiatedBlock { Center = center, Slim = cube, Position = cube.Position, }; if (sorted) { SlimsSortedList.Add(radiatedBlock); } else { _slimsSet.Add(cube); } } } if (sorted) { SlimsSortedList.Sort((x, y) => Vector3I.DistanceManhattan(x.Position, x.Slim.Position).CompareTo(Vector3I.DistanceManhattan(y.Position, y.Slim.Position))); } }
private void GetIntVectorsInSphere2(MyCubeGrid grid, Vector3I center, double radius) { SlimsSortedList.Clear(); radius *= grid.GridSizeR; var gridMin = grid.Min; var gridMax = grid.Max; double radiusSq = radius * radius; int radiusCeil = (int)Math.Ceiling(radius); int i, j, k; Vector3I max = Vector3I.Min(Vector3I.One * radiusCeil, gridMax - center); Vector3I min = Vector3I.Max(Vector3I.One * -radiusCeil, gridMin - center); for (i = min.X; i <= max.X; ++i) { for (j = min.Y; j <= max.Y; ++j) { for (k = min.Z; k <= max.Z; ++k) { if (i * i + j * j + k * k < radiusSq) { var vector3I = center + new Vector3I(i, j, k); IMySlimBlock slim = grid.GetCubeBlock(vector3I); if (slim != null && slim.Position == vector3I) { var radiatedBlock = new RadiatedBlock { Center = center, Slim = slim, Position = vector3I }; SlimsSortedList.Add(radiatedBlock); } } } } } SlimsSortedList.Sort((a, b) => Vector3I.Dot(a.Position, a.Position).CompareTo(Vector3I.Dot(b.Position, b.Position))); }
internal void PurgeAll() { FutureEvents.Purge((int)Tick); PurgeTerminalSystem(); foreach (var reports in Reporter.ReportData.Values) { foreach (var report in reports) { report.Clean(); Reporter.ReportPool.Return(report); } reports.Clear(); } Reporter.ReportData.Clear(); Reporter.ReportPool.Clean(); PacketsToClient.Clear(); PacketsToServer.Clear(); foreach (var suit in (PacketType[])Enum.GetValues(typeof(PacketType))) { foreach (var pool in PacketPools.Values) { pool.Clean(); } PacketPools.Clear(); } foreach (var item in _effectedCubes) { var cubeid = item.Key; var blockInfo = item.Value; var functBlock = blockInfo.FunctBlock; var cube = blockInfo.CubeBlock; if (cube == null || cube.MarkedForClose) { _effectPurge.Enqueue(cubeid); continue; } functBlock.EnabledChanged -= ForceDisable; functBlock.Enabled = blockInfo.FirstState; cube.SetDamageEffect(false); _effectPurge.Enqueue(cubeid); } while (_effectPurge.Count != 0) { _effectedCubes.Remove(_effectPurge.Dequeue()); } Av.Glows.Clear(); Av.AvShotPool.Clean(); DeferedUpBlockTypeCleanUp(true); BlockTypeCleanUp.Clear(); foreach (var map in GridToFatMap.Keys) { RemoveGridFromMap(map); } GridToFatMap.Clear(); FatMapPool.Clean(); DirtyGridsTmp.Clear(); foreach (var structure in WeaponPlatforms.Values) { foreach (var system in structure.WeaponSystems) { foreach (var ammo in system.Value.WeaponAmmoTypes) { ammo.AmmoDef.Const.PrimeEntityPool?.Clean(); } } structure.WeaponSystems.Clear(); } WeaponPlatforms.Clear(); foreach (var gridToMap in GridToBlockTypeMap) { foreach (var map in gridToMap.Value) { map.Value.ClearImmediate(); ConcurrentListPool.Return(map.Value); } gridToMap.Value.Clear(); BlockTypePool.Return(gridToMap.Value); } GridToBlockTypeMap.Clear(); foreach (var playerGrids in PlayerEntityIdInRange) { playerGrids.Value.Clear(); } PlayerEntityIdInRange.Clear(); DirtyGrids.Clear(); DsUtil.Purge(); DsUtil2.Purge(); _effectActive = false; ShootingWeapons.Clear(); AcquireTargets.Clear(); RemoveEffectsFromGrid.Clear(); WeaponAmmoPullQueue.Clear(); AmmoToPullQueue.Clear(); Hits.Clear(); AllArmorBaseDefinitions.Clear(); HeavyArmorBaseDefinitions.Clear(); AllArmorBaseDefinitions.Clear(); AcquireTargets.Clear(); ChargingWeapons.Clear(); LargeBlockSphereDb.Clear(); SmallBlockSphereDb.Clear(); AnimationsToProcess.Clear(); _subTypeIdToWeaponDefs.Clear(); WeaponDefinitions.Clear(); SlimsSortedList.Clear(); _destroyedSlims.Clear(); _destroyedSlimsClient.Clear(); _slimHealthClient.Clear(); _slimsSet.Clear(); _turretDefinitions.Clear(); foreach (var comp in CompsToStart) { PlatFormPool.Return(comp.Platform); comp.Platform = null; } foreach (var readd in CompReAdds) { PlatFormPool.Return(readd.Comp.Platform); readd.Comp.Platform = null; } foreach (var comp in CompsDelayed) { PlatFormPool.Return(comp.Platform); comp.Platform = null; } PlatFormPool.Clean(); CompsToStart.ClearImmediate(); CompsDelayed.Clear(); CompReAdds.Clear(); GridAiPool.Clean(); Av.RipMap.Clear(); foreach (var mess in Av.KeensBrokenParticles) { Av.KeenMessPool.Return(mess); } Av.KeensBrokenParticles.Clear(); foreach (var av in Av.AvShots) { av.GlowSteps.Clear(); Av.AvShotPool.Return(av); } Av.AvShotPool.Clean(); Av.AvBarrels1.Clear(); Av.AvBarrels2.Clear(); Av.AvShots.Clear(); Av.HitSounds.Clear(); foreach (var errorpkt in ClientSideErrorPktList) { errorpkt.Packet.CleanUp(); } ClientSideErrorPktList.Clear(); GridEffectPool.Clean(); GridEffectsPool.Clean(); BlockTypePool.Clean(); ConcurrentListPool.Clean(); GroupInfoPool.Clean(); TargetInfoPool.Clean(); Projectiles.Clean(); WeaponCoreBlockDefs.Clear(); VanillaIds.Clear(); VanillaCoreIds.Clear(); WeaponCoreFixedBlockDefs.Clear(); WeaponCoreTurretBlockDefs.Clear(); foreach (var p in Projectiles.ProjectilePool) { p.AmmoEffect?.Stop(); } Projectiles.ShrapnelToSpawn.Clear(); Projectiles.ShrapnelPool.Clean(); Projectiles.FragmentPool.Clean(); Projectiles.ActiveProjetiles.ApplyChanges(); Projectiles.ActiveProjetiles.Clear(); Projectiles.ProjectilePool.Clear(); Projectiles.HitEntityPool.Clean(); Projectiles.CleanUp.Clear(); Projectiles.VirtInfoPool.Clean(); DbsToUpdate.Clear(); GridTargetingAIs.Clear(); DsUtil = null; DsUtil2 = null; SlimsSortedList = null; Enforced = null; StallReporter = null; Proccessor = null; Physics = null; Camera = null; Projectiles = null; TrackingAi = null; UiInput = null; TargetUi = null; Placer = null; WheelUi = null; TargetGps = null; SApi.Unload(); SApi = null; Api = null; ApiServer = null; Reporter = null; WeaponDefinitions = null; AnimationsToProcess = null; ProjectileTree.Clear(); ProjectileTree = null; Av = null; HudUi = null; AllDefinitions = null; SoundDefinitions = null; ActiveCockPit = null; ActiveControlBlock = null; ControlledEntity = null; }
internal void PurgeAll() { PurgedAll = true; FutureEvents.Purge((int)Tick); foreach (var comp in CompsToStart) { if (comp?.Platform != null) { CloseComps(comp.MyCube); } } foreach (var readd in CompReAdds) { if (!readd.Ai.Closed) { readd.Ai.AiForceClose(); } if (readd.Comp?.Platform != null) { CloseComps(readd.Comp.MyCube); } } foreach (var comp in CompsDelayed) { if (comp?.Platform != null) { CloseComps(comp.MyCube); } } foreach (var gridAi in DelayedAiClean) { if (!gridAi.Closed) { gridAi.AiForceClose(); } } PlatFormPool.Clean(); CompsToStart.ClearImmediate(); DelayedAiClean.ClearImmediate(); CompsDelayed.Clear(); CompReAdds.Clear(); GridAiPool.Clean(); PurgeTerminalSystem(this); HudUi.Purge(); TerminalMon.Purge(); foreach (var reports in Reporter.ReportData.Values) { foreach (var report in reports) { report.Clean(); Reporter.ReportPool.Return(report); } reports.Clear(); } Reporter.ReportData.Clear(); Reporter.ReportPool.Clean(); PacketsToClient.Clear(); PacketsToServer.Clear(); AcqManager.Clean(); CleanSounds(true); foreach (var e in Emitters) { e.StopSound(true); } foreach (var e in Av.HitEmitters) { e.StopSound(true); } foreach (var e in Av.FireEmitters) { e.StopSound(true); } foreach (var e in Av.TravelEmitters) { e.StopSound(true); } Emitters.Clear(); Av.HitEmitters.Clear(); Av.FireEmitters.Clear(); Av.TravelEmitters.Clear(); foreach (var item in EffectedCubes) { var cubeid = item.Key; var blockInfo = item.Value; var functBlock = blockInfo.FunctBlock; if (functBlock == null || functBlock.MarkedForClose) { _effectPurge.Enqueue(cubeid); continue; } functBlock.EnabledChanged -= ForceDisable; functBlock.Enabled = blockInfo.FirstState; functBlock.SetDamageEffect(false); if (HandlesInput) { functBlock.AppendingCustomInfo -= blockInfo.AppendCustomInfo; } _effectPurge.Enqueue(cubeid); } while (_effectPurge.Count != 0) { EffectedCubes.Remove(_effectPurge.Dequeue()); } Av.Glows.Clear(); Av.AvShotPool.Clean(); DeferedUpBlockTypeCleanUp(true); BlockTypeCleanUp.Clear(); foreach (var map in GridToInfoMap.Keys) { RemoveGridFromMap(map); } GridToInfoMap.Clear(); GridMapPool.Clean(); DirtyGridsTmp.Clear(); foreach (var structure in WeaponPlatforms.Values) { foreach (var system in structure.WeaponSystems) { system.Value.PreFirePairs.Clear(); system.Value.FireWhenDonePairs.Clear(); system.Value.FirePerShotPairs.Clear(); system.Value.RotatePairs.Clear(); system.Value.ReloadPairs.Clear(); foreach (var ammo in system.Value.AmmoTypes) { ammo.AmmoDef.Const.PrimeEntityPool?.Clean(); ammo.AmmoDef.Const.HitDefaultSoundPairs.Clear(); ammo.AmmoDef.Const.HitVoxelSoundPairs.Clear(); ammo.AmmoDef.Const.HitShieldSoundPairs.Clear(); ammo.AmmoDef.Const.HitFloatingSoundPairs.Clear(); ammo.AmmoDef.Const.HitPlayerSoundPairs.Clear(); ammo.AmmoDef.Const.TravelSoundPairs.Clear(); ammo.AmmoDef.Const.CustomSoundPairs.Clear(); } } structure.WeaponSystems.Clear(); } WeaponPlatforms.Clear(); foreach (var gridToMap in GridToBlockTypeMap) { foreach (var map in gridToMap.Value) { ConcurrentListPool.Return(map.Value); } gridToMap.Value.Clear(); BlockTypePool.Return(gridToMap.Value); } GridToBlockTypeMap.Clear(); foreach (var playerGrids in PlayerEntityIdInRange) { playerGrids.Value.Clear(); } PlayerEntityIdInRange.Clear(); DirtyGridInfos.Clear(); DsUtil.Purge(); DsUtil2.Purge(); ShootingWeapons.Clear(); WeaponToPullAmmo.Clear(); AmmoToPullQueue.Clear(); ChargingWeaponsIndexer.Clear(); WeaponsToRemoveAmmoIndexer.Clear(); ChargingWeapons.Clear(); Hits.Clear(); HomingWeapons.Clear(); GridToMasterAi.Clear(); Players.Clear(); IdToCompMap.Clear(); AllArmorBaseDefinitions.Clear(); HeavyArmorBaseDefinitions.Clear(); AllArmorBaseDefinitions.Clear(); AcquireTargets.Clear(); LargeBlockSphereDb.Clear(); SmallBlockSphereDb.Clear(); AnimationsToProcess.Clear(); _subTypeIdToWeaponDefs.Clear(); WeaponDefinitions.Clear(); SlimsSortedList.Clear(); _destroyedSlims.Clear(); _destroyedSlimsClient.Clear(); _slimHealthClient.Clear(); _slimsSet.Clear(); _turretDefinitions.Clear(); _tmpNearByBlocks.Clear(); foreach (var av in Av.AvShots) { av.GlowSteps.Clear(); Av.AvShotPool.Return(av); } Av.AvShotPool.Clean(); Av.AvBarrels1.Clear(); Av.AvBarrels2.Clear(); Av.AvShots.Clear(); Av.HitSounds.Clear(); foreach (var errorpkt in ClientSideErrorPkt) { errorpkt.Packet.CleanUp(); } ClientSideErrorPkt.Clear(); GridEffectPool.Clean(); GridEffectsPool.Clean(); BlockTypePool.Clean(); ConcurrentListPool.Clean(); TargetInfoPool.Clean(); PacketObjPool.Clean(); InventoryMoveRequestPool.Clean(); WeaponCoreBlockDefs.Clear(); VanillaIds.Clear(); VanillaCoreIds.Clear(); WeaponCoreFixedBlockDefs.Clear(); WeaponCoreTurretBlockDefs.Clear(); VoxelCaches.Clear(); ArmorCubes.Clear(); foreach (var p in Projectiles.ProjectilePool) { p.Info?.AvShot?.AmmoEffect?.Stop(); } Projectiles.ShrapnelToSpawn.Clear(); Projectiles.ShrapnelPool.Clean(); Projectiles.FragmentPool.Clean(); Projectiles.ActiveProjetiles.Clear(); Projectiles.ProjectilePool.Clear(); Projectiles.HitEntityPool.Clean(); Projectiles.VirtInfoPool.Clean(); DbsToUpdate.Clear(); GridTargetingAIs.Clear(); DsUtil = null; DsUtil2 = null; SlimsSortedList = null; Settings = null; StallReporter = null; TerminalMon = null; Physics = null; Camera = null; Projectiles = null; TrackingAi = null; UiInput = null; TargetUi = null; Placer = null; TargetGps = null; SApi.Unload(); SApi = null; Api = null; ApiServer = null; Reporter = null; WeaponDefinitions = null; AnimationsToProcess = null; ProjectileTree.Clear(); ProjectileTree = null; Av = null; HudUi = null; AllDefinitions = null; SoundDefinitions = null; ActiveCockPit = null; ActiveControlBlock = null; ControlledEntity = null; TmpStorage = null; }
public void GetBlocksInsideSphere(MyCubeGrid grid, Dictionary <Vector3I, IMySlimBlock> cubes, ref BoundingSphereD sphere, bool sorted, Vector3I center, bool checkTriangles = false) { if (grid.PositionComp == null) { return; } if (sorted) { SlimsSortedList.Clear(); } else { _slimsSet.Clear(); } var matrixNormalizedInv = grid.PositionComp.WorldMatrixNormalizedInv; Vector3D result; Vector3D.Transform(ref sphere.Center, ref matrixNormalizedInv, out result); var localSphere = new BoundingSphere(result, (float)sphere.Radius); var fromSphere2 = BoundingBox.CreateFromSphere(localSphere); var min = (Vector3D)fromSphere2.Min; var max = (Vector3D)fromSphere2.Max; var vector3I1 = new Vector3I((int)Math.Round(min.X * grid.GridSizeR), (int)Math.Round(min.Y * grid.GridSizeR), (int)Math.Round(min.Z * grid.GridSizeR)); var vector3I2 = new Vector3I((int)Math.Round(max.X * grid.GridSizeR), (int)Math.Round(max.Y * grid.GridSizeR), (int)Math.Round(max.Z * grid.GridSizeR)); var start = Vector3I.Min(vector3I1, vector3I2); var end = Vector3I.Max(vector3I1, vector3I2); if ((end - start).Volume() < cubes.Count) { var vector3IRangeIterator = new Vector3I_RangeIterator(ref start, ref end); var next = vector3IRangeIterator.Current; while (vector3IRangeIterator.IsValid()) { IMySlimBlock cube; if (cubes.TryGetValue(next, out cube)) { if (new BoundingBox(cube.Min * grid.GridSize - grid.GridSizeHalf, cube.Max * grid.GridSize + grid.GridSizeHalf).Intersects(localSphere)) { var radiatedBlock = new RadiatedBlock { Center = center, Slim = cube, Position = cube.Position, }; if (sorted) { SlimsSortedList.Add(radiatedBlock); } else { _slimsSet.Add(cube); } } } vector3IRangeIterator.GetNext(out next); } } else { foreach (var cube in cubes.Values) { if (new BoundingBox(cube.Min * grid.GridSize - grid.GridSizeHalf, cube.Max * grid.GridSize + grid.GridSizeHalf).Intersects(localSphere)) { var radiatedBlock = new RadiatedBlock { Center = center, Slim = cube, Position = cube.Position, }; if (sorted) { SlimsSortedList.Add(radiatedBlock); } else { _slimsSet.Add(cube); } } } } if (sorted) { SlimsSortedList.Sort((x, y) => Vector3I.DistanceManhattan(x.Position, x.Slim.Position).CompareTo(Vector3I.DistanceManhattan(y.Position, y.Slim.Position))); } }
private void DamageGrid(HitEntity hitEnt, ProInfo t, bool canDamage) { var grid = hitEnt.Entity as MyCubeGrid; if (grid == null || grid.MarkedForClose || !hitEnt.HitPos.HasValue || hitEnt.Blocks == null) { hitEnt.Blocks?.Clear(); return; } if (t.AmmoDef.DamageScales.Shields.Type == ShieldDef.ShieldType.Heal || (!t.AmmoDef.Const.SelfDamage || !MyAPIGateway.Session.SessionSettings.EnableTurretsFriendlyFire) && t.Ai.MyGrid.IsSameConstructAs(grid)) { t.BaseDamagePool = 0; return; } _destroyedSlims.Clear(); _destroyedSlimsClient.Clear(); var largeGrid = grid.GridSizeEnum == MyCubeSize.Large; var areaRadius = largeGrid ? t.AmmoDef.Const.AreaRadiusLarge : t.AmmoDef.Const.AreaRadiusSmall; var detonateRadius = largeGrid ? t.AmmoDef.Const.DetonateRadiusLarge : t.AmmoDef.Const.DetonateRadiusSmall; var maxObjects = t.AmmoDef.Const.MaxObjectsHit; var areaEffect = t.AmmoDef.AreaEffect.AreaEffect; var explosive = areaEffect == AreaEffectType.Explosive; var radiant = areaEffect == AreaEffectType.Radiant; var detonateOnEnd = t.AmmoDef.AreaEffect.Detonation.DetonateOnEnd; var detonateDmg = t.AmmoDef.Const.DetonationDamage; var shieldBypass = t.AmmoDef.DamageScales.Shields.Type == ShieldDef.ShieldType.Bypass; var attackerId = shieldBypass ? grid.EntityId : t.Target.FiringCube.EntityId; var attacker = shieldBypass ? (MyEntity)grid : t.Target.FiringCube; var areaEffectDmg = areaEffect != AreaEffectType.Disabled ? t.AmmoDef.Const.AreaEffectDamage : 0; var hitMass = t.AmmoDef.Mass; var sync = MpActive && (DedicatedServer || IsServer); var hasAreaDmg = areaEffectDmg > 0; var radiantCascade = radiant && !detonateOnEnd; var primeDamage = !radiantCascade || !hasAreaDmg; var radiantBomb = radiant && detonateOnEnd; var damageType = explosive || radiant ? MyDamageType.Explosion : MyDamageType.Bullet; var fallOff = t.AmmoDef.Const.FallOffScaling && t.DistanceTraveled > t.AmmoDef.DamageScales.FallOff.Distance; var fallOffMultipler = 1f; if (fallOff) { fallOffMultipler = (float)MathHelperD.Clamp(1.0 - ((t.DistanceTraveled - t.AmmoDef.DamageScales.FallOff.Distance) / (t.AmmoDef.Const.MaxTrajectory - t.AmmoDef.DamageScales.FallOff.Distance)), t.AmmoDef.DamageScales.FallOff.MinMultipler, 1); } var damagePool = t.BaseDamagePool; if (t.AmmoDef.Const.VirtualBeams) { var hits = t.WeaponCache.Hits; damagePool *= hits; areaEffectDmg *= hits; } var objectsHit = t.ObjectsHit; var countBlocksAsObjects = t.AmmoDef.ObjectsHit.CountBlocks; List <Vector3I> radiatedBlocks = null; if (radiant) { GetBlockSphereDb(grid, areaRadius, out radiatedBlocks); } var done = false; var nova = false; var outOfPew = false; for (int i = 0; i < hitEnt.Blocks.Count; i++) { if (done || outOfPew && !nova) { break; } var rootBlock = hitEnt.Blocks[i]; if (!nova) { if (_destroyedSlims.Contains(rootBlock) || _destroyedSlimsClient.Contains(rootBlock)) { continue; } if (rootBlock.IsDestroyed) { _destroyedSlims.Add(rootBlock); if (IsClient) { _destroyedSlimsClient.Add(rootBlock); if (_slimHealthClient.ContainsKey(rootBlock)) { _slimHealthClient.Remove(rootBlock); } } continue; } } var door = rootBlock.FatBlock as MyDoorBase; if (door != null && door.Open && !HitDoor(hitEnt, door)) { continue; } var radiate = radiantCascade || nova; var dmgCount = 1; if (radiate) { if (nova) { GetBlockSphereDb(grid, detonateRadius, out radiatedBlocks); } if (radiatedBlocks != null) { ShiftAndPruneBlockSphere(grid, rootBlock.Position, radiatedBlocks, SlimsSortedList); } done = nova; dmgCount = SlimsSortedList.Count; } for (int j = 0; j < dmgCount; j++) { var block = radiate ? SlimsSortedList[j].Slim : rootBlock; var blockHp = !IsClient ? block.Integrity : _slimHealthClient.ContainsKey(block) ? _slimHealthClient[block] : block.Integrity; float damageScale = 1; var cube = block.FatBlock as MyCubeBlock; if (cube != null && cube.Components.Has <WeaponComponent>()) { damageScale = 0.25f; } if (t.AmmoDef.Const.DamageScaling) { var d = t.AmmoDef.DamageScales; if (d.MaxIntegrity > 0 && blockHp > d.MaxIntegrity) { outOfPew = true; damagePool = 0; continue; } if (d.Grids.Large >= 0 && largeGrid) { damageScale *= d.Grids.Large; } else if (d.Grids.Small >= 0 && !largeGrid) { damageScale *= d.Grids.Small; } MyDefinitionBase blockDef = null; if (t.AmmoDef.Const.ArmorScaling) { blockDef = block.BlockDefinition; var isArmor = AllArmorBaseDefinitions.Contains(blockDef); if (isArmor && d.Armor.Armor >= 0) { damageScale *= d.Armor.Armor; } else if (!isArmor && d.Armor.NonArmor >= 0) { damageScale *= d.Armor.NonArmor; } if (isArmor && (d.Armor.Light >= 0 || d.Armor.Heavy >= 0)) { var isHeavy = HeavyArmorBaseDefinitions.Contains(blockDef); if (isHeavy && d.Armor.Heavy >= 0) { damageScale *= d.Armor.Heavy; } else if (!isHeavy && d.Armor.Light >= 0) { damageScale *= d.Armor.Light; } } } if (t.AmmoDef.Const.CustomDamageScales) { if (blockDef == null) { blockDef = block.BlockDefinition; } float modifier; var found = t.AmmoDef.Const.CustomBlockDefinitionBasesToScales.TryGetValue(blockDef, out modifier); if (found) { damageScale *= modifier; } else if (t.AmmoDef.DamageScales.Custom.IgnoreAllOthers) { continue; } } if (fallOff) { damageScale *= fallOffMultipler; } } var blockIsRoot = block == rootBlock; var primaryDamage = primeDamage || blockIsRoot; if (damagePool <= 0 && primaryDamage || objectsHit >= maxObjects) { break; } var scaledDamage = damagePool * damageScale; if (primaryDamage) { if (countBlocksAsObjects) { objectsHit++; } if (scaledDamage <= blockHp) { outOfPew = true; damagePool = 0; } else { _destroyedSlims.Add(block); if (IsClient) { _destroyedSlimsClient.Add(block); if (_slimHealthClient.ContainsKey(block)) { _slimHealthClient.Remove(block); } } damagePool -= blockHp; } } else { scaledDamage = areaEffectDmg * damageScale; if (scaledDamage >= blockHp) { _destroyedSlims.Add(block); if (IsClient) { _destroyedSlimsClient.Add(block); if (_slimHealthClient.ContainsKey(block)) { _slimHealthClient.Remove(block); } } } } if (canDamage) { block.DoDamage(scaledDamage, damageType, sync, null, attackerId); } else { var hasBlock = _slimHealthClient.ContainsKey(block); if (hasBlock && _slimHealthClient[block] - scaledDamage > 0) { _slimHealthClient[block] -= scaledDamage; } else if (hasBlock) { _slimHealthClient.Remove(block); } else if (block.Integrity - scaledDamage > 0) { _slimHealthClient[block] = blockHp - scaledDamage; } } var theEnd = damagePool <= 0 || objectsHit >= maxObjects; if (explosive && (!detonateOnEnd && blockIsRoot || detonateOnEnd && theEnd)) { if (areaEffectDmg > 0) { SUtils.CreateMissileExplosion(this, areaEffectDmg * damageScale, areaRadius, hitEnt.HitPos.Value, hitEnt.Intersection.Direction, attacker, grid, t.AmmoDef, true); } if (detonateOnEnd && theEnd) { SUtils.CreateMissileExplosion(this, detonateDmg * damageScale, detonateRadius, hitEnt.HitPos.Value, hitEnt.Intersection.Direction, attacker, grid, t.AmmoDef, true); } } else if (!nova) { if (hitMass > 0 && blockIsRoot) { var speed = t.AmmoDef.Trajectory.DesiredSpeed > 0 ? t.AmmoDef.Trajectory.DesiredSpeed : 1; ApplyProjectileForce(grid, grid.GridIntegerToWorld(rootBlock.Position), hitEnt.Intersection.Direction, (hitMass * speed)); } if (radiantBomb && theEnd) { nova = true; i--; t.BaseDamagePool = 0; t.ObjectsHit = maxObjects; objectsHit = int.MinValue; var aInfo = t.AmmoDef.AreaEffect; var dInfo = aInfo.Detonation; if (dInfo.DetonationDamage > 0) { damagePool = detonateDmg; } else if (aInfo.AreaEffectDamage > 0) { damagePool = areaEffectDmg; } else { damagePool = scaledDamage; } break; } } } } if (!countBlocksAsObjects) { t.ObjectsHit += 1; } if (!nova) { t.BaseDamagePool = damagePool; t.ObjectsHit = objectsHit; } if (radiantCascade || nova) { SlimsSortedList.Clear(); } hitEnt.Blocks.Clear(); }