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); } }
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; }
public WeaponStructure(Session session, KeyValuePair <string, Dictionary <string, MyTuple <string, string, string> > > tDef, List <WeaponDefinition> wDefList) { Session = session; var map = tDef.Value; var numOfParts = wDefList.Count; MultiParts = numOfParts > 1; var muzzlePartNames = new MyStringHash[numOfParts]; var weaponId = 0; WeaponSystems = new Dictionary <MyStringHash, WeaponSystem>(MyStringHash.Comparer); HashToId = new Dictionary <int, int>(); var gridWeaponCap = 0; foreach (var w in map) { var myMuzzleNameHash = MyStringHash.GetOrCompute(w.Key); var myAzimuthNameHash = MyStringHash.GetOrCompute(w.Value.Item2); var myElevationNameHash = MyStringHash.GetOrCompute(w.Value.Item3); muzzlePartNames[weaponId] = myMuzzleNameHash; var typeName = w.Value.Item1; var weaponDef = new WeaponDefinition(); foreach (var weapon in wDefList) { if (weapon.HardPoint.WeaponName == typeName) { weaponDef = weapon; } } var cap = weaponDef.HardPoint.Other.GridWeaponCap; if (gridWeaponCap == 0 && cap > 0) { gridWeaponCap = cap; } else if (cap > 0 && gridWeaponCap > 0 && cap < gridWeaponCap) { gridWeaponCap = cap; } weaponDef.HardPoint.DeviateShotAngle = MathHelper.ToRadians(weaponDef.HardPoint.DeviateShotAngle); var shrapnelNames = new HashSet <string>(); for (int i = 0; i < weaponDef.Ammos.Length; i++) { var ammo = weaponDef.Ammos[i]; if (!shrapnelNames.Contains(ammo.Shrapnel.AmmoRound) && !string.IsNullOrEmpty(ammo.Shrapnel.AmmoRound)) { shrapnelNames.Add(ammo.Shrapnel.AmmoRound); } } var weaponAmmo = new WeaponAmmoTypes[weaponDef.Ammos.Length]; for (int i = 0; i < weaponDef.Ammos.Length; i++) { var ammo = weaponDef.Ammos[i]; var ammoDefId = new MyDefinitionId(); var ammoEnergy = ammo.AmmoMagazine == string.Empty || ammo.AmmoMagazine == "Energy"; foreach (var def in Session.AllDefinitions) { if (ammoEnergy && def.Id.SubtypeId.String == "Energy" || def.Id.SubtypeId.String == ammo.AmmoMagazine) { ammoDefId = def.Id; } } Session.AmmoInventoriesMaster[ammoDefId] = new ConcurrentDictionary <MyInventory, MyFixedPoint>(); weaponAmmo[i] = new WeaponAmmoTypes { AmmoDef = ammo, AmmoDefinitionId = ammoDefId, AmmoName = ammo.AmmoRound, IsShrapnel = shrapnelNames.Contains(ammo.AmmoRound) }; } var weaponIdHash = (tDef.Key + myElevationNameHash + myMuzzleNameHash + myAzimuthNameHash).GetHashCode(); HashToId.Add(weaponIdHash, weaponId); WeaponSystems.Add(myMuzzleNameHash, new WeaponSystem(Session, myMuzzleNameHash, myAzimuthNameHash, myElevationNameHash, weaponDef, typeName, weaponAmmo, weaponIdHash, weaponId)); weaponId++; } GridWeaponCap = gridWeaponCap; MuzzlePartNames = muzzlePartNames; }
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; }