internal void Clean() { System = null; HitPos = Vector3D.Zero; Ai = null; ConsumableDef = null; AttackerId = 0; Damage = 0; Hits = 0; }
internal void InitVirtual(Weapon weapon, ConsumableDef ammodef, MyEntity primeEntity, MyEntity triggerEntity, Weapon.Muzzle muzzle, double maxTrajectory, float shotFade) { IsVirtual = true; System = weapon.System; Ai = weapon.Comp.Ai; MyPlanet = weapon.Comp.Ai.MyPlanet; MyShield = weapon.Comp.Ai.MyShield; InPlanetGravity = weapon.Comp.Ai.InPlanetGravity; ConsumableDef = ammodef; PrimeEntity = primeEntity; TriggerEntity = triggerEntity; Target.Entity = weapon.Target.Entity; Target.Projectile = weapon.Target.Projectile; Target.FiringCube = weapon.Target.FiringCube; WeaponId = weapon.WeaponId; MuzzleId = muzzle.MuzzleId; UniqueMuzzleId = muzzle.UniqueId; Direction = muzzle.DeviatedDir; Origin = muzzle.Position; MaxTrajectory = maxTrajectory; ShotFade = shotFade; }
private void ComputeEffects(MyCubeGrid grid, ConsumableDef consumableDef, float damagePool, ref float healthPool, long attackerId, List <IMySlimBlock> blocks) { var largeGrid = grid.GridSizeEnum == MyCubeSize.Large; var eWarInfo = consumableDef.AreaEffect.EwarFields; var duration = (uint)eWarInfo.Duration; var stack = eWarInfo.StackDuration; var maxStack = eWarInfo.MaxStacks; var nextTick = Tick + 1; var maxTick = stack ? (uint)(nextTick + (duration * maxStack)) : nextTick + duration; var fieldType = consumableDef.AreaEffect.AreaEffect; var sync = MpActive && (DedicatedServer || IsServer); foreach (var block in blocks) { var cube = block.FatBlock as MyCubeBlock; if (damagePool <= 0 || healthPool <= 0) { break; } if (fieldType != DotField) { if (cube == null || cube.MarkedForClose || !cube.IsWorking && !EffectedCubes.ContainsKey(cube.EntityId) || !(cube is IMyFunctionalBlock)) { continue; } } var blockHp = block.Integrity; float damageScale = 1; var tmpDamagePool = damagePool; if (consumableDef.Const.DamageScaling) { var d = consumableDef.DamageScales; if (d.MaxIntegrity > 0 && blockHp > d.MaxIntegrity) { 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 (consumableDef.Const.ArmorScaling) { blockDef = block.BlockDefinition; var isArmor = AllArmorBaseDefinitions.Contains(blockDef) || CustomArmorSubtypes.Contains(blockDef.Id.SubtypeId); 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) || CustomHeavyArmorSubtypes.Contains(blockDef.Id.SubtypeId); if (isHeavy && d.Armor.Heavy >= 0) { damageScale *= d.Armor.Heavy; } else if (!isHeavy && d.Armor.Light >= 0) { damageScale *= d.Armor.Light; } } } if (consumableDef.Const.CustomDamageScales) { if (blockDef == null) { blockDef = block.BlockDefinition; } float modifier; var found = consumableDef.Const.CustomBlockDefinitionBasesToScales.TryGetValue(blockDef, out modifier); if (found) { damageScale *= modifier; } else if (consumableDef.DamageScales.Custom.IgnoreAllOthers) { continue; } } } var scaledDamage = tmpDamagePool * damageScale; var blockDisabled = false; if (scaledDamage <= blockHp) { tmpDamagePool = 0; } else { blockDisabled = true; tmpDamagePool -= blockHp; } if (fieldType == DotField && IsServer) { block.DoDamage(scaledDamage, MyDamageType.Explosion, sync, null, attackerId); continue; } if (cube != null) { BlockState blockState; var cubeId = cube.EntityId; if (stack && EffectedCubes.TryGetValue(cubeId, out blockState)) { if (blockState.Health > 0) { damagePool = tmpDamagePool; } if (!blockDisabled && blockState.Health - scaledDamage > 0) { blockState.Health -= scaledDamage; blockState.Endtick = Tick + (duration + 1); } else if (blockState.Endtick + (duration + 1) < maxTick) { blockState.Health = 0; healthPool -= 1; blockState.Endtick += (duration + 1); } else { blockState.Health = 0; healthPool -= 1; blockState.Endtick = maxTick; } } else { damagePool = tmpDamagePool; blockState.FunctBlock = ((IMyFunctionalBlock)cube); var originState = blockState.FunctBlock.Enabled; blockState.FirstTick = Tick + 1; blockState.FirstState = originState; blockState.NextTick = nextTick; blockState.Endtick = Tick + (duration + 1); blockState.Session = this; blockState.ConsumableDef = consumableDef; if (!blockDisabled) { blockState.Health = blockHp - scaledDamage; } else { blockState.Health = 0; } } EffectedCubes[cube.EntityId] = blockState; } } }
internal void Clean() { if (Monitors?.Count > 0) { for (int i = 0; i < Monitors.Count; i++) { Monitors[i].Invoke(Target.FiringCube.EntityId, WeaponId, Id, Target.TargetId, Hit.LastHit, false); } System.Session.MonitoredProjectiles.Remove(Id); } Monitors = null; Target.Reset(System.Session.Tick, Target.States.ProjectileClosed); HitList.Clear(); if (IsShrapnel) { if (VoxelCache != null && System.Session != null) { System.Session.NewVoxelCache = VoxelCache; } else { Log.Line($"IsShrapnel voxelcache return failure"); } } if (PrimeEntity != null) { ConsumableDef.Const.PrimeEntityPool.Return(PrimeEntity); PrimeEntity = null; } if (TriggerEntity != null) { System.Session.TriggerEntityPool.Return(TriggerEntity); TriggerEntity = null; } AvShot = null; System = null; Ai = null; MyPlanet = null; MyShield = null; ConsumableDef = null; WeaponCache = null; VoxelCache = null; IsShrapnel = false; EwarAreaPulse = false; EwarActive = false; ModelOnly = false; LockOnFireState = false; IsFiringPlayer = false; ClientSent = false; InPlanetGravity = false; TriggerGrowthSteps = 0; WeaponId = 0; MuzzleId = 0; Age = 0; ProjectileDisplacement = 0; MaxTrajectory = 0; ShotFade = 0; TracerLength = 0; FireCounter = 0; AiVersion = 0; UniqueMuzzleId = 0; EnableGuidance = true; Hit = new Hit(); Direction = Vector3D.Zero; Origin = Vector3D.Zero; ShooterVel = Vector3D.Zero; TriggerMatrix = MatrixD.Identity; }