////////////////

        private static void AddAll(Projectile proj)
        {
            foreach (var kv in AltProjectileInfo.ProjInfoTypes)
            {
                AltProjectileInfo.Add(proj, kv.Key, kv.Value);
            }
        }
        ////////////////

        internal static void UpdateAll()
        {
            if (AltProjectileInfo.ProjInfoTypes.Count == 0)
            {
                return;
            }

            var map = AltProjectileInfo.ProjInfos;

            for (int who = 0; who < Main.projectile.Length; who++)
            {
                Projectile proj     = Main.projectile[who];
                bool       is_empty = map[who].Count == 0;

                if (proj == null || !proj.active || proj.type == 0)
                {
                    if (!is_empty)
                    {
                        AltProjectileInfo.Clear(who);
                    }
                    continue;
                }

                if (!is_empty)
                {
                    foreach (AltProjectileInfo info in map[who].Values)
                    {
                        if (info.ProjType != proj.type)
                        {
                            is_empty = true;
                            break;
                        }
                    }
                    if (is_empty)
                    {
                        AltProjectileInfo.Clear(who);
                    }
                }

                if (is_empty)
                {
                    AltProjectileInfo.AddAll(proj);
                }

                // Run updates
                foreach (AltProjectileInfo info in map[who].Values)
                {
                    info.Update();
                }
            }
        }
        ////////////////

        static AltProjectileInfo()
        {
            AltProjectileInfo.DataInitialize();
        }