private void SeedButton_Click(object sender, RoutedEventArgs e)
 {
     GameSeed = RNG.GetUInt32();
     RNG.SeedMe((int)GameSeed);
     SeedTextBox.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
     ModSeedTextBox.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
 }
        static void PrintCSV()
        {
            using (StreamWriter sw = File.CreateText("C:\\Program Files (x86)\\Steam\\steamapps\\common\\theendisnigh\\data\\map.csv"))
            {
                for (int i = 0; i < MAP_HEIGHT; i++)
                {
                    for (int j = 0; j < MAP_WIDTH; j++)
                    {
                        if (Map[i, j] != null)
                        {
                            string name = RNG.GetUInt32().ToString();

                            if (Map[i, j].Name == "start")
                            {
                                name = "start";
                            }

                            var file = LevelManip.Load($"tools/map testing/maptest/{Map[i, j].Name}.lvl");
                            LevelManip.Save(file, $"C:\\Program Files (x86)\\Steam\\steamapps\\common\\theendisnigh\\tilemaps\\{name}.lvl");

                            sw.Write($"{name}.lvl,");
                        }
                        else
                        {
                            sw.Write("a.lvl,");
                        }
                    }
                    sw.Write('\n');
                }
            }
        }
Example #3
0
        public static string PlayerPhysics()
        {
            double gravity                   = 40;
            double leniency                  = .1;
            double max_fallspeed             = -60;
            double maxspeed                  = 8;
            double runspeed                  = 11.5;
            double ground_friction           = .7;
            double stop_friction             = .1;
            double air_friction              = .8;
            double fastfall_gravity          = 65;
            double fastfall_jerkdown         = -5;
            double fastfall_maxspeed         = -90;
            double float_time                = 1;
            double jumpheight                = 3.2;
            double release_jumpheight        = .3;
            double longjump_slidethreshold   = 5;
            double longjump_speed            = 16;
            double longjump_height           = 1.9;
            double longjump_airfriction      = .7;
            double ledgejump_height          = 3;
            double enemy_bounceheight_nojump = .7;
            double enemy_bounceheight_jump   = 4.2;
            double mush_bounceheight_nojump  = 2.7;
            double mush_bounceheight_jump    = 8.2;
            double enemy_prebounce_time      = 999999;
            double enemy_postbounce_time     = .05;
            double swimspeed                 = 0;
            double water_exitheight          = 0;

            string extras = "";

            // bounds
            int lower         = 25;
            int upper         = 251;
            int maxBonusJumps = 3;

            // scalar values
            //double gravityScale = (double)RNG.rand.Next(25, 401) / 100;
            //double speedScale = (double)RNG.rand.Next(30, 201) / 100;

            gravity       = RNG.random.Next(10, 121);
            max_fallspeed = -RNG.random.Next(50, 1000) / 10;

            maxspeed = RNG.random.Next(50, 201) / 10;
            runspeed = RNG.random.Next(50, 201) / 10;


            //double speedFriction;
            //if (speedScale > 1)
            //{
            //    speedFriction = speedScale / 100;
            //}

            //ground_friction *= Math.Min(0.9999, (double)RNG.rand.Next(lower, upper) / 100);
            //stop_friction *= Math.Min(0.9999, (double)RNG.rand.Next(lower, upper) / 100);
            //air_friction *= Math.Min(0.9999, (double)RNG.rand.Next(lower, upper) / 100);

            ground_friction = (double)RNG.random.Next(7000, 9000) / 10000;
            stop_friction   = (double)RNG.random.Next(7000, 8500) / 10000;
            air_friction    = (double)RNG.random.Next(7000, 10000) / 10000;

            fastfall_gravity  = RNG.random.Next(10, 121);
            fastfall_jerkdown = -RNG.random.Next(1, 121) / 10;
            fastfall_maxspeed = -RNG.random.Next(1, 121);

            if (RNG.random.Next(0, 10) == 0)
            {
                fastfall_gravity  *= -1;
                fastfall_jerkdown *= -1;
                fastfall_maxspeed *= -1;
            }

            //float_time *= (double)RNG.rand.Next(lower, upper) / 100;
            jumpheight         = (double)RNG.random.Next(320, 751) / 100;
            release_jumpheight = (double)RNG.random.Next(10, 70) / 100;

            //longjump_slidethreshold *= (double)RNG.rand.Next(lower, upper) / 100;
            longjump_speed       = RNG.random.Next(100, 300) / 10;
            longjump_height      = (double)RNG.random.Next(50, 601) / 100;
            longjump_airfriction = (double)RNG.random.Next(5000, 10000) / 10000;
            ledgejump_height     = (double)RNG.random.Next(20, 60) / 10;

            //longjump_slidethreshold = ;

            enemy_bounceheight_nojump = (double)RNG.random.Next(2, 31) / 10;
            enemy_bounceheight_jump   = (double)RNG.random.Next(20, 81) / 10;
            mush_bounceheight_nojump  = (double)RNG.random.Next(10, 51) / 10;
            mush_bounceheight_jump    = (double)RNG.random.Next(40, 101) / 10;
            //enemy_prebounce_time *= (double)RNG.rand.Next(lower, upper) / 100;
            //enemy_postbounce_time *= (double)RNG.rand.Next(lower, upper) / 100;
            //swimspeed *= (double)RNG.rand.Next(lower, upper) / 100;
            //water_exitheight *= (double)RNG.rand.Next(lower, upper) / 100;

            if (jumpheight < 3.5)
            {
                maxBonusJumps = 1;
            }
            if (RNG.CoinFlip()) // bonus jumps
            {
                double numBonusJumps = RNG.random.Next(1, maxBonusJumps + 1);
                jumpheight /= numBonusJumps + 1;

                extras += "bonus_jumps " + numBonusJumps + "\n";
                extras += "bonus_jump_heights [";
                for (int i = 0; i < numBonusJumps + 1; i++)
                {
                    if (i > 0)
                    {
                        extras += ", ";
                    }
                    extras += jumpheight;
                }
                extras += "]\n";
                if (numBonusJumps == 0)
                {
                    leniency = RNG.random.NextDouble();
                }
            }

            string filename = "data/player_physics/" + RNG.GetUInt32().ToString() + ".txt";

            using (StreamWriter sw = File.CreateText(Randomizer.saveDir + filename))
            {
                sw.WriteLine(nameof(gravity) + " " + gravity);
                sw.WriteLine(nameof(leniency) + " " + leniency);
                sw.WriteLine(nameof(max_fallspeed) + " " + max_fallspeed);
                sw.WriteLine(nameof(maxspeed) + " " + maxspeed);
                sw.WriteLine(nameof(runspeed) + " " + runspeed);
                sw.WriteLine(nameof(ground_friction) + " " + ground_friction);
                sw.WriteLine(nameof(stop_friction) + " " + stop_friction);
                sw.WriteLine(nameof(air_friction) + " " + air_friction);
                sw.WriteLine(nameof(fastfall_gravity) + " " + fastfall_gravity);
                sw.WriteLine(nameof(fastfall_jerkdown) + " " + fastfall_jerkdown);
                sw.WriteLine(nameof(fastfall_maxspeed) + " " + fastfall_maxspeed);
                sw.WriteLine(nameof(float_time) + " " + float_time);
                sw.WriteLine(nameof(jumpheight) + " " + jumpheight);
                sw.WriteLine(nameof(release_jumpheight) + " " + release_jumpheight);
                sw.WriteLine(nameof(longjump_slidethreshold) + " " + longjump_slidethreshold);
                sw.WriteLine(nameof(longjump_speed) + " " + longjump_speed);
                sw.WriteLine(nameof(longjump_height) + " " + longjump_height);
                sw.WriteLine(nameof(longjump_airfriction) + " " + longjump_airfriction);
                sw.WriteLine(nameof(ledgejump_height) + " " + ledgejump_height);
                sw.WriteLine(nameof(enemy_bounceheight_nojump) + " " + enemy_bounceheight_nojump);
                sw.WriteLine(nameof(enemy_bounceheight_jump) + " " + enemy_bounceheight_jump);
                sw.WriteLine(nameof(mush_bounceheight_nojump) + " " + mush_bounceheight_nojump);
                sw.WriteLine(nameof(mush_bounceheight_jump) + " " + mush_bounceheight_jump);
                sw.WriteLine(nameof(enemy_prebounce_time) + " " + enemy_prebounce_time);
                sw.WriteLine(nameof(enemy_postbounce_time) + " " + enemy_postbounce_time);
                sw.WriteLine(nameof(swimspeed) + " " + swimspeed);
                sw.WriteLine(nameof(water_exitheight) + " " + water_exitheight);
                sw.WriteLine(extras);
            }
            return(filename);
        }
