Exemple #1
0
        /// <summary>
        /// Loads user definitons for ammo and weapons
        /// </summary>
        private static void LoadUserDefinitions()
        {
            Type ammoType = typeof(AmmoDefinition);

            foreach (AmmoDefinition def in KeenAmmoDefinitions)
            {
                string filename = $"Ammo_{def.SubtypeId}";
                if (FileExistsInWorldStorage(filename, ammoType))
                {
                    try
                    {
                        TextReader     r = MyAPIGateway.Utilities.ReadFileInWorldStorage(filename, ammoType);
                        AmmoDefinition a = MyAPIGateway.Utilities.SerializeFromXML <AmmoDefinition>(r.ReadToEnd());
                        r.Close();

                        Tools.Info($"{((a.Enabled) ? "(ENABLED)" : "(DISABLED)")} Loading user ammo definition {a.SubtypeId}");

                        if (a.Enabled)
                        {
                            Static.AmmoDefinitions.Add(a);
                        }
                    }
                    catch
                    {
                        Tools.Error($"Failed to load file {def.SubtypeId}");
                    }
                }
            }


            Type weaponType = typeof(WeaponDefinition);

            foreach (WeaponDefinition def in KeenWeaponDefinitions)
            {
                string filename = $"Weapon_{def.SubtypeId}";
                if (FileExistsInWorldStorage(filename, weaponType))
                {
                    try
                    {
                        TextReader       r = MyAPIGateway.Utilities.ReadFileInWorldStorage(filename, weaponType);
                        WeaponDefinition w = MyAPIGateway.Utilities.SerializeFromXML <WeaponDefinition>(r.ReadToEnd());
                        r.Close();

                        Tools.Info($"{((w.Enabled) ? "(ENABLED)" : "(DISABLED)")} Loading user weapon definition {w.SubtypeId}");

                        if (w.Enabled)
                        {
                            Static.WeaponDefinitions.Add(w);
                        }
                    }
                    catch
                    {
                        Tools.Error($"Failed to load file {def.SubtypeId}");
                    }
                }
            }
        }
Exemple #2
0
        public Projectile(Vector3D origin, Vector3 direction, Vector3D startVelocity, AmmoDefinition ammo, long shooterId)
        {
            Ammo      = ammo;
            ShooterId = shooterId;

            Origin    = origin;
            Position  = origin;
            Direction = direction;

            float speed = ammo.DesiredSpeed + ((ammo.SpeedVariance > 0) ? MyRandom.Instance.GetRandomFloat(-ammo.SpeedVariance, ammo.SpeedVariance) : 0);

            Velocity = startVelocity + (Direction * speed);
        }
Exemple #3
0
        private void UpdateAI()
        {
            if (!IsValidTarget(Target))
            {
                IsAIShooting = false;
                Target       = TargetAcquisition();
            }

            if (Target != null)
            {
                MatrixD        muzzleMatrix = gun.GunBase.GetMuzzleWorldMatrix();
                string         ammoId       = gun.GunBase.CurrentAmmoDefinition.Id.SubtypeId.String;
                AmmoDefinition ammo         = Settings.AmmoDefinitionLookup[ammoId];

                Vector3D linearVelocity;
                if (Target is IMyCubeBlock)
                {
                    linearVelocity = (Target as MyCubeBlock).CubeGrid.Physics.LinearVelocity;
                }
                else
                {
                    linearVelocity = Target.Physics.LinearVelocity;
                }

                Vector3D targetPosition;
                if (Target is IMyCharacter)
                {
                    targetPosition = Target.PositionComp.WorldVolume.Center + (Target.WorldMatrix.Up * 0.5f);
                }
                else
                {
                    targetPosition = Target.PositionComp.WorldAABB.Center;
                }

                Vector3D leadPosition = CalculateProjectileInterceptPosition(ammo.DesiredSpeed, Block.CubeGrid.Physics.LinearVelocity, muzzleMatrix.Translation, linearVelocity, targetPosition);

                if (IsTargetVisible(Target, leadPosition))
                {
                    Tools.AddGPS(CubeBlock.EntityId + 2, leadPosition);
                    float remainingAngle = LookAt(leadPosition);
                    // does not shoot if the angle (radians) is not close to on target
                    IsAIShooting = Math.Abs(remainingAngle) < 0.02;
                }
                else
                {
                    Target = null;
                }

                //MyAPIGateway.Utilities.ShowNotification($"{Target.GetType().Name} {(CubeBlock.WorldMatrix.Translation - Target.WorldMatrix.Translation).Length().ToString("n0")} - {remainingAngle.ToString("n5")} - {linearVelocity.ToString("n2")}", 1);
            }
        }
