internal PartAnimation(PartAnimation copyFromAnimation) { EventTrigger = copyFromAnimation.EventTrigger; RotationSet = copyFromAnimation.RotationSet; RotCenterSet = copyFromAnimation.RotCenterSet; CurrentEmissivePart = copyFromAnimation.CurrentEmissivePart; AnimationId = copyFromAnimation.AnimationId; ResetEmissives = copyFromAnimation.ResetEmissives; EmissiveIds = copyFromAnimation.EmissiveIds; //Unique Animation ID _uid = Guid.NewGuid(); TypeSet = copyFromAnimation.TypeSet; Muzzle = copyFromAnimation.Muzzle; MoveToSetIndexer = copyFromAnimation.MoveToSetIndexer; NumberOfMoves = copyFromAnimation.NumberOfMoves; System = copyFromAnimation.System; SubpartId = copyFromAnimation.SubpartId; MotionDelay = copyFromAnimation.MotionDelay; DoesLoop = copyFromAnimation.DoesLoop; DoesReverse = copyFromAnimation.DoesReverse; TriggerOnce = copyFromAnimation.TriggerOnce; _currentMove = 0; MovesPivotPos = copyFromAnimation.MovesPivotPos; FinalPos = copyFromAnimation.FinalPos; HomePos = copyFromAnimation.HomePos; HasMovement = copyFromAnimation.HasMovement; EmissiveParts = copyFromAnimation.EmissiveParts; EventIdLookup = copyFromAnimation.EventIdLookup; }
internal void Close() { // Reset only vars that are not always set Hit = new Hit(); if (AmmoSound) { TravelEmitter.StopSound(true); AmmoSound = false; } HitVelocity = Vector3D.Zero; TracerBack = Vector3D.Zero; TracerFront = Vector3D.Zero; ClosestPointOnLine = Vector3D.Zero; Color = Vector4.Zero; OnScreen = Screen.None; Tracer = TracerState.Off; Trail = TrailState.Off; LifeTime = 0; TracerSteps = 0; TracerStep = 0; DistanceToLine = 0; TracerWidth = 0; TrailWidth = 0; TrailScaler = 0; MaxTrajectory = 0; ShotFade = 0; ParentId = ulong.MaxValue; Dirty = false; AmmoSound = false; HitSoundActive = false; StartSoundActived = false; IsShrapnel = false; HasTravelSound = false; HitParticle = ParticleState.None; Triggered = false; Cloaked = false; Active = false; TrailActivated = false; ShrinkInited = false; Hitting = false; Back = false; LastStep = false; DetonateFakeExp = false; TracerShrinks.Clear(); GlowSteps.Clear(); Offsets.Clear(); // FiringWeapon = null; PrimeEntity = null; TriggerEntity = null; Ai = null; AmmoDef = null; System = null; }
private static bool AcquireBlock(WeaponSystem system, GridAi ai, Target target, TargetInfo info, Vector3D weaponPos, WeaponRandomGenerator wRng, RandomType type, ref BoundingSphereD waterSphere, Weapon w = null, bool checkPower = true) { if (system.TargetSubSystems) { var subSystems = system.Values.Targeting.SubSystems; var targetLinVel = info.Target.Physics?.LinearVelocity ?? Vector3D.Zero; var targetAccel = (int)system.Values.HardPoint.AimLeadingPrediction > 1 ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero; var focusSubSystem = w != null && w.Comp.Data.Repo.Base.Set.Overrides.FocusSubSystem; foreach (var blockType in subSystems) { var bt = focusSubSystem ? w.Comp.Data.Repo.Base.Set.Overrides.SubSystem : blockType; ConcurrentDictionary <BlockTypes, ConcurrentCachingList <MyCubeBlock> > blockTypeMap; system.Session.GridToBlockTypeMap.TryGetValue((MyCubeGrid)info.Target, out blockTypeMap); if (bt != Any && blockTypeMap != null && blockTypeMap[bt].Count > 0) { var subSystemList = blockTypeMap[bt]; if (system.ClosestFirst) { if (target.Top5.Count > 0 && (bt != target.LastBlockType || target.Top5[0].CubeGrid != subSystemList[0].CubeGrid)) { target.Top5.Clear(); } target.LastBlockType = bt; if (GetClosestHitableBlockOfType(subSystemList, ai, target, weaponPos, targetLinVel, targetAccel, ref waterSphere, w, checkPower)) { return(true); } } else if (FindRandomBlock(system, ai, target, weaponPos, info, subSystemList, w, wRng, type, ref waterSphere, checkPower)) { return(true); } } if (focusSubSystem) { break; } } if (system.OnlySubSystems || focusSubSystem && w.Comp.Data.Repo.Base.Set.Overrides.SubSystem != Any) { return(false); } } FatMap fatMap; return(system.Session.GridToFatMap.TryGetValue((MyCubeGrid)info.Target, out fatMap) && fatMap.MyCubeBocks != null && FindRandomBlock(system, ai, target, weaponPos, info, fatMap.MyCubeBocks, w, wRng, type, ref waterSphere, checkPower)); }
private void GetPeakDps(WeaponAmmoTypes ammoDef, WeaponSystem system, WeaponDefinition wDef, out float peakDps, out float shotsPerSec, out float baseDps, out float areaDps, out float detDps) { var s = system; var a = ammoDef.AmmoDef; var hasShrapnel = ShrapnelId > -1; var l = wDef.HardPoint.Loading; if (s.ReloadTime > 0 || MagazineSize > 0) { var burstPerMag = l.ShotsInBurst > 0 ? (int)Math.Floor((double)(MagazineSize / l.ShotsInBurst)) : 0; burstPerMag = burstPerMag >= 1 ? burstPerMag - 1 : burstPerMag; var drainPerMin = ((MagazineSize / (float)s.RateOfFire) / s.BarrelsPerShot) * 3600.0f; drainPerMin = MagazineSize >= 1 ? drainPerMin : 1; var timeSpentOnBurst = l.DelayAfterBurst > 0 ? burstPerMag * l.DelayAfterBurst : 0; var timePerMag = drainPerMin + s.ReloadTime + timeSpentOnBurst; shotsPerSec = ((3600f / timePerMag) * MagazineSize) / 60 * l.TrajectilesPerBarrel; baseDps = BaseDamage * shotsPerSec; areaDps = !AmmoAreaEffect ? 0 : (float)((a.AreaEffect.AreaEffectDamage * (a.AreaEffect.AreaEffectRadius * 0.5f)) * shotsPerSec); detDps = a.AreaEffect.Detonation.DetonateOnEnd ? (a.AreaEffect.Detonation.DetonationDamage * (a.AreaEffect.Detonation.DetonationRadius * 0.5f)) * shotsPerSec : 0; if (hasShrapnel) { var sAmmo = wDef.Ammos[ShrapnelId]; var fragments = a.Shrapnel.Fragments; baseDps += sAmmo.BaseDamage * fragments; areaDps += sAmmo.AreaEffect.AreaEffect == AreaEffectType.Disabled ? 0 : (float)((sAmmo.AreaEffect.AreaEffectDamage * (sAmmo.AreaEffect.AreaEffectRadius * 0.5f)) * fragments); detDps += sAmmo.AreaEffect.Detonation.DetonateOnEnd ? (sAmmo.AreaEffect.Detonation.DetonationDamage * (sAmmo.AreaEffect.Detonation.DetonationRadius * 0.5f)) * fragments : 0; } peakDps = (baseDps + areaDps + detDps); } else { var timeSpentOnBurst = l.DelayAfterBurst > 0 ? ((3600 / s.RateOfFire) * (l.ShotsInBurst / s.BarrelsPerShot)) + l.DelayAfterBurst : 0; shotsPerSec = timeSpentOnBurst > 0 ? (((3600 / timeSpentOnBurst) * l.ShotsInBurst) / 60 * l.TrajectilesPerBarrel) * s.BarrelsPerShot : (((60) / (3600 / s.RateOfFire)) * l.TrajectilesPerBarrel) * s.BarrelsPerShot; baseDps = BaseDamage * shotsPerSec; areaDps = !AmmoAreaEffect ? 0 : (float)((a.AreaEffect.AreaEffectDamage * (a.AreaEffect.AreaEffectRadius * 0.5f)) * shotsPerSec); detDps = a.AreaEffect.Detonation.DetonateOnEnd ? (a.AreaEffect.Detonation.DetonationDamage * (a.AreaEffect.Detonation.DetonationRadius * 0.5f)) * shotsPerSec : 0; if (hasShrapnel) { var sAmmo = wDef.Ammos[ShrapnelId]; var fragments = a.Shrapnel.Fragments; baseDps += sAmmo.BaseDamage * fragments; areaDps += sAmmo.AreaEffect.AreaEffect == AreaEffectType.Disabled ? 0 : (float)((sAmmo.AreaEffect.AreaEffectDamage * (sAmmo.AreaEffect.AreaEffectRadius * 0.5f)) * fragments); detDps += sAmmo.AreaEffect.Detonation.DetonateOnEnd ? (sAmmo.AreaEffect.Detonation.DetonationDamage * (sAmmo.AreaEffect.Detonation.DetonationRadius * 0.5f)) * fragments : 0; } peakDps = (baseDps + areaDps + detDps); } }
internal void Init(ProInfo info, double firstStepSize, double maxSpeed) { System = info.System; AmmoDef = info.AmmoDef; Ai = info.Ai; IsShrapnel = info.IsShrapnel; if (ParentId != ulong.MaxValue) { Log.Line($"invalid avshot, parentId:{ParentId}"); } ParentId = info.Id; Model = (info.AmmoDef.Const.PrimeModel || info.AmmoDef.Const.TriggerModel) ? Model = ModelState.Exists : Model = ModelState.None; PrimeEntity = info.PrimeEntity; TriggerEntity = info.TriggerEntity; Origin = info.Origin; Offset = AmmoDef.Const.OffsetEffect; MaxTracerLength = info.TracerLength; MuzzleId = info.MuzzleId; WeaponId = info.WeaponId; MaxSpeed = maxSpeed; MaxStepSize = MaxSpeed * MyEngineConstants.PHYSICS_STEP_SIZE_IN_SECONDS; ShootVelStep = info.ShooterVel * MyEngineConstants.PHYSICS_STEP_SIZE_IN_SECONDS; info.Ai.WeaponBase.TryGetValue(info.Target.FiringCube, out FiringWeapon); MaxTrajectory = info.MaxTrajectory; ShotFade = info.ShotFade; ShrinkInited = false; HitEmitter.CanPlayLoopSounds = false; if (AmmoDef.Const.DrawLine) { Tracer = !AmmoDef.Const.IsBeamWeapon && firstStepSize < MaxTracerLength && !MyUtils.IsZero(firstStepSize - MaxTracerLength, 1E-01F) ? TracerState.Grow : TracerState.Full; } else { Tracer = TracerState.Off; } if (AmmoDef.Const.Trail) { MaxGlowLength = MathHelperD.Clamp(AmmoDef.AmmoGraphics.Lines.Trail.DecayTime * MaxStepSize, 0.1f, MaxTrajectory); Trail = AmmoDef.AmmoGraphics.Lines.Trail.Back ? TrailState.Back : Trail = TrailState.Front; GlowShrinkSize = !AmmoDef.AmmoGraphics.Lines.Trail.UseColorFade ? AmmoDef.Const.TrailWidth / AmmoDef.AmmoGraphics.Lines.Trail.DecayTime : 1f / AmmoDef.AmmoGraphics.Lines.Trail.DecayTime; Back = Trail == TrailState.Back; } else { Trail = TrailState.Off; } TotalLength = MathHelperD.Clamp(MaxTracerLength + MaxGlowLength, 0.1f, MaxTrajectory); }
internal void InitVirtual(WeaponSystem system, GridAi ai, AmmoDef ammodef, MyEntity primeEntity, MyEntity triggerEntity, Target target, int weaponId, int muzzleId, Vector3D origin, Vector3D virDirection) { System = system; Ai = ai; AmmoDef = ammodef; PrimeEntity = primeEntity; TriggerEntity = triggerEntity; Target.Entity = target.Entity; Target.Projectile = target.Projectile; Target.FiringCube = target.FiringCube; WeaponId = weaponId; MuzzleId = muzzleId; Direction = virDirection; Origin = origin; }
internal void Clean(uint expireTick) { Target.Reset(expireTick, Target.States.ProjectileClosed); HitList.Clear(); if (PrimeEntity != null) { AmmoDef.Const.PrimeEntityPool.Return(PrimeEntity); PrimeEntity = null; } if (TriggerEntity != null) { Ai.Session.TriggerEntityPool.Return(TriggerEntity); TriggerEntity = null; } AvShot = null; System = null; Ai = null; AmmoDef = null; WeaponCache = null; LastHitShield = false; IsShrapnel = false; TriggeredPulse = false; EwarActive = false; ModelOnly = false; LockOnFireState = false; IsFiringPlayer = false; ClientSent = false; TriggerGrowthSteps = 0; WeaponId = 0; MuzzleId = 0; Age = 0; ProjectileDisplacement = 0; MaxTrajectory = 0; ShotFade = 0; TracerLength = 0; EnableGuidance = true; Direction = Vector3D.Zero; VisualDir = Vector3D.Zero; Origin = Vector3D.Zero; ShooterVel = Vector3D.Zero; TriggerMatrix = MatrixD.Identity; }
internal void InitVirtual(Weapon weapon, AmmoDef 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; AmmoDef = 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 Energy(WeaponAmmoTypes ammoPair, WeaponSystem system, WeaponDefinition wDef, out bool energyAmmo, out bool mustCharge, out bool reloadable, out int energyMagSize, out bool burstMode, out bool shotReload) { energyAmmo = ammoPair.AmmoDefinitionId.SubtypeId.String == "Energy" || ammoPair.AmmoDefinitionId.SubtypeId.String == string.Empty; mustCharge = (energyAmmo || IsHybrid) && system.ReloadTime > 0; reloadable = !energyAmmo || mustCharge; burstMode = wDef.HardPoint.Loading.ShotsInBurst > 0 && (energyAmmo || MagazineDef.Capacity >= wDef.HardPoint.Loading.ShotsInBurst); shotReload = !burstMode && wDef.HardPoint.Loading.ShotsInBurst > 0 && wDef.HardPoint.Loading.DelayAfterBurst > 0; if (mustCharge) { var ewar = (int)ammoPair.AmmoDef.AreaEffect.AreaEffect > 3; var shotEnergyCost = ewar ? ammoPair.AmmoDef.EnergyCost * AreaEffectDamage : ammoPair.AmmoDef.EnergyCost * BaseDamage; var requiredPower = (((shotEnergyCost * ((system.RateOfFire / MyEngineConstants.UPDATE_STEPS_PER_SECOND) * MyEngineConstants.PHYSICS_STEP_SIZE_IN_SECONDS)) * wDef.HardPoint.Loading.BarrelsPerShot) * wDef.HardPoint.Loading.TrajectilesPerBarrel); energyMagSize = (int)Math.Ceiling(requiredPower * (system.ReloadTime / MyEngineConstants.UPDATE_STEPS_PER_SECOND)); return; } energyMagSize = int.MaxValue; }
internal static Vector3D?ProcessVoxel(LineD trajectile, MyVoxelBase voxel, WeaponSystem system, List <Vector3I> testPoints) { var planet = voxel as MyPlanet; var voxelMap = voxel as MyVoxelMap; var ray = new RayD(trajectile.From, trajectile.Direction); var voxelAABB = voxel.PositionComp.WorldAABB; var rayVoxelDist = ray.Intersects(voxelAABB); if (rayVoxelDist.HasValue) { var voxelMaxLen = voxel.PositionComp.WorldVolume.Radius * 2; var start = trajectile.From + (ray.Direction * rayVoxelDist.Value); var lenRemain = trajectile.Length - rayVoxelDist.Value; var end = voxelMaxLen > lenRemain ? start + (ray.Direction * lenRemain) : start + (ray.Direction * voxelMaxLen); var testLine = new LineD(trajectile.From + (ray.Direction * rayVoxelDist.Value), end); var rotMatrix = Quaternion.CreateFromRotationMatrix(voxel.WorldMatrix); var obb = new MyOrientedBoundingBoxD(voxel.PositionComp.WorldAABB.Center, voxel.PositionComp.LocalAABB.HalfExtents, rotMatrix); if (obb.Intersects(ref testLine) != null) { Log.Line("obb"); if (planet != null) { var startPos = trajectile.From - planet.PositionLeftBottomCorner; var startInt = Vector3I.Round(startPos); var endPos = trajectile.To - planet.PositionLeftBottomCorner; var endInt = Vector3I.Round(endPos); BresenhamLineDraw(startInt, endInt, testPoints); for (int i = 0; i < testPoints.Count; ++i) { var voxelCoord = testPoints[i]; var voxelHit = new VoxelHit(); planet.Storage.ExecuteOperationFast(ref voxelHit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false); if (voxelHit.HasHit) { return((Vector3D)voxelCoord + planet.PositionLeftBottomCorner); } } } else if (voxelMap != null) { var startPos = trajectile.From - voxelMap.PositionLeftBottomCorner; var startInt = Vector3I.Round(startPos); var endPos = trajectile.To - voxelMap.PositionLeftBottomCorner; var endInt = Vector3I.Round(endPos); BresenhamLineDraw(startInt, endInt, testPoints); for (int i = 0; i < testPoints.Count; ++i) { var voxelCoord = testPoints[i]; var voxelHit = new VoxelHit(); voxelMap.Storage.ExecuteOperationFast(ref voxelHit, MyStorageDataTypeFlags.Content, ref voxelCoord, ref voxelCoord, notifyRangeChanged: false); if (voxelHit.HasHit) { return((Vector3D)voxelCoord + voxelMap.PositionLeftBottomCorner); } } } } } return(null); }
private static bool FindRandomBlock(WeaponSystem system, GridAi ai, Target target, Vector3D weaponPos, TargetInfo info, ConcurrentCachingList <MyCubeBlock> subSystemList, Weapon w, WeaponRandomGenerator wRng, RandomType type, ref BoundingSphereD waterSphere, bool checkPower = true) { var totalBlocks = subSystemList.Count; var topEnt = info.Target.GetTopMostParent(); var entSphere = topEnt.PositionComp.WorldVolume; var distToEnt = MyUtils.GetSmallestDistanceToSphere(ref weaponPos, ref entSphere); var turretCheck = w != null; var topBlocks = system.Values.Targeting.TopBlocks; var lastBlocks = topBlocks > 10 && distToEnt < 1000 ? topBlocks : 10; var isPriroity = false; if (lastBlocks < 250) { TargetInfo priorityInfo; MyEntity fTarget; if (ai.Construct.Data.Repo.FocusData.Target[0] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[0], out fTarget) && ai.Targets.TryGetValue(fTarget, out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt) { isPriroity = true; lastBlocks = totalBlocks < 250 ? totalBlocks : 250; } else if (ai.Construct.Data.Repo.FocusData.Target[1] > 0 && MyEntities.TryGetEntityById(ai.Construct.Data.Repo.FocusData.Target[1], out fTarget) && ai.Targets.TryGetValue(fTarget, out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt) { isPriroity = true; lastBlocks = totalBlocks < 250 ? totalBlocks : 250; } } if (totalBlocks < lastBlocks) { lastBlocks = totalBlocks; } var deck = GetDeck(ref target.BlockDeck, ref target.BlockPrevDeckLen, 0, totalBlocks, topBlocks, wRng, type); var physics = system.Session.Physics; var iGrid = topEnt as IMyCubeGrid; var gridPhysics = iGrid?.Physics; Vector3D targetLinVel = gridPhysics?.LinearVelocity ?? Vector3D.Zero; Vector3D targetAccel = (int)system.Values.HardPoint.AimLeadingPrediction > 1 ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero; var foundBlock = false; var blocksChecked = 0; var blocksSighted = 0; for (int i = 0; i < totalBlocks; i++) { if (turretCheck && (blocksChecked > lastBlocks || isPriroity && (blocksSighted > 100 || blocksChecked > 50 && system.Session.RandomRayCasts > 500 || blocksChecked > 25 && system.Session.RandomRayCasts > 1000))) { break; } var card = deck[i]; var block = subSystemList[card]; if (!(block is IMyTerminalBlock) || block.MarkedForClose || checkPower && !block.IsWorking) { continue; } system.Session.BlockChecks++; var blockPos = block.CubeGrid.GridIntegerToWorld(block.Position); double rayDist; if (turretCheck) { double distSqr; Vector3D.DistanceSquared(ref blockPos, ref weaponPos, out distSqr); if (distSqr > w.MaxTargetDistanceSqr || distSqr < w.MinTargetDistanceSqr) { continue; } blocksChecked++; ai.Session.CanShoot++; Vector3D predictedPos; if (!Weapon.CanShootTarget(w, ref blockPos, targetLinVel, targetAccel, out predictedPos)) { continue; } if (system.Session.WaterApiLoaded && waterSphere.Radius > 2 && waterSphere.Contains(predictedPos) != ContainmentType.Disjoint) { continue; } blocksSighted++; system.Session.RandomRayCasts++; IHitInfo hitInfo; physics.CastRay(weaponPos, blockPos, out hitInfo, 15); if (hitInfo?.HitEntity == null || hitInfo.HitEntity is MyVoxelBase) { continue; } var hitGrid = hitInfo.HitEntity as MyCubeGrid; if (hitGrid != null) { if (hitGrid.MarkedForClose || hitGrid != block.CubeGrid && hitGrid.IsSameConstructAs(ai.MyGrid)) { continue; } bool enemy; var bigOwners = hitGrid.BigOwners; if (bigOwners.Count == 0) { enemy = true; } else { var relationship = target.FiringCube.GetUserRelationToOwner(hitGrid.BigOwners[0]); enemy = relationship != MyRelationsBetweenPlayerAndBlock.Owner && relationship != MyRelationsBetweenPlayerAndBlock.FactionShare; } if (!enemy) { continue; } } Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist); var shortDist = rayDist * (1 - hitInfo.Fraction); var origDist = rayDist * hitInfo.Fraction; var topEntId = block.GetTopMostParent().EntityId; target.Set(block, hitInfo.Position, shortDist, origDist, topEntId); foundBlock = true; break; } Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist); target.Set(block, block.PositionComp.WorldAABB.Center, rayDist, rayDist, block.GetTopMostParent().EntityId); foundBlock = true; break; } return(foundBlock); }
internal static bool GetClosestHitableBlockOfType(ConcurrentCachingList <MyCubeBlock> cubes, GridAi ai, Target target, Vector3D currentPos, Vector3D targetLinVel, Vector3D targetAccel, WeaponSystem system, Weapon w = null, bool checkPower = true) { var minValue = double.MaxValue; var minValue0 = double.MaxValue; var minValue1 = double.MaxValue; var minValue2 = double.MaxValue; var minValue3 = double.MaxValue; MyCubeBlock newEntity = null; MyCubeBlock newEntity0 = null; MyCubeBlock newEntity1 = null; MyCubeBlock newEntity2 = null; MyCubeBlock newEntity3 = null; var bestCubePos = Vector3D.Zero; var top5Count = target.Top5.Count; var testPos = currentPos; var top5 = target.Top5; IHitInfo hitInfo = null; var notSelfHit = false; for (int i = 0; i < cubes.Count + top5Count; i++) { ai.Session.BlockChecks++; var index = i < top5Count ? i : i - top5Count; var cube = i < top5Count ? top5[index] : cubes[index]; var grid = cube.CubeGrid; if (grid?.Physics == null || !grid.Physics.Enabled || grid.PositionComp == null) { continue; } if (cube.MarkedForClose || checkPower && !cube.IsWorking || !(cube is IMyTerminalBlock) || cube == newEntity || cube == newEntity0 || cube == newEntity1 || cube == newEntity2 || cube == newEntity3) { continue; } var cubePos = grid.GridIntegerToWorld(cube.Position); var range = cubePos - testPos; var test = (range.X * range.X) + (range.Y * range.Y) + (range.Z * range.Z); if (test < minValue3) { IHitInfo hit = null; var best = test < minValue; var bestTest = false; if (best) { if (w != null && !(!w.IsTurret && w.ActiveAmmoDef.AmmoDef.Trajectory.Smarts.OverideTarget)) { ai.Session.CanShoot++; var castRay = false; Vector3D predictedPos; Vector3D?hitPos; if (Weapon.CanShootTarget(w, cubePos, targetLinVel, targetAccel, out predictedPos)) { castRay = !w.HitOther || !GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref testPos, ref cubePos, out hitPos, w.Comp.MyCube, w.Comp.Ai); } if (castRay) { ai.Session.ClosestRayCasts++; bestTest = MyAPIGateway.Physics.CastRay(testPos, cubePos, out hit, 15, true) && hit?.HitEntity == cube.CubeGrid; if (hit == null && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf()) || (hit.HitEntity != ai.MyGrid)) { notSelfHit = true; } } } else { bestTest = true; } } if (best && bestTest) { minValue3 = minValue2; newEntity3 = newEntity2; minValue2 = minValue1; newEntity2 = newEntity1; minValue1 = minValue0; newEntity1 = newEntity0; minValue0 = minValue; newEntity0 = newEntity; minValue = test; newEntity = cube; bestCubePos = cubePos; hitInfo = hit; } else if (test < minValue0) { minValue3 = minValue2; newEntity3 = newEntity2; minValue2 = minValue1; newEntity2 = newEntity1; minValue1 = minValue0; newEntity1 = newEntity0; minValue0 = test; newEntity0 = cube; } else if (test < minValue1) { minValue3 = minValue2; newEntity3 = newEntity2; minValue2 = minValue1; newEntity2 = newEntity1; minValue1 = test; newEntity1 = cube; } else if (test < minValue2) { minValue3 = minValue2; newEntity3 = newEntity2; minValue2 = test; newEntity2 = cube; } else { minValue3 = test; newEntity3 = cube; } } } top5.Clear(); if (newEntity != null && hitInfo != null) { double rayDist; Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist); var shortDist = rayDist * (1 - hitInfo.Fraction); var origDist = rayDist * hitInfo.Fraction; var topEntId = newEntity.GetTopMostParent().EntityId; target.Set(newEntity, hitInfo.Position, shortDist, origDist, topEntId); top5.Add(newEntity); } else if (newEntity != null) { double rayDist; Vector3D.Distance(ref testPos, ref bestCubePos, out rayDist); var shortDist = rayDist; var origDist = rayDist; var topEntId = newEntity.GetTopMostParent().EntityId; target.Set(newEntity, bestCubePos, shortDist, origDist, topEntId); top5.Add(newEntity); } else { target.Reset(ai.Session.Tick, Target.States.NoTargetsSeen, w == null); } if (newEntity0 != null) { top5.Add(newEntity0); } if (newEntity1 != null) { top5.Add(newEntity1); } if (newEntity2 != null) { top5.Add(newEntity2); } if (newEntity3 != null) { top5.Add(newEntity3); } if (!notSelfHit && w != null) { w.HitOther = true; } return(hitInfo != null); }
private static bool FindRandomBlock(WeaponSystem system, GridAi ai, Target target, Vector3D weaponPos, TargetInfo info, ConcurrentCachingList <MyCubeBlock> subSystemList, Weapon w, int seed, bool checkPower = true) { var totalBlocks = subSystemList.Count; var topEnt = info.Target.GetTopMostParent(); var entSphere = topEnt.PositionComp.WorldVolume; var distToEnt = MyUtils.GetSmallestDistanceToSphere(ref weaponPos, ref entSphere); var turretCheck = w != null; var topBlocks = system.Values.Targeting.TopBlocks; var lastBlocks = topBlocks > 10 && distToEnt < 1000 ? topBlocks : 10; var isPriroity = false; if (lastBlocks < 250) { TargetInfo priorityInfo; if (ai.Focus.Target[0] != null && ai.Targets.TryGetValue(ai.Focus.Target[0], out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt) { isPriroity = true; lastBlocks = totalBlocks < 250 ? totalBlocks : 250; } else if (ai.Focus.Target[1] != null && ai.Targets.TryGetValue(ai.Focus.Target[1], out priorityInfo) && priorityInfo.Target?.GetTopMostParent() == topEnt) { isPriroity = true; lastBlocks = totalBlocks < 250 ? totalBlocks : 250; } } if (totalBlocks < lastBlocks) { lastBlocks = totalBlocks; } var deck = GetDeck(ref target.BlockDeck, ref target.BlockPrevDeckLen, 0, totalBlocks, topBlocks, seed); var physics = ai.Session.Physics; var iGrid = topEnt as IMyCubeGrid; var gridPhysics = iGrid?.Physics; Vector3D targetLinVel = gridPhysics?.LinearVelocity ?? Vector3D.Zero; Vector3D targetAccel = (int)system.Values.HardPoint.AimLeadingPrediction > 1 ? info.Target.Physics?.LinearAcceleration ?? Vector3D.Zero : Vector3.Zero; var notSelfHit = false; var foundBlock = false; var blocksChecked = 0; var blocksSighted = 0; var weaponRangeSqr = turretCheck ? w.MaxTargetDistanceSqr : 0; for (int i = 0; i < totalBlocks; i++) { if (turretCheck && (blocksChecked > lastBlocks || isPriroity && (blocksSighted > 100 || blocksChecked > 50 && ai.Session.RandomRayCasts > 500 || blocksChecked > 25 && ai.Session.RandomRayCasts > 1000))) { break; } var card = deck[i]; var block = subSystemList[card]; if (!(block is IMyTerminalBlock) || block.MarkedForClose || checkPower && !block.IsWorking) { continue; } ai.Session.BlockChecks++; var blockPos = block.CubeGrid.GridIntegerToWorld(block.Position); double rayDist; if (turretCheck) { double distSqr; Vector3D.DistanceSquared(ref blockPos, ref weaponPos, out distSqr); if (distSqr > weaponRangeSqr) { continue; } blocksChecked++; ai.Session.CanShoot++; Vector3D predictedPos; if (!Weapon.CanShootTarget(w, blockPos, targetLinVel, targetAccel, out predictedPos)) { continue; } blocksSighted++; Vector3D?hitPos; if (!w.HitOther && GridIntersection.BresenhamGridIntersection(ai.MyGrid, ref weaponPos, ref blockPos, out hitPos, w.Comp.MyCube, w.Comp.Ai)) { continue; } ai.Session.RandomRayCasts++; IHitInfo hitInfo; physics.CastRay(weaponPos, blockPos, out hitInfo, 15, true); if (hitInfo == null || hitInfo.HitEntity != ai.MyGrid && (!w.System.Values.HardPoint.Other.MuzzleCheck || !w.MuzzleHitSelf())) { notSelfHit = true; } if (hitInfo?.HitEntity == null || hitInfo.HitEntity is MyVoxelBase || hitInfo.HitEntity == ai.MyGrid) { continue; } var hitGrid = hitInfo.HitEntity as MyCubeGrid; if (hitGrid != null) { if (hitGrid.MarkedForClose) { continue; } bool enemy; var bigOwners = hitGrid.BigOwners; if (bigOwners.Count == 0) { enemy = true; } else { var relationship = target.FiringCube.GetUserRelationToOwner(hitGrid.BigOwners[0]); enemy = relationship != MyRelationsBetweenPlayerAndBlock.Owner && relationship != MyRelationsBetweenPlayerAndBlock.FactionShare; } if (!enemy) { continue; } } Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist); var shortDist = rayDist * (1 - hitInfo.Fraction); var origDist = rayDist * hitInfo.Fraction; var topEntId = block.GetTopMostParent().EntityId; target.Set(block, hitInfo.Position, shortDist, origDist, topEntId); foundBlock = true; break; } Vector3D.Distance(ref weaponPos, ref blockPos, out rayDist); target.Set(block, block.PositionComp.WorldAABB.Center, rayDist, rayDist, block.GetTopMostParent().EntityId); foundBlock = true; break; } if (turretCheck && !notSelfHit) { w.HitOther = true; } return(foundBlock); }
public AmmoConstants(WeaponAmmoTypes ammo, WeaponDefinition wDef, Session session, WeaponSystem system) { MyInventory.GetItemVolumeAndMass(ammo.AmmoDefinitionId, out MagMass, out MagVolume); MagazineDef = MyDefinitionManager.Static.GetAmmoMagazineDefinition(ammo.AmmoDefinitionId); TracerMaterial = MyStringId.GetOrCompute(ammo.AmmoDef.AmmoGraphics.Lines.TracerMaterial); TrailMaterial = MyStringId.GetOrCompute(ammo.AmmoDef.AmmoGraphics.Lines.Trail.Material); if (ammo.AmmoDefinitionId.SubtypeId.String != "Energy" || ammo.AmmoDefinitionId.SubtypeId.String == string.Empty) { AmmoItem = new MyPhysicalInventoryItem() { Amount = 1, Content = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_AmmoMagazine>(ammo.AmmoDefinitionId.SubtypeName) } } ; for (int i = 0; i < wDef.Ammos.Length; i++) { var ammoType = wDef.Ammos[i]; if (ammoType.AmmoRound.Equals(ammo.AmmoDef.Shrapnel.AmmoRound)) { ShrapnelId = i; } } IsMine = ammo.AmmoDef.Trajectory.Guidance == DetectFixed || ammo.AmmoDef.Trajectory.Guidance == DetectSmart || ammo.AmmoDef.Trajectory.Guidance == DetectTravelTo; IsField = ammo.AmmoDef.Trajectory.FieldTime > 0; IsHybrid = ammo.AmmoDef.HybridRound; IsTurretSelectable = !ammo.IsShrapnel || ammo.AmmoDef.HardPointUsable; AmmoParticle = ammo.AmmoDef.AmmoGraphics.Particles.Ammo.Name != string.Empty; AmmoParticleShrinks = ammo.AmmoDef.AmmoGraphics.Particles.Ammo.ShrinkByDistance; HitParticleShrinks = ammo.AmmoDef.AmmoGraphics.Particles.Hit.ShrinkByDistance; HitParticle = ammo.AmmoDef.AmmoGraphics.Particles.Hit.Name != string.Empty; DrawLine = ammo.AmmoDef.AmmoGraphics.Lines.Tracer.Enable; LineColorVariance = ammo.AmmoDef.AmmoGraphics.Lines.ColorVariance.Start > 0 && ammo.AmmoDef.AmmoGraphics.Lines.ColorVariance.End > 0; LineWidthVariance = ammo.AmmoDef.AmmoGraphics.Lines.WidthVariance.Start > 0 || ammo.AmmoDef.AmmoGraphics.Lines.WidthVariance.End > 0; SpeedVariance = ammo.AmmoDef.Trajectory.SpeedVariance.Start > 0 || ammo.AmmoDef.Trajectory.SpeedVariance.End > 0; RangeVariance = ammo.AmmoDef.Trajectory.RangeVariance.Start > 0 || ammo.AmmoDef.Trajectory.RangeVariance.End > 0; TrailWidth = ammo.AmmoDef.AmmoGraphics.Lines.Trail.CustomWidth > 0 ? ammo.AmmoDef.AmmoGraphics.Lines.Trail.CustomWidth : ammo.AmmoDef.AmmoGraphics.Lines.Tracer.Width; TargetOffSet = ammo.AmmoDef.Trajectory.Smarts.Inaccuracy > 0; TargetLossTime = ammo.AmmoDef.Trajectory.TargetLossTime > 0 ? ammo.AmmoDef.Trajectory.TargetLossTime : int.MaxValue; CanZombie = TargetLossTime > 0 && TargetLossTime != int.MaxValue && !IsMine; MaxLifeTime = ammo.AmmoDef.Trajectory.MaxLifeTime > 0 ? ammo.AmmoDef.Trajectory.MaxLifeTime : int.MaxValue; MaxChaseTime = ammo.AmmoDef.Trajectory.Smarts.MaxChaseTime > 0 ? ammo.AmmoDef.Trajectory.Smarts.MaxChaseTime : int.MaxValue; MaxObjectsHit = ammo.AmmoDef.ObjectsHit.MaxObjectsHit > 0 ? ammo.AmmoDef.ObjectsHit.MaxObjectsHit : int.MaxValue; BaseDamage = ammo.AmmoDef.BaseDamage; MaxTargets = ammo.AmmoDef.Trajectory.Smarts.MaxTargets; TargetLossDegree = ammo.AmmoDef.Trajectory.TargetLossDegree > 0 ? (float)Math.Cos(MathHelper.ToRadians(ammo.AmmoDef.Trajectory.TargetLossDegree)) : 0; ShieldModifier = ammo.AmmoDef.DamageScales.Shields.Modifier > 0 ? ammo.AmmoDef.DamageScales.Shields.Modifier : 1; ShieldBypassMod = ammo.AmmoDef.DamageScales.Shields.BypassModifier > 0 && ammo.AmmoDef.DamageScales.Shields.BypassModifier < 1 ? ammo.AmmoDef.DamageScales.Shields.BypassModifier : 1; AmmoSkipAccel = ammo.AmmoDef.Trajectory.AccelPerSec <= 0; FeelsGravity = ammo.AmmoDef.Trajectory.GravityMultiplier > 0; MaxTrajectory = ammo.AmmoDef.Trajectory.MaxTrajectory; MaxTrajectorySqr = MaxTrajectory * MaxTrajectory; HasBackKickForce = ammo.AmmoDef.BackKickForce > 0; MaxLateralThrust = MathHelperD.Clamp(ammo.AmmoDef.Trajectory.Smarts.MaxLateralThrust, 0.000001, 1); Fields(ammo.AmmoDef, out PulseInterval, out PulseChance, out Pulse); AreaEffects(ammo.AmmoDef, out AreaEffect, out AreaEffectDamage, out AreaEffectSize, out DetonationDamage, out AmmoAreaEffect, out AreaRadiusSmall, out AreaRadiusLarge, out DetonateRadiusSmall, out DetonateRadiusLarge, out Ewar, out EwarEffect, out EwarTriggerRange); DamageScales(ammo.AmmoDef, out DamageScaling, out FallOffScaling, out ArmorScaling, out CustomDamageScales, out CustomBlockDefinitionBasesToScales, out SelfDamage, out VoxelDamage); Beams(ammo.AmmoDef, out IsBeamWeapon, out VirtualBeams, out RotateRealBeam, out ConvergeBeams, out OneHitParticle, out OffsetEffect); CollisionShape(ammo.AmmoDef, out CollisionIsLine, out CollisionSize, out TracerLength); SmartsDelayDistSqr = (CollisionSize * ammo.AmmoDef.Trajectory.Smarts.TrackingDelay) * (CollisionSize * ammo.AmmoDef.Trajectory.Smarts.TrackingDelay); PrimeEntityPool = Models(ammo.AmmoDef, wDef, out PrimeModel, out TriggerModel, out ModelPath); Energy(ammo, system, wDef, out EnergyAmmo, out MustCharge, out Reloadable, out EnergyMagSize, out BurstMode, out HasShotReloadDelay); Sound(ammo.AmmoDef, session, out HitSound, out AmmoTravelSound, out HitSoundDistSqr, out AmmoTravelSoundDistSqr, out AmmoSoundMaxDistSqr); MagazineSize = EnergyAmmo ? EnergyMagSize : MagazineDef.Capacity; GetPeakDps(ammo, system, wDef, out PeakDps, out ShotsPerSec, out BaseDps, out AreaDps, out DetDps); DesiredProjectileSpeed = (float)(!IsBeamWeapon ? ammo.AmmoDef.Trajectory.DesiredSpeed : MaxTrajectory * MyEngineConstants.UPDATE_STEPS_PER_SECOND); Trail = ammo.AmmoDef.AmmoGraphics.Lines.Trail.Enable; }
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) { AmmoDef.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; AmmoDef = 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; VisualDir = Vector3D.Zero; Origin = Vector3D.Zero; ShooterVel = Vector3D.Zero; TriggerMatrix = MatrixD.Identity; }
internal PartAnimation(EventTriggers eventTrigger, string animationId, Matrix[] rotationSet, Matrix[] rotCeterSet, AnimationType[] typeSet, string[] emissiveIds, int[] currentEmissivePart, int[][] moveToSetIndexer, string subpartId, MyEntity part, MyEntity mainEnt, string muzzle, uint motionDelay, WeaponSystem system, bool loop = false, bool reverse = false, bool triggerOnce = false, bool resetEmissives = false) { EventTrigger = eventTrigger; RotationSet = rotationSet; RotCenterSet = rotCeterSet; CurrentEmissivePart = currentEmissivePart; AnimationId = animationId; ResetEmissives = resetEmissives; EmissiveIds = emissiveIds; //Unique Animation ID _uid = Guid.NewGuid(); TypeSet = typeSet; Muzzle = muzzle; MoveToSetIndexer = moveToSetIndexer; NumberOfMoves = MoveToSetIndexer.Length; Part = part; System = system; SubpartId = subpartId; MotionDelay = motionDelay; MainEnt = mainEnt; DoesLoop = loop; DoesReverse = reverse; TriggerOnce = triggerOnce; _currentMove = 0; if (part != null) { FinalPos = HomePos = part.PositionComp.LocalMatrixRef; var emissivePartCheck = new HashSet <string>(); var emissiveParts = new List <string>(); for (int i = 0; i < NumberOfMoves; i++) { Matrix rotation; Matrix rotAroundCenter; Vector3D translation; AnimationType animationType; EmissiveState currentEmissive; GetCurrentMove(out translation, out rotation, out rotAroundCenter, out animationType, out currentEmissive); if (animationType == AnimationType.Movement) { HasMovement = true; FinalPos.Translation += translation; } if (rotation != Matrix.Zero) { HasMovement = true; FinalPos *= rotation; } if (rotAroundCenter != Matrix.Zero) { HasMovement = true; FinalPos *= rotAroundCenter; } if (currentEmissive.EmissiveParts != null) { for (int j = 0; j < currentEmissive.EmissiveParts.Length; j++) { var currEmissive = currentEmissive.EmissiveParts[j]; if (emissivePartCheck.Contains(currEmissive)) { continue; } emissivePartCheck.Add(currEmissive); emissiveParts.Add(currEmissive); } } Next(); } EmissiveParts = emissiveParts.ToArray(); Reset(); foreach (var evnt in Enum.GetNames(typeof(EventTriggers))) { EventTriggers trigger; Enum.TryParse(evnt, out trigger); EventIdLookup.Add(trigger, evnt + SubpartId); } CheckAffectPivot(part, out MovesPivotPos); } }