Example #4
0
        public static string PlatformPhysics()
        {
            // DEFAULT PLATFORM PHYSICS
            double MovingPlatformSpeedLow         = 2;
            double MovingPlatformSpeedMed         = 4;
            double MovingPlatformSpeedHigh        = 6;
            double SmoothMovingPlatformSpeedLow   = 1;
            double SmoothMovingPlatformSpeedMed   = 3;
            double SmoothMovingPlatformSpeedHigh  = 5;
            double SmoothMovingPlatformSpeedXSlow = .2;
            double FallingPlatformGravitytLow     = .5;
            double FallingPlatformGravitytMed     = 1;
            double FallingPlatformGravitytHigh    = 2;
            double CrumblingPlatformGravitytLow   = .5;
            double CrumblingPlatformGravitytMed   = 1;
            double CrumblingPlatformGravitytHigh  = 2;
            double SmasherSpeedLow           = 20;
            double SmasherDelayLow           = 2;
            double SmasherSpeedMed           = 25;
            double SmasherDelayMed           = 1;
            double SmasherSpeedHigh          = 30;
            double SmasherDelayHigh          = .5;
            double WeightedPlatformSpeedLow  = 1;
            double WeightedPlatformSpeedMed  = 2;
            double WeightedPlatformSpeedHigh = 4;

            // Lower and Upper Bounds (in %)
            double minimum = 0;
            int    lower   = 30;
            int    upper   = 201;

            // Alter Values
            MovingPlatformSpeedLow         *= (double)RNG.random.Next(lower, upper) / 100;
            MovingPlatformSpeedMed         *= (double)RNG.random.Next(lower, upper) / 100;
            MovingPlatformSpeedHigh        *= (double)RNG.random.Next(lower, upper) / 100;
            SmoothMovingPlatformSpeedLow   *= (double)RNG.random.Next(lower, upper) / 100;
            SmoothMovingPlatformSpeedMed   *= (double)RNG.random.Next(lower, upper) / 100;
            SmoothMovingPlatformSpeedHigh  *= (double)RNG.random.Next(lower, upper) / 100;
            SmoothMovingPlatformSpeedXSlow *= (double)RNG.random.Next(lower, upper) / 100;
            FallingPlatformGravitytLow     *= (double)RNG.random.Next(lower, upper) / 100;
            FallingPlatformGravitytMed     *= (double)RNG.random.Next(lower, upper) / 100;
            FallingPlatformGravitytHigh    *= (double)RNG.random.Next(lower, upper) / 100;
            CrumblingPlatformGravitytLow   *= (double)RNG.random.Next(lower, upper) / 100;
            CrumblingPlatformGravitytMed   *= (double)RNG.random.Next(lower, upper) / 100;
            CrumblingPlatformGravitytHigh  *= (double)RNG.random.Next(lower, upper) / 100;
            SmasherSpeedLow            = (double)RNG.random.Next(5, 40);
            SmasherDelayLow           *= (double)RNG.random.Next(lower, upper) / 100;
            SmasherSpeedMed            = (double)RNG.random.Next(7, 48);
            SmasherDelayMed           *= (double)RNG.random.Next(lower, upper) / 100;
            SmasherSpeedHigh           = (double)RNG.random.Next(10, 56);
            SmasherDelayHigh          *= (double)RNG.random.Next(lower, upper) / 100;
            WeightedPlatformSpeedLow  *= (double)RNG.random.Next(lower, upper) / 100;
            WeightedPlatformSpeedMed  *= (double)RNG.random.Next(lower, upper) / 100;
            WeightedPlatformSpeedHigh *= (double)RNG.random.Next(lower, upper) / 100;

            // Write platformphysics.txt
            string filename = "data/platform_physics/" + RNG.GetUInt32().ToString() + ".txt";

            using (StreamWriter sw = File.CreateText(Randomizer.saveDir + filename))
            {
                sw.WriteLine(nameof(MovingPlatformSpeedLow) + " " + MovingPlatformSpeedLow);
                sw.WriteLine(nameof(MovingPlatformSpeedMed) + " " + MovingPlatformSpeedMed);
                sw.WriteLine(nameof(MovingPlatformSpeedHigh) + " " + MovingPlatformSpeedHigh);
                sw.WriteLine(nameof(SmoothMovingPlatformSpeedLow) + " " + SmoothMovingPlatformSpeedLow);
                sw.WriteLine(nameof(SmoothMovingPlatformSpeedMed) + " " + SmoothMovingPlatformSpeedMed);
                sw.WriteLine(nameof(SmoothMovingPlatformSpeedHigh) + " " + SmoothMovingPlatformSpeedHigh);
                sw.WriteLine(nameof(SmoothMovingPlatformSpeedXSlow) + " " + SmoothMovingPlatformSpeedXSlow);
                sw.WriteLine(nameof(FallingPlatformGravitytLow) + " " + FallingPlatformGravitytLow);
                sw.WriteLine(nameof(FallingPlatformGravitytMed) + " " + FallingPlatformGravitytMed);
                sw.WriteLine(nameof(FallingPlatformGravitytHigh) + " " + FallingPlatformGravitytHigh);
                sw.WriteLine(nameof(CrumblingPlatformGravitytLow) + " " + CrumblingPlatformGravitytLow);
                sw.WriteLine(nameof(CrumblingPlatformGravitytMed) + " " + CrumblingPlatformGravitytMed);
                sw.WriteLine(nameof(CrumblingPlatformGravitytHigh) + " " + CrumblingPlatformGravitytHigh);
                sw.WriteLine(nameof(SmasherSpeedLow) + " " + SmasherSpeedLow);
                sw.WriteLine(nameof(SmasherDelayLow) + " " + SmasherDelayLow);
                sw.WriteLine(nameof(SmasherSpeedMed) + " " + SmasherSpeedMed);
                sw.WriteLine(nameof(SmasherDelayMed) + " " + SmasherDelayMed);
                sw.WriteLine(nameof(SmasherSpeedHigh) + " " + SmasherSpeedHigh);
                sw.WriteLine(nameof(SmasherDelayHigh) + " " + SmasherDelayHigh);
                sw.WriteLine(nameof(WeightedPlatformSpeedLow) + " " + WeightedPlatformSpeedLow);
                sw.WriteLine(nameof(WeightedPlatformSpeedMed) + " " + WeightedPlatformSpeedMed);
                sw.WriteLine(nameof(WeightedPlatformSpeedHigh) + " " + WeightedPlatformSpeedHigh);
            }

            return(filename);
        }