Exemple #4
0
        public void Copy(AmmoDefinition a)
        {
            SubtypeId     = a.SubtypeId;
            DesiredSpeed  = a.DesiredSpeed;
            SpeedVariance = a.SpeedVariance;
            MaxTrajectory = a.MaxTrajectory;
            BackkickForce = a.BackkickForce;
            //PhysicalMaterial = a.PhysicalMaterial;

            ProjectileHitImpulse       = a.ProjectileHitImpulse;
            ProjectileTrailScale       = a.ProjectileTrailScale;
            ProjectileTrailColor       = a.ProjectileTrailColor;
            ProjectileTrailMaterial    = a.ProjectileTrailMaterial;
            ProjectileTrailProbability = a.ProjectileTrailProbability;
            ProjectileOnHitEffectName  = a.ProjectileOnHitEffectName;
            ProjectileMassDamage       = a.ProjectileMassDamage;
            ProjectileHealthDamage     = a.ProjectileHealthDamage;
            ProjectileHeadShotDamage   = a.ProjectileHeadShotDamage;
            ProjectileCount            = a.ProjectileCount;

            Ricochet = a.Ricochet;
        }
Exemple #5
0
        /// <summary>
        /// This converts keens definitions into mostly identical copies that are used within the system.
        /// </summary>
        private static void LoadKeenDefinitions()
        {
            KeenAmmoDefinitions.Clear();
            KeenWeaponDefinitions.Clear();
            Type ammoType   = typeof(AmmoDefinition);
            Type weaponType = typeof(WeaponDefinition);

            foreach (MyDefinitionBase def in MyDefinitionManager.Static.GetAllDefinitions())
            {
                try
                {
                    if (def is MyAmmoMagazineDefinition)
                    {
                        MyAmmoDefinition ammo = MyDefinitionManager.Static.GetAmmoDefinition((def as MyAmmoMagazineDefinition).AmmoDefinitionId);

                        if (ammo.IsExplosive)
                        {
                            Tools.Info($"Skipping keen ammo definition: {ammo.Id}");
                            continue;
                        }
                        else
                        {
                            Tools.Info($"Loading keen ammo definition: {ammo.Id}");
                        }

                        AmmoDefinition a = AmmoDefinition.CreateFromKeenDefinition(ammo as MyProjectileAmmoDefinition);
                        KeenAmmoDefinitions.Add(a);

                        string filename = $"Ammo_{a.SubtypeId}";

                        if (Static.WriteDefaultDefinitionsToFile && !FileExistsInWorldStorage(filename, ammoType))
                        {
                            try
                            {
                                AmmoDefinition ca = a.Clone();
                                ca.Enabled = false;

                                TextWriter writer = MyAPIGateway.Utilities.WriteFileInWorldStorage(filename, ammoType);
                                writer.Write(MyAPIGateway.Utilities.SerializeToXML(ca));
                                writer.Close();
                            }
                            catch
                            {
                                Tools.Error($"Unable to write to file {a.SubtypeId}");
                            }
                        }
                    }
                    else if (def is MyWeaponBlockDefinition)
                    {
                        MyWeaponBlockDefinition block     = def as MyWeaponBlockDefinition;
                        MyWeaponDefinition      weaponDef = MyDefinitionManager.Static.GetWeaponDefinition(block.WeaponDefinitionId);

                        if (weaponDef.HasMissileAmmoDefined)
                        {
                            Tools.Info($"Skipping keen weapon definition: {block.WeaponDefinitionId}");
                            continue;
                        }
                        else
                        {
                            Tools.Info($"Loading keen weapon definition: {block.WeaponDefinitionId}");
                        }

                        // stop vanilla projectile from firing
                        // Thanks for the help Digi
                        for (int i = 0; i < weaponDef.WeaponAmmoDatas.Length; i++)
                        {
                            var ammoData = weaponDef.WeaponAmmoDatas[i];

                            if (ammoData == null)
                            {
                                continue;
                            }

                            ammoData.ShootIntervalInMiliseconds = int.MaxValue;
                        }

                        WeaponDefinition w = WeaponDefinition.CreateFromKeenDefinition(block, weaponDef);
                        KeenWeaponDefinitions.Add(w);

                        string filename = $"Weapon_{w.SubtypeId}";

                        if (Static.WriteDefaultDefinitionsToFile && !FileExistsInWorldStorage(filename, weaponType))
                        {
                            try
                            {
                                WeaponDefinition cw = w.Clone();
                                cw.Enabled = false;

                                TextWriter writer = MyAPIGateway.Utilities.WriteFileInWorldStorage(filename, weaponType);
                                writer.Write(MyAPIGateway.Utilities.SerializeToXML(cw));
                                writer.Close();
                            }
                            catch
                            {
                                Tools.Error($"Unable to write to file {w.SubtypeId}");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Tools.Error($"Failed to load definition: {def.Id}\n{e}");
                }
            }
        }
Exemple #6
0
        public void Spawn(Vector3D origin, Vector3 direction, Vector3D startVelocity, long shooterId, AmmoDefinition ammo)
        {
            lock (projectileCreationLock)
            {
                projectileCount++;
                if (Projectiles.Length < projectileCount)
                {
                    Projectile[] newArray = new Projectile[Projectiles.Length * 2];
                    Array.Copy(Projectiles, newArray, Projectiles.Length);
                    Projectiles = newArray;
                }

                Projectiles[projectileCount - 1] = new Projectile(origin, direction, startVelocity, ammo, shooterId);
            }
        }
Exemple #7
0
        /// <summary>
        /// First call in the update loop
        /// Used to update the firing state of this weapon
        /// </summary>
        public virtual void Update()
        {
            // stop looping if not shooting
            if (!IsShooting)
            {
                //if (!IsAnimated)
                //{
                //	ControlLayer.NeedsUpdate = VRage.ModAPI.MyEntityUpdateEnum.NONE;
                //}

                return;
            }

            byte     notify                = 0x0;
            DateTime currentTime           = DateTime.UtcNow;
            double   timeSinceLastShot     = (currentTime - LastShootTime).TotalMilliseconds;
            double   timeSinceLastAmmoFeed = (currentTime - LastAmmoFeed).TotalMilliseconds;

            if (timeSinceLastAmmoFeed > AmmoFeedInterval)
            {
                if ((Inventory.CurrentVolume.RawValue / Inventory.MaxVolume.RawValue) < InventoryFillFactorMin)
                {
                    InventoryComponent.Fill(CubeBlock, gun.GunBase.CurrentAmmoMagazineId);
                }
            }

            //if (!MyAPIGateway.Utilities.IsDedicated && MyAPIGateway.Session != null)
            //{
            //	MyAPIGateway.Utilities.ShowNotification($"ShootTime: {timeSinceLastShot.ToString("n0")}ms - {State.Value} - {IsShooting} - {IsReloading} - {(timeSinceLastShot * (AmmoData.RateOfFire * Tools.MinutesToMilliseconds)).ToString("n2")} {CurrentShotInBurst}/{AmmoData.ShotsInBurst}", 1);
            //}

            // Stops if weapons are reloading
            if (IsReloading)
            {
                if (timeSinceLastShot < ReloadTime)
                {
                    return;
                }

                Reloading.Value = false;
                //State.Value &= ~WeaponState.Reloading;
            }

            // Stops if weapons are not ready to fire this frame
            if (timeSinceLastShot * (AmmoData.RateOfFire * Tools.MinutesToMilliseconds) < 1f)
            {
                return;
            }


            // Stops if weapons are not working/functional
            if (!Block.IsWorking)
            {
                if (!Block.IsFunctional)
                {
                    notify |= 0x1;
                }
                else
                {
                    notify |= 0x2;
                }
            }
            else
            {
                bool enoughAmmo = gun.GunBase.HasEnoughAmmunition();
                if (!enoughAmmo)
                {
                    StartNoAmmoSound();
                    notify |= 0x4;
                }
                else if (MySessionComponentSafeZones.IsActionAllowed(Block.GetPosition(), Tools.CastProhibit(MySessionComponentSafeZones.AllowedActions, 2)))
                {
                    // Fixed guns do not update unless the mouse is pressed.
                    // This updates the position when terminal fire is active.
                    if (IsFixedGun)
                    {
                        MyEntitySubpart subpart;
                        if (CubeBlock.Subparts.TryGetValue("Barrel", out subpart))
                        {
                            gun.GunBase.WorldMatrix = subpart.PositionComp.WorldMatrixRef;
                        }
                    }

                    // NOTE: RateOfFire is limited to 3600 rounds per seconds using this method

                    MatrixD        muzzleMatrix = gun.GunBase.GetMuzzleWorldMatrix();
                    Vector3        direction    = muzzleMatrix.Forward;
                    Vector3D       origin       = muzzleMatrix.Translation;
                    string         ammoId       = gun.GunBase.CurrentAmmoDefinition.Id.SubtypeId.String;
                    AmmoDefinition ammo         = Settings.AmmoDefinitionLookup[ammoId];

                    // calculate deviation
                    sbyte   index          = DeviationIndex.Value;
                    MatrixD positionMatrix = Matrix.CreateWorld(origin, Tools.ApplyDeviation(direction, DeviateShotAngle, ref index), muzzleMatrix.Up);
                    DeviationIndex.SetValue(index, SyncType.None);

                    // spawn projectile
                    Core.Static.Spawn(positionMatrix.Translation, positionMatrix.Forward, Block.CubeGrid.Physics.LinearVelocity, Block.EntityId, ammo);
                    //Projectile bullet = new Projectile(CubeBlock.EntityId, positionMatrix.Translation, positionMatrix.Forward, Block.CubeGrid.Physics.LinearVelocity, ammoId);
                    //Core.SpawnProjectile(bullet);
                    gun.GunBase.ConsumeAmmo();

                    //apply recoil
                    if (ammo.BackkickForce > 0)
                    {
                        //CubeBlock.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, -direction * ammo.BackkickForce, CubeBlock.WorldMatrix.Translation, Vector3.Zero);

                        //Core.PhysicsRequests.Enqueue(new PhysicsDefinition {
                        //	Target = CubeBlock,
                        //	Force = -direction * ammo.BackkickForce,
                        //	Position = CubeBlock.WorldMatrix.Translation
                        //});
                    }

                    // create sound
                    StartShootSound();
                    //MakeSecondaryShotSound();

                    // create muzzle flash
                    if (!MyAPIGateway.Utilities.IsDedicated && Settings.Static.DrawMuzzleFlash)
                    {
                        MatrixD matrix = MatrixD.CreateFromDir(direction);
                        matrix.Translation = origin;

                        bool foundParticle = MyParticlesManager.TryCreateParticleEffect(MuzzleFlashSpriteName, ref matrix, ref origin, uint.MaxValue, out muzzleFlash);
                        if (foundParticle)
                        {
                            MuzzleFlashActive      = true;
                            MuzzleFlashCurrentTime = 0;
                            muzzleFlash.Play();
                        }
                    }

                    CurrentShotInBurst++;
                    if (AmmoData.ShotsInBurst == 0)
                    {
                        CurrentShotInBurst = 0;
                    }
                    else if (CurrentShotInBurst == AmmoData.ShotsInBurst)
                    {
                        notify            |= 0x8;
                        CurrentShotInBurst = 0;
                        Reloading.Value    = true;
                        //State.Value |= WeaponState.Reloading;
                        DeviationIndex.Push();
                    }

                    if (IsTerminalShootOnce)
                    {
                        State.SetValue(State.Value & ~WeaponState.TerminalShootOnce);
                    }

                    LastShootTime = currentTime;
                }
            }

            if (Notify != notify)
            {
                Core.NotifyNextFrame(Block.CubeGrid.EntityId);
                Notify = notify;
            }
        }