Example #5
0
        public static string WaterPhysics()
        {
            double gravity                   = 28;
            double leniency                  = .1;
            double max_fallspeed             = -5;
            double maxspeed                  = 5;
            double runspeed                  = 7;
            double ground_friction           = .95;
            double stop_friction             = .90;
            double air_friction              = .95;
            double fastfall_gravity          = 30;
            double fastfall_jerkdown         = -1;
            double fastfall_maxspeed         = -15;
            double float_time                = 1;
            double jumpheight                = 3.2;
            double release_jumpheight        = .3;
            double longjump_slidethreshold   = 5;
            double longjump_speed            = 10;
            double longjump_height           = 1.9;
            double longjump_airfriction      = .99;
            double ledgejump_height          = 3;
            double enemy_bounceheight_nojump = .7;
            double enemy_bounceheight_jump   = 4.2;
            double mush_bounceheight_nojump  = 2.7;
            double mush_bounceheight_jump    = 8.2;
            double enemy_prebounce_time      = 999999;
            double enemy_postbounce_time     = .05;
            double swimspeed                 = 7.5;
            double water_exitheight          = 2.6;

            int lower = 50;
            int upper = 201;

            gravity       *= (double)RNG.random.Next(lower, upper) / 100;
            leniency      *= (double)RNG.random.Next(lower, upper) / 100;
            max_fallspeed *= (double)RNG.random.Next(75, upper) / 100;
            maxspeed      *= (double)RNG.random.Next(lower, upper) / 100;
            runspeed      *= (double)RNG.random.Next(lower, upper) / 100;

            ground_friction = (double)RNG.random.Next(7000, 9000) / 10000;
            stop_friction   = (double)RNG.random.Next(7000, 8500) / 10000;
            air_friction    = (double)RNG.random.Next(7000, 10000) / 10000;

            fastfall_gravity        *= (double)RNG.random.Next(lower, upper) / 100;
            fastfall_jerkdown       *= (double)RNG.random.Next(lower, upper) / 100;
            fastfall_maxspeed       *= (double)RNG.random.Next(lower, upper) / 100;
            float_time              *= (double)RNG.random.Next(lower, upper) / 100;
            jumpheight              *= (double)RNG.random.Next(lower, upper) / 100;
            release_jumpheight      *= (double)RNG.random.Next(lower, upper) / 100;
            longjump_slidethreshold *= (double)RNG.random.Next(lower, upper) / 100;
            longjump_speed          *= (double)RNG.random.Next(lower, upper) / 100;
            longjump_height         *= (double)RNG.random.Next(lower, upper) / 100;
            longjump_airfriction    *= (double)RNG.random.Next(lower, upper) / 100;
            ledgejump_height        *= (double)RNG.random.Next(lower, upper) / 100;
            //enemy_bounceheight_nojump *= (double)RNG.rand.Next(lower, upper) / 100;
            //enemy_bounceheight_jump *= (double)RNG.rand.Next(lower, upper) / 100;
            //mush_bounceheight_nojump *= (double)RNG.rand.Next(lower, upper) / 100;
            //mush_bounceheight_jump *= (double)RNG.rand.Next(lower, upper) / 100;
            //enemy_prebounce_time *= (double)RNG.rand.Next(lower, upper) / 100;
            //enemy_postbounce_time *= (double)RNG.rand.Next(lower, upper) / 100;
            swimspeed        *= (double)RNG.random.Next(lower, upper) / 100;
            water_exitheight *= (double)RNG.random.Next(lower, upper) / 100;

            string filename = "data/water_physics/" + RNG.GetUInt32().ToString() + ".txt";

            using (StreamWriter sw = File.CreateText(Randomizer.saveDir + filename))
            {
                sw.WriteLine(nameof(gravity) + " " + gravity);
                sw.WriteLine(nameof(leniency) + " " + leniency);
                sw.WriteLine(nameof(max_fallspeed) + " " + max_fallspeed);
                sw.WriteLine(nameof(maxspeed) + " " + maxspeed);
                sw.WriteLine(nameof(runspeed) + " " + runspeed);
                sw.WriteLine(nameof(ground_friction) + " " + ground_friction);
                sw.WriteLine(nameof(stop_friction) + " " + stop_friction);
                sw.WriteLine(nameof(air_friction) + " " + air_friction);
                sw.WriteLine(nameof(fastfall_gravity) + " " + fastfall_gravity);
                sw.WriteLine(nameof(fastfall_jerkdown) + " " + fastfall_jerkdown);
                sw.WriteLine(nameof(fastfall_maxspeed) + " " + fastfall_maxspeed);
                sw.WriteLine(nameof(float_time) + " " + float_time);
                sw.WriteLine(nameof(jumpheight) + " " + jumpheight);
                sw.WriteLine(nameof(release_jumpheight) + " " + release_jumpheight);
                sw.WriteLine(nameof(longjump_slidethreshold) + " " + longjump_slidethreshold);
                sw.WriteLine(nameof(longjump_speed) + " " + longjump_speed);
                sw.WriteLine(nameof(longjump_height) + " " + longjump_height);
                sw.WriteLine(nameof(longjump_airfriction) + " " + longjump_airfriction);
                sw.WriteLine(nameof(ledgejump_height) + " " + ledgejump_height);
                sw.WriteLine(nameof(enemy_bounceheight_nojump) + " " + enemy_bounceheight_nojump);
                sw.WriteLine(nameof(enemy_bounceheight_jump) + " " + enemy_bounceheight_jump);
                sw.WriteLine(nameof(mush_bounceheight_nojump) + " " + mush_bounceheight_nojump);
                sw.WriteLine(nameof(mush_bounceheight_jump) + " " + mush_bounceheight_jump);
                sw.WriteLine(nameof(enemy_prebounce_time) + " " + enemy_prebounce_time);
                sw.WriteLine(nameof(enemy_postbounce_time) + " " + enemy_postbounce_time);
                sw.WriteLine(nameof(swimspeed) + " " + swimspeed);
                sw.WriteLine(nameof(water_exitheight) + " " + water_exitheight);
            }
            return(filename);
        }
        public static string MistParticle(SettingsFile settings)
        {
            string particle_name = "MistParticle" + RNG.GetUInt32().ToString();

            int layer      = 4;
            int base_speed = 3;

            // can be anything
            double alpha_start = 1;
            double alpha_end   = 0;
            string movieclip;
            int    max_particles     = settings.MaxParticles;
            int    emit_spread       = 0;
            string rotation_speed    = "0";
            string initial_rotation  = "0";
            double particle_lifetime = RNG.random.Next(1, 5);
            string size_start;
            int    size_end = RNG.random.Next(50, 101);

            string emit_direction = $"[{RNG.random.Next(-10, 11) / 10},{RNG.random.Next(-10, 11) / 10}]";

            if (emit_direction == "[0,0]")
            {
                emit_direction = "[0,-1]";
            }
            //string emit_box = "";
            //string emit_offset = "";

            string force = "0";
            int    emit_rate;
            int    emit_amount;
            double initial_speed = RNG.random.Next(0, 20);
            double friction      = 1;

            // open particles file
            var    gon      = GonObject.Load($"data/text/particles_templates.gon"); // open particle file
            string template = gon["templates"]["MistParticle"].String();            // load particle template

            // select particle from pool
            var particles = gon["particles"];
            var chosen    = particles[RNG.random.Next(0, particles.Size())];

            // get particle variables from file
            movieclip = chosen["name"].String();
            string face_moving_direction = chosen["face_moving_direction"].String();

            alpha_start = chosen["alpha"].Number();
            double size = chosen["size"].Number() * .03;

            size_start = $"[{size * .75},{size * 1.25}]";
            layer      = chosen["layer"].Int();
            double density     = chosen["density"].Number();
            double speed_scale = chosen["speed_scale"].Number();

            // calculate emitter properties
            int emit_density = (int)(64 * density);

            emit_rate   = RNG.random.Next(1, emit_density);
            emit_amount = emit_density / emit_rate;
            if (RNG.CoinFlip())
            {
                emit_spread = RNG.random.Next(0, 46);
            }
            if (RNG.random.Next(0, 10) == 0)
            {
                emit_spread = 360;
            }

            if (!Convert.ToBoolean(face_moving_direction))
            {
                int temp = RNG.random.Next(0, 251);
                rotation_speed   = $"[{temp},{temp * 1.5}]";
                initial_rotation = "[0, 359]";
            }

            template = template.Replace("PARTICLE_NAME", particle_name);
            template = template.Replace("LAYER", layer.ToString());
            template = template.Replace("MOVIECLIP", movieclip);
            template = template.Replace("MAX_PARTICLES", max_particles.ToString());
            template = template.Replace("EMIT_RATE", emit_rate.ToString());
            template = template.Replace("EMIT_AMOUNT", emit_amount.ToString());
            template = template.Replace("EMIT_DIRECTION", emit_direction);
            template = template.Replace("EMIT_SPREAD", emit_spread.ToString());
            //template = template.Replace("EMIT_BOX", emit_box);
            //template = template.Replace("EMIT_OFFSET", emit_offset);
            template = template.Replace("PARTICLE_LIFETIME", particle_lifetime.ToString());
            template = template.Replace("INITIAL_SPEED", $"[{initial_speed},{initial_speed * 2}]");
            template = template.Replace("INITIAL_ROTATION", initial_rotation.ToString());
            template = template.Replace("ROTATION_SPEED", rotation_speed.ToString());
            template = template.Replace("FORCE", force);
            template = template.Replace("FRICTION", friction.ToString());
            template = template.Replace("ALPHA_START", alpha_start.ToString());
            template = template.Replace("ALPHA_END", alpha_end.ToString());
            template = template.Replace("SIZE_START", size_start);
            template = template.Replace("SIZE_END", size_end.ToString());
            template = template.Replace("FACE_MOVING_DIRECTION", face_moving_direction);
            template = template.Replace("SPEED_SCALE", speed_scale.ToString());

            using (StreamWriter sw = File.AppendText(Randomizer.saveDir + "data/particles.txt.append"))
            {
                sw.WriteLine(template);
            }
            return(particle_name);
        }
        public static string DirectionParticle(SettingsFile settings)
        {
            string particle_name = "DirectionParticle" + RNG.GetUInt32().ToString();

            int    layer      = 4;
            double base_speed = 3;
            double base_force = 1;
            string notes      = "#";

            // can be anything
            double alpha_start = 1;
            double alpha_end   = 1;
            string movieclip;
            int    max_particles     = settings.MaxParticles;
            int    emit_spread       = 0;
            string rotation_speed    = "0";
            string initial_rotation  = "0";
            double particle_lifetime = 80;
            string size_start;

            // establish direction
            string emit_direction = "";
            string emit_box       = "";
            string emit_offset    = "";

            // dependent on eachother
            int    emit_rate;
            int    emit_amount;
            double initial_speed;
            double friction = 1;
            string force;

            // open particles file
            var    gon      = GonObject.Load($"data/text/particles_templates.gon"); // open particle file
            string template = gon["templates"]["DirectionParticle"].String();       // load particle template

            // select particle from pool
            var particles = gon["particles"];
            var chosen    = particles[RNG.random.Next(0, particles.Size())];

            // get particle variables from file
            movieclip = chosen["name"].String();
            string face_moving_direction = chosen["face_moving_direction"].String();

            alpha_start = chosen["alpha"].Number();
            double size = chosen["size"].Number();

            size_start = $"[{size * .75},{size * 1.25}]";
            layer      = chosen["layer"].Int();
            double density     = chosen["density"].Number();
            double speed_scale = chosen["speed_scale"].Number();

            speed_scale += RNG.random.Next(-2, 3) / 10;

            int speed_scalar = 1, force_scalar = 1;
            // set moving direction
            bool force_neg = false;
            int  direction = RNG.random.Next(0, 4);

            switch (direction)
            {
            case 0:     // up
                emit_direction = $"[{RNG.random.Next(-3, 4) / 10},1]";
                emit_box       = "[54,1]";
                emit_offset    = "[27,-3]";
                break;

            case 1:     // down
                emit_direction = $"[{RNG.random.Next(-3, 4) / 10},-1]";
                emit_box       = "[54,1]";
                emit_offset    = "[27,35]";
                force_neg      = true;
                break;

            case 2:     // right
                emit_direction = $"[1,{RNG.random.Next(-3, 4) / 10}]";
                emit_box       = "[1,32]";
                emit_offset    = "[-3,16]";
                base_speed    *= 1.2;
                base_force    *= .8;
                break;

            case 3:     // left
                emit_direction = $"[-1,{RNG.random.Next(-3, 4) / 10}]";
                emit_box       = "[1,32]";
                emit_offset    = "[57,16]";
                base_speed    *= 1.2;
                base_force    *= .8;
                force_neg      = true;
                break;
            }

            //int particle_density = 100;

            int emit_density = (int)(RNG.random.Next(5, 16) * density);

            speed_scalar = RNG.random.Next(1, 5);

            if (RNG.CoinFlip())   // decide whether to accelerate, slow down, or no force
            {
                force_scalar = speed_scalar * speed_scalar;
                if (RNG.CoinFlip() && direction < 2)   // gravity
                {
                    //force_scalar = speed_scalar * speed_scalar;
                    force_neg     = !force_neg;
                    emit_density *= Math.Max(speed_scalar / 2, 1);
                    notes        += "gravity, ";
                }
                else    // accelerate
                {
                    //force_scalar = speed_scalar * speed_scalar;
                    emit_density *= speed_scalar;
                    notes        += "accelerate, ";
                }
            }
            else
            {
                force_scalar  = 0;
                emit_density *= speed_scalar;
            }

            notes += $"force scalar: {force_scalar}, speed scalar: {speed_scalar}, ";

            initial_speed = base_speed * speed_scalar;                                              // set initial speed
            double parallel_force      = base_force * force_scalar * -(Convert.ToInt32(force_neg)); // set force
            double perpendicular_force = base_force * force_scalar * RNG.random.Next(-10, 11) / 10;

            //perpendicular_force = 0;

            if (RNG.random.Next(0, 3) == 0)   // decide if particle fades out
            {
                alpha_end         = 0;
                particle_lifetime = (float)RNG.random.Next(2, 4) * (float)base_speed / (float)speed_scalar;
            }

            if (direction > 1)  // if right or left
            {
                force              = $"[{parallel_force},{perpendicular_force}]";
                particle_lifetime *= 2;
            }
            else
            {
                force = $"[{perpendicular_force},{parallel_force}]";
            }

            emit_rate   = RNG.random.Next(1, emit_density);
            emit_amount = emit_density / emit_rate;
            if (RNG.CoinFlip())
            {
                emit_spread = RNG.random.Next(0, 46);
            }

            if (!Convert.ToBoolean(face_moving_direction))
            {
                int temp = RNG.random.Next(0, 251);
                rotation_speed   = $"[{temp},{temp * 1.5}]";
                initial_rotation = "[0, 359]";
            }

            // write all values to template
            template = template.Replace("PARTICLE_NAME", particle_name);
            template = template.Replace("LAYER", layer.ToString());
            template = template.Replace("MOVIECLIP", movieclip);
            template = template.Replace("MAX_PARTICLES", max_particles.ToString());
            template = template.Replace("EMIT_RATE", emit_rate.ToString());
            template = template.Replace("EMIT_AMOUNT", emit_amount.ToString());
            template = template.Replace("EMIT_DIRECTION", emit_direction);
            template = template.Replace("EMIT_SPREAD", emit_spread.ToString());
            template = template.Replace("EMIT_BOX", emit_box);
            template = template.Replace("EMIT_OFFSET", emit_offset);
            template = template.Replace("PARTICLE_LIFETIME", particle_lifetime.ToString());
            template = template.Replace("INITIAL_SPEED", $"[{initial_speed},{initial_speed * 2}]");
            template = template.Replace("INITIAL_ROTATION", initial_rotation.ToString());
            template = template.Replace("ROTATION_SPEED", rotation_speed.ToString());
            template = template.Replace("FORCE", force);
            template = template.Replace("FRICTION", friction.ToString());
            template = template.Replace("ALPHA_START", alpha_start.ToString());
            template = template.Replace("ALPHA_END", alpha_end.ToString());
            template = template.Replace("SIZE_START", size_start);
            //template = template.Replace("SIZE_END", size_end.ToString());
            template  = template.Replace("FACE_MOVING_DIRECTION", face_moving_direction);
            template  = template.Replace("SPEED_SCALE", speed_scale.ToString());
            template += notes;

            using (StreamWriter sw = File.AppendText(Randomizer.saveDir + "data/particles.txt.append"))
            {
                sw.WriteLine(template);
            }
            return(particle_name);
        }