Ejemplo n.º 1
0
 public IncreaseBiodiversity(AutoEvoConfiguration configuration, PatchMap map, Patch patch, Random random)
 {
     this.map           = map;
     this.patch         = patch;
     this.configuration = configuration;
     this.random        = new Random(random.Next());
 }
Ejemplo n.º 2
0
 public SimulationConfiguration(AutoEvoConfiguration autoEvoConfiguration, PatchMap initialConditions,
                                int steps = 1)
 {
     AutoEvoConfiguration = autoEvoConfiguration;
     OriginalMap          = initialConditions;
     StepsLeft            = Math.Max(1, steps);
 }
Ejemplo n.º 3
0
 public FindBestMigration(AutoEvoConfiguration configuration, PatchMap map, Species species,
                          Random random, int migrationsToTry, bool allowNoMigration) : base(migrationsToTry, allowNoMigration)
 {
     this.configuration = configuration;
     this.map           = map;
     this.species       = species;
     this.random        = new Random(random.Next());
 }
Ejemplo n.º 4
0
        /// <summary>
        ///   Prints to log a summary of the results
        /// </summary>
        public void PrintSummary(PatchMap previousPopulations = null)
        {
            GD.Print("Start of auto-evo results summary (entries: ", results.Count, ")");

            GD.Print(MakeSummary(previousPopulations));

            GD.Print("End of results summary");
        }
Ejemplo n.º 5
0
 public CalculatePopulation(AutoEvoConfiguration configuration, PatchMap map,
                            List <Species> extraSpecies = null, List <Species> excludedSpecies = null,
                            bool collectEnergyInfo      = false)
 {
     this.configuration     = configuration;
     this.map               = map;
     this.extraSpecies      = extraSpecies;
     this.excludedSpecies   = excludedSpecies;
     this.collectEnergyInfo = collectEnergyInfo;
 }
Ejemplo n.º 6
0
 public void SetMap(PatchMap map)
 {
     mapDrawer.Map = map;
 }
Ejemplo n.º 7
0
    public static PatchMap Generate(WorldGenerationSettings settings, Species defaultSpecies)
    {
        // TODO: implement actual generation based on settings
        _ = settings;

        var map = new PatchMap();

        // Predefined patches
        Patch patch0 = new Patch(TranslationServer.Translate("PATCH_PANGONIAN_VENTS"), 0,
                                 GetBiomeTemplate("aavolcanic_vent"));

        patch0.Depth[0] = 2500;
        patch0.Depth[1] = 3000;
        patch0.AddSpecies(defaultSpecies);
        patch0.ScreenCoordinates = new Vector2(100, 400);
        map.AddPatch(patch0);

        Patch patch1 = new Patch(TranslationServer.Translate("PATCH_PANGONIAN_MESOPELAGIC"), 1,
                                 GetBiomeTemplate("mesopelagic"));

        patch1.Depth[0]          = 200;
        patch1.Depth[1]          = 1000;
        patch1.ScreenCoordinates = new Vector2(200, 200);
        map.AddPatch(patch1);

        Patch patch2 = new Patch(TranslationServer.Translate("PATCH_PANGONIAN_EPIPELAGIC"), 2,
                                 GetBiomeTemplate("default"));

        patch2.Depth[0]          = 0;
        patch2.Depth[1]          = 200;
        patch2.ScreenCoordinates = new Vector2(200, 100);
        map.AddPatch(patch2);

        Patch patch3 = new Patch(TranslationServer.Translate("PATCH_PANGONIAN_TIDEPOOL"), 3,
                                 GetBiomeTemplate("tidepool"));

        patch3.Depth[0]          = 0;
        patch3.Depth[1]          = 10;
        patch3.ScreenCoordinates = new Vector2(300, 100);
        map.AddPatch(patch3);

        Patch patch4 = new Patch(TranslationServer.Translate("PATCH_PANGONIAN_BATHYPELAGIC"), 4,
                                 GetBiomeTemplate("bathypelagic"));

        patch4.Depth[0]          = 1000;
        patch4.Depth[1]          = 4000;
        patch4.ScreenCoordinates = new Vector2(200, 300);
        map.AddPatch(patch4);

        Patch patch5 = new Patch(TranslationServer.Translate("PATHCH_PANGONIAN_ABYSSOPELAGIC"), 5,
                                 GetBiomeTemplate("abyssopelagic"));

        patch5.Depth[0]          = 4000;
        patch5.Depth[1]          = 6000;
        patch5.ScreenCoordinates = new Vector2(300, 400);
        map.AddPatch(patch5);

        Patch patch6 = new Patch(TranslationServer.Translate("PATCH_PANGONIAN_COAST"), 6,
                                 GetBiomeTemplate("coastal"));

        patch6.Depth[0]          = 0;
        patch6.Depth[1]          = 200;
        patch6.ScreenCoordinates = new Vector2(100, 100);
        map.AddPatch(patch6);

        Patch patch7 = new Patch(TranslationServer.Translate("PATCH_PANGONIAN_ESTUARY"), 7,
                                 GetBiomeTemplate("estuary"));

        patch7.Depth[0]          = 0;
        patch7.Depth[1]          = 200;
        patch7.ScreenCoordinates = new Vector2(70, 160);
        map.AddPatch(patch7);

        Patch patch8 = new Patch(TranslationServer.Translate("PATCH_CAVE"), 8,
                                 GetBiomeTemplate("underwater_cave"));

        patch8.Depth[0]          = 200;
        patch8.Depth[1]          = 1000;
        patch8.ScreenCoordinates = new Vector2(300, 200);
        map.AddPatch(patch8);

        Patch patch9 = new Patch(TranslationServer.Translate("PATCH_ICE_SHELF"), 9,
                                 GetBiomeTemplate("ice_shelf"));

        patch9.Depth[0]          = 0;
        patch9.Depth[1]          = 200;
        patch9.ScreenCoordinates = new Vector2(200, 30);
        map.AddPatch(patch9);

        Patch patch10 = new Patch(TranslationServer.Translate("PATCH_PANGONIAN_SEAFLOOR"), 10,
                                  GetBiomeTemplate("seafloor"));

        patch10.Depth[0]          = 4000;
        patch10.Depth[1]          = 6000;
        patch10.ScreenCoordinates = new Vector2(200, 400);
        map.AddPatch(patch10);

        // Connections
        patch0.AddNeighbour(patch10);

        patch1.AddNeighbour(patch4);
        patch1.AddNeighbour(patch2);
        patch1.AddNeighbour(patch8);

        patch2.AddNeighbour(patch1);
        patch2.AddNeighbour(patch3);
        patch2.AddNeighbour(patch6);
        patch2.AddNeighbour(patch9);

        patch3.AddNeighbour(patch2);

        patch4.AddNeighbour(patch5);
        patch4.AddNeighbour(patch1);
        patch4.AddNeighbour(patch10);

        patch5.AddNeighbour(patch10);
        patch5.AddNeighbour(patch4);

        patch6.AddNeighbour(patch2);
        patch6.AddNeighbour(patch7);

        patch7.AddNeighbour(patch6);

        patch8.AddNeighbour(patch1);

        patch9.AddNeighbour(patch2);

        patch10.AddNeighbour(patch4);
        patch10.AddNeighbour(patch5);
        patch10.AddNeighbour(patch0);

        map.CurrentPatch = patch0;
        return(map);
    }
Ejemplo n.º 8
0
        /// <summary>
        ///   Makes summary text
        /// </summary>
        /// <param name="previousPopulations">If provided comparisons to previous populations is included</param>
        /// <param name="playerReadable">if true ids are removed from the output</param>
        /// <param name="effects">if not null these effects are applied to the population numbers</param>
        /// <returns>The generated summary text</returns>
        public LocalizedStringBuilder MakeSummary(PatchMap previousPopulations = null,
                                                  bool playerReadable          = false, List <ExternalEffect> effects = null)
        {
            const bool resolveMigrations = true;
            const bool resolveSplits     = true;

            var builder = new LocalizedStringBuilder(500);

            LocalizedStringBuilder PatchString(Patch patch)
            {
                var builder2 = new LocalizedStringBuilder(80);

                if (!playerReadable)
                {
                    builder2.Append(patch.ID);
                }

                builder2.Append(' ');
                builder2.Append(new LocalizedString(patch.Name));

                return(builder2);
            }

            void OutputPopulationForPatch(Species species, Patch patch, long population)
            {
                builder.Append("  ");
                var patchName = PatchString(patch);

                if (population > 0)
                {
                    builder.Append(patchName);
                    builder.Append(' ');
                    builder.Append(new LocalizedString("POPULATION"));
                    builder.Append(' ');
                    builder.Append(population);
                }
                else
                {
                    // For some reason this line had one more space padding than the case that the population
                    // wasn't extinct in this patch

                    builder.Append(new LocalizedString("WENT_EXTINCT_IN", patchName));
                }

                if (previousPopulations != null)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("PREVIOUS"));
                    builder.Append(' ');
                    builder.Append(previousPopulations.GetPatch(patch.ID).GetSpeciesPopulation(species));
                }

                builder.Append('\n');
            }

            foreach (var entry in
                     results.Values.OrderByDescending(s => s.Species.PlayerSpecies)
                     .ThenBy(s => s.Species.FormattedName))
            {
                builder.Append(playerReadable ? entry.Species.FormattedName : entry.Species.FormattedIdentifier);
                builder.Append(":\n");

                if (entry.SplitFrom != null)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("RUN_RESULT_SPLIT_FROM",
                                                       playerReadable ? entry.SplitFrom.FormattedName : entry.SplitFrom.FormattedIdentifier));

                    builder.Append('\n');
                }

                if (entry.NewlyCreated != null)
                {
                    builder.Append(' ');

                    switch (entry.NewlyCreated.Value)
                    {
                    case NewSpeciesType.FillNiche:
                        builder.Append(new LocalizedString("RUN_RESULT_NICHE_FILL"));
                        break;

                    case NewSpeciesType.SplitDueToMutation:
                        builder.Append(new LocalizedString("RUN_RESULT_SELECTION_PRESSURE_SPLIT"));
                        break;

                    default:
                        GD.PrintErr("Unhandled newly created species type: ", entry.NewlyCreated.Value);
                        builder.Append(entry.NewlyCreated.Value);
                        break;
                    }

                    builder.Append('\n');
                }

                if (entry.SplitOff != null)
                {
                    if (entry.SplitOffPatches == null)
                    {
                        throw new InvalidOperationException("List of split off patches is null");
                    }

                    builder.Append(' ');
                    builder.Append(new LocalizedString("RUN_RESULT_SPLIT_OFF_TO",
                                                       playerReadable ? entry.SplitOff.FormattedName : entry.SplitOff.FormattedIdentifier));
                    builder.Append('\n');

                    foreach (var patch in entry.SplitOffPatches)
                    {
                        builder.Append("   ");

                        builder.Append(new LocalizedString(patch.Name));
                        builder.Append('\n');
                    }
                }

                if (entry.MutatedProperties != null)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("RUN_RESULT_HAS_A_MUTATION"));

                    if (!playerReadable)
                    {
                        builder.Append(", ");
                        builder.Append(new LocalizedString("RUN_RESULT_GENE_CODE"));
                        builder.Append(' ');
                        builder.Append(entry.MutatedProperties.StringCode);
                    }

                    builder.Append('\n');
                }

                if (entry.SpreadToPatches.Count > 0)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("RUN_RESULT_SPREAD_TO_PATCHES"));
                    builder.Append('\n');

                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        if (playerReadable)
                        {
                            builder.Append("  ");
                            builder.Append(new LocalizedString("RUN_RESULT_BY_SENDING_POPULATION",
                                                               new LocalizedString(spreadEntry.To.Name), spreadEntry.Population,
                                                               new LocalizedString(spreadEntry.From.Name)));
                        }
                        else
                        {
                            builder.Append("  ");
                            builder.Append(new LocalizedString(spreadEntry.To.Name));
                            builder.Append(" pop: ");
                            builder.Append(spreadEntry.Population);
                            builder.Append(" from: ");
                            builder.Append(new LocalizedString(spreadEntry.From.Name));
                        }

                        builder.Append('\n');
                    }
                }

                builder.Append(' ');
                builder.Append(new LocalizedString("RUN_RESULT_POP_IN_PATCHES"));
                builder.Append('\n');

                foreach (var patchPopulation in entry.NewPopulationInPatches)
                {
                    long adjustedPopulation = patchPopulation.Value;

                    if (resolveMigrations)
                    {
                        adjustedPopulation +=
                            CountSpeciesSpreadPopulation(entry.Species, patchPopulation.Key);
                    }

                    if (resolveSplits)
                    {
                        if (entry.SplitOffPatches?.Contains(patchPopulation.Key) == true)
                        {
                            // All population splits off
                            adjustedPopulation = 0;
                        }
                    }

                    // Apply external effects
                    if (effects != null && previousPopulations != null &&
                        previousPopulations.CurrentPatch.ID == patchPopulation.Key.ID)
                    {
                        foreach (var effect in effects)
                        {
                            if (effect.Species == entry.Species)
                            {
                                adjustedPopulation +=
                                    effect.Constant + (long)(effect.Species.Population * effect.Coefficient)
                                    - effect.Species.Population;
                            }
                        }
                    }

                    // As the populations are added to all patches, even when the species is not there, we remove those
                    // from output if there is currently no population in a patch and there isn't one in
                    // previousPopulations
                    var include = false;

                    if (adjustedPopulation > 0)
                    {
                        include = true;
                    }
                    else
                    {
                        if (previousPopulations?.GetPatch(patchPopulation.Key.ID).GetSpeciesPopulation(entry.Species) >
                            0)
                        {
                            include = true;
                        }
                    }

                    if (include)
                    {
                        OutputPopulationForPatch(entry.Species, patchPopulation.Key, adjustedPopulation);
                    }
                }

                // Also print new patches the species moved to (as the moves don't get
                // included in newPopulationInPatches
                if (resolveMigrations)
                {
                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        var found = false;

                        var to = spreadEntry.To;

                        foreach (var populationEntry in entry.NewPopulationInPatches)
                        {
                            if (populationEntry.Key == to)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            OutputPopulationForPatch(entry.Species, to,
                                                     CountSpeciesSpreadPopulation(entry.Species, to));
                        }
                    }
                }

                // Print populations from splits
                // Warning suppressed on resolveSplits to allow keeping the variable
                // ReSharper disable once RedundantLogicalConditionalExpressionOperand
                if (resolveSplits && entry.SplitFrom != null)
                {
                    var splitFrom = results[entry.SplitFrom];

                    // Skip if the SplitFrom variable was used just to indicate this didn't pop out of thin air
                    if (splitFrom.SplitOff == entry.Species)
                    {
                        foreach (var patchPopulation in splitFrom.SplitOffPatches)
                        {
                            OutputPopulationForPatch(entry.Species, patchPopulation,
                                                     splitFrom.NewPopulationInPatches[patchPopulation]);
                        }
                    }
                }

                if (GetGlobalPopulation(entry.Species, resolveMigrations, resolveSplits) <= 0)
                {
                    builder.Append(' ');
                    builder.Append(new LocalizedString("WENT_EXTINCT_FROM_PLANET"));
                    builder.Append('\n');
                }

                if (playerReadable)
                {
                    builder.Append('\n');
                }
            }

            return(builder);
        }
Ejemplo n.º 9
0
        /// <summary>
        ///   Makes summary text
        /// </summary>
        /// <param name="previousPopulations">If provided comparisons to previous populations is included</param>
        /// <param name="playerReadable">if true ids are removed from the output</param>
        /// <param name="effects">if not null these effects are applied to the population numbers</param>
        public string MakeSummary(PatchMap previousPopulations = null,
                                  bool playerReadable          = false, List <ExternalEffect> effects = null)
        {
            const bool resolveMoves = true;

            var builder = new StringBuilder(500);

            string PatchString(Patch patch)
            {
                var builder2 = new StringBuilder(80);

                if (!playerReadable)
                {
                    builder2.Append(patch.ID);
                }

                builder2.Append(" ");
                builder2.Append(patch.Name);

                return(builder2.ToString());
            }

            void OutputPopulationForPatch(Species species, Patch patch, long population)
            {
                if (population > 0)
                {
                    builder.Append("  ");
                    builder.Append(PatchString(patch));
                    builder.Append(" ");
                    builder.Append(TranslationServer.Translate("POPULATION"));
                    builder.Append(" ");
                    builder.Append(population);
                }
                else
                {
                    builder.Append("  ");
                    builder.Append(" went extinct in ");
                    builder.Append(PatchString(patch));
                }

                if (previousPopulations != null)
                {
                    builder.Append(" ");
                    builder.Append(TranslationServer.Translate("PREVIOUS"));
                    builder.Append(" ");
                    builder.Append(previousPopulations.GetPatch(patch.ID).GetSpeciesPopulation(species));
                }

                builder.Append("\n");
            }

            foreach (var entry in results.Values)
            {
                builder.Append(playerReadable ? entry.Species.FormattedName : entry.Species.FormattedIdentifier);
                builder.Append(":\n");

                if (entry.MutatedProperties != null)
                {
                    builder.Append(" ");
                    builder.Append(TranslationServer.Translate("RUNRESULT_HAS_A_MUTATION"));

                    if (!playerReadable)
                    {
                        builder.Append(", ");
                        builder.Append(TranslationServer.Translate("RUNRESULT_GENE_CODE"));
                        builder.Append(" ");
                        builder.Append(entry.MutatedProperties.StringCode);
                    }

                    builder.Append("\n");
                }

                if (entry.SpreadToPatches.Count > 0)
                {
                    builder.Append(" ");
                    builder.Append(TranslationServer.Translate("RUNRESULT_SPREAD_TO_PATCHES"));
                    builder.Append("\n");

                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        if (playerReadable)
                        {
                            builder.Append("  ");
                            builder.Append(string.Format(CultureInfo.CurrentCulture,
                                                         TranslationServer.Translate("RUNRESULT_BY_SENDING_POPULATION"),
                                                         spreadEntry.To.Name, spreadEntry.Population, spreadEntry.From.Name));
                        }
                        else
                        {
                            builder.Append("  ");
                            builder.Append(spreadEntry.To.Name);
                            builder.Append(" pop: ");
                            builder.Append(spreadEntry.Population);
                            builder.Append(" from: ");
                            builder.Append(spreadEntry.From.Name);
                        }

                        builder.Append("\n");
                    }
                }

                builder.Append(" ");
                builder.Append(TranslationServer.Translate("RUNRESULT_POP_IN_PATCHES"));
                builder.Append("\n");

                foreach (var patchPopulation in entry.NewPopulationInPatches)
                {
                    long adjustedPopulation = patchPopulation.Value;

                    if (resolveMoves)
                    {
                        adjustedPopulation +=
                            CountSpeciesSpreadPopulation(entry.Species, patchPopulation.Key);
                    }

                    // Apply external effects
                    if (effects != null && previousPopulations != null &&
                        previousPopulations.CurrentPatch.ID == patchPopulation.Key.ID)
                    {
                        foreach (var effect in effects)
                        {
                            if (effect.Species == entry.Species)
                            {
                                adjustedPopulation +=
                                    effect.Constant + (long)(effect.Species.Population * effect.Coefficient)
                                    - effect.Species.Population;
                            }
                        }
                    }

                    // As the populations are added to all patches, even when the species is not there, we remove those
                    // from output if there is currently no population in a patch and there isn't one in
                    // previousPopulations
                    var include = false;

                    if (adjustedPopulation > 0)
                    {
                        include = true;
                    }
                    else if (previousPopulations != null)
                    {
                        if (previousPopulations.GetPatch(patchPopulation.Key.ID).GetSpeciesPopulation(entry.Species) >
                            0)
                        {
                            include = true;
                        }
                    }

                    if (include)
                    {
                        OutputPopulationForPatch(entry.Species, patchPopulation.Key, adjustedPopulation);
                    }
                }

                // Also print new patches the species moved to (as the moves don't get
                // included in newPopulationInPatches
                if (resolveMoves)
                {
                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        var found = false;

                        var to = spreadEntry.To;

                        foreach (var populationEntry in entry.NewPopulationInPatches)
                        {
                            if (populationEntry.Key == to)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            OutputPopulationForPatch(entry.Species, to,
                                                     CountSpeciesSpreadPopulation(entry.Species, to));
                        }
                    }
                }

                if (GetGlobalPopulation(entry.Species, resolveMoves) <= 0)
                {
                    builder.Append(" ");
                    builder.Append("went extinct from the planet");
                    builder.Append("\n");
                }

                if (playerReadable)
                {
                    builder.Append("\n");
                }
            }

            return(builder.ToString());
        }
Ejemplo n.º 10
0
        public int DumpPatches(string outputFormat)
        {
            var offset = 8;               // skip to the tone map

            byte[] buffer;
            (buffer, offset) = Util.GetNextBytes(this.data, offset, PatchMap.Size);
            var patchMap = new PatchMap(buffer);

            List <int> patchNumbers = new List <int>();

            var patchCount = 0;

            for (var i = 0; i < PatchMap.PatchCount; i++)
            {
                if (patchMap[i])
                {
                    patchCount += 1;
                    //Console.Write(i + 1);
                    //Console.Write(" ");

                    patchNumbers.Add(i);
                }
            }

            var minimumPatchSize = SingleCommonSettings.DataSize + 2 * KSynthLib.K5000.Source.DataSize;
            var totalPatchSize   = 0;            // the total size of all the single patches
            var allPatchInfos    = new List <PatchInfo>();
            var singlePatches    = new List <SinglePatch>();

            foreach (var patchNumber in patchNumbers)
            {
                var startOffset = offset;                  // save the current offset because we need to copy more bytes later

                var sizeToRead = Math.Max(minimumPatchSize, this.data.Length - offset);
                // We don't know yet how many bytes the patch is, but it is at least the minimum size
                (buffer, offset) = Util.GetNextBytes(this.data, offset, sizeToRead);
                // the offset has now been updated past the read size, so need to adjust it back later

                //Console.Error.WriteLine(Util.HexDump(buffer));
                //Console.Error.WriteLine($"checksum = {buffer[0]:X2}H");

                var patch = new SinglePatch(buffer);

                // Find out how many PCM and ADD sources
                var pcmCount = 0;
                var addCount = 0;
                foreach (var source in patch.Sources)
                {
                    if (source.IsAdditive)
                    {
                        addCount += 1;
                    }
                    else
                    {
                        pcmCount += 1;
                    }
                }

                // Figure out the total size of the single patch based on the counts
                var patchSize = 1 + SingleCommonSettings.DataSize                        // includes the checksum
                                + patch.Sources.Length * KSynthLib.K5000.Source.DataSize // all sources have this part
                                + addCount * AdditiveKit.DataSize;
                //Console.WriteLine($"{pcmCount}PCM {addCount}ADD size={patchSize} bytes");

                offset = startOffset;                  // back up to the start of the patch data
                // Read the whole patch now that we know its size
                //Console.WriteLine($"About to read {patchSize} bytes starting from offset {offset:X4}h");
                (buffer, offset) = Util.GetNextBytes(this.data, offset, patchSize);

                totalPatchSize += patchSize;

                singlePatches.Add(patch);
            }

            foreach (var patch in singlePatches)
            {
                if (outputFormat.Equals("text"))
                {
                    Console.WriteLine(patch);
                }
                else if (outputFormat.Equals("json"))
                {
                    string jsonString = JsonConvert.SerializeObject(
                        patch,
                        Newtonsoft.Json.Formatting.Indented,
                        new Newtonsoft.Json.Converters.StringEnumConverter()
                        );
                    Console.WriteLine(jsonString);
                }
            }

            return(0);
        }
Ejemplo n.º 11
0
    public static PatchMap Generate(WorldGenerationSettings settings, Species defaultSpecies)
    {
        // TODO: implement actual generation based on settings
        _ = settings;

        var map = new PatchMap();

        // Predefined patches
        Patch patch0 = new Patch("Pangonian vents", 0, GetBiomeTemplate("aavolcanic_vent"));

        patch0.Depth[0] = 2500;
        patch0.Depth[1] = 3000;
        patch0.AddSpecies(defaultSpecies);
        patch0.ScreenCoordinates = new Vector2(100, 400);
        map.AddPatch(patch0);

        Patch patch1 = new Patch("Pangonian Mesopelagic", 1, GetBiomeTemplate("mesopelagic"));

        patch1.Depth[0]          = 200;
        patch1.Depth[1]          = 1000;
        patch1.ScreenCoordinates = new Vector2(200, 200);
        map.AddPatch(patch1);

        Patch patch2 = new Patch("Pangonian Epipelagic", 2, GetBiomeTemplate("default"));

        patch2.Depth[0]          = 0;
        patch2.Depth[1]          = 200;
        patch2.ScreenCoordinates = new Vector2(200, 100);
        map.AddPatch(patch2);

        Patch patch3 = new Patch("Pangonian Tidepool", 3, GetBiomeTemplate("tidepool"));

        patch3.Depth[0]          = 0;
        patch3.Depth[1]          = 10;
        patch3.ScreenCoordinates = new Vector2(300, 100);
        map.AddPatch(patch3);

        Patch patch4 = new Patch("Pangonian Bathypelagic", 4,
                                 GetBiomeTemplate("bathypelagic"));

        patch4.Depth[0]          = 1000;
        patch4.Depth[1]          = 4000;
        patch4.ScreenCoordinates = new Vector2(200, 300);
        map.AddPatch(patch4);

        Patch patch5 = new Patch("Pangonian Abyssopelagic", 5,
                                 GetBiomeTemplate("abyssopelagic"));

        patch5.Depth[0]          = 4000;
        patch5.Depth[1]          = 6000;
        patch5.ScreenCoordinates = new Vector2(300, 400);
        map.AddPatch(patch5);

        Patch patch6 = new Patch("Pangonian Coast", 6, GetBiomeTemplate("coastal"));

        patch6.Depth[0]          = 0;
        patch6.Depth[1]          = 200;
        patch6.ScreenCoordinates = new Vector2(100, 100);
        map.AddPatch(patch6);

        Patch patch7 = new Patch("Pangonian Estuary", 7, GetBiomeTemplate("estuary"));

        patch7.Depth[0]          = 0;
        patch7.Depth[1]          = 200;
        patch7.ScreenCoordinates = new Vector2(70, 160);
        map.AddPatch(patch7);

        Patch patch8 = new Patch("Cave", 8, GetBiomeTemplate("underwater_cave"));

        patch8.Depth[0]          = 200;
        patch8.Depth[1]          = 1000;
        patch8.ScreenCoordinates = new Vector2(300, 200);
        map.AddPatch(patch8);

        Patch patch9 = new Patch("Ice Shelf", 9, GetBiomeTemplate("ice_shelf"));

        patch9.Depth[0]          = 0;
        patch9.Depth[1]          = 200;
        patch9.ScreenCoordinates = new Vector2(200, 30);
        map.AddPatch(patch9);

        Patch patch10 = new Patch("Pangonian Sea Floor", 10, GetBiomeTemplate("seafloor"));

        patch10.Depth[0]          = 4000;
        patch10.Depth[1]          = 6000;
        patch10.ScreenCoordinates = new Vector2(200, 400);
        map.AddPatch(patch10);

        // Connections
        patch0.AddNeighbour(patch10);

        patch1.AddNeighbour(patch4);
        patch1.AddNeighbour(patch2);
        patch1.AddNeighbour(patch8);

        patch2.AddNeighbour(patch1);
        patch2.AddNeighbour(patch3);
        patch2.AddNeighbour(patch6);
        patch2.AddNeighbour(patch9);

        patch3.AddNeighbour(patch2);

        patch4.AddNeighbour(patch5);
        patch4.AddNeighbour(patch1);
        patch4.AddNeighbour(patch10);

        patch5.AddNeighbour(patch10);
        patch5.AddNeighbour(patch4);

        patch6.AddNeighbour(patch2);
        patch6.AddNeighbour(patch7);

        patch7.AddNeighbour(patch6);

        patch8.AddNeighbour(patch1);

        patch9.AddNeighbour(patch2);

        patch10.AddNeighbour(patch4);
        patch10.AddNeighbour(patch5);
        patch10.AddNeighbour(patch0);

        map.CurrentPatch = patch0;
        return(map);
    }
Ejemplo n.º 12
0
 public FindBestMigration(PatchMap map, Species species, int migrationsToTry, bool allowNoMigration)
     : base(migrationsToTry, allowNoMigration)
 {
     this.map     = map;
     this.species = species;
 }
Ejemplo n.º 13
0
        /// <summary>
        ///   Makes summary text
        /// </summary>
        /// <param name="previousPopulations">If provided comparisons to previous populations is included</param>
        /// <param name="playerReadable">if true ids are removed from the output</param>
        /// <param name="effects">if not null these effects are applied to the population numbers</param>
        public string MakeSummary(PatchMap previousPopulations = null,
                                  bool playerReadable          = false, List <ExternalEffect> effects = null)
        {
            const bool resolveMoves = true;

            var builder = new StringBuilder(500);

            string PatchString(Patch patch)
            {
                var builder2 = new StringBuilder(80);

                if (!playerReadable)
                {
                    builder2.Append(patch.ID);
                }

                builder2.Append(" ");
                builder2.Append(patch.Name);

                return(builder2.ToString());
            }

            void OutputPopulationForPatch(Species species, Patch patch, int population)
            {
                builder.Append("  ");

                builder.Append(PatchString(patch));

                builder.Append(" population: ");
                builder.Append(Math.Max(population, 0));

                if (previousPopulations != null)
                {
                    builder.Append(" previous: ");
                    builder.Append(previousPopulations.GetPatch(patch.ID).GetSpeciesPopulation(species));
                }

                builder.Append("\n");
            }

            foreach (var entry in results.Values)
            {
                builder.Append(playerReadable ? entry.Species.FormattedName : entry.Species.FormattedIdentifier);
                builder.Append(":\n");

                if (entry.MutatedProperties != null)
                {
                    builder.Append(" has a mutation");

                    if (!playerReadable)
                    {
                        builder.Append(", gene code: ");
                        builder.Append(entry.MutatedProperties.StringCode);
                    }

                    builder.Append("\n");
                }

                if (entry.SpreadToPatches.Count > 0)
                {
                    builder.Append(" spread to patches:\n");

                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        if (playerReadable)
                        {
                            builder.Append("  ");
                            builder.Append(spreadEntry.To.Name);
                            builder.Append(" by sending: ");
                            builder.Append(spreadEntry.Population);
                            builder.Append(" population");
                            builder.Append(" from patch: ");
                            builder.Append(spreadEntry.From.Name);
                        }
                        else
                        {
                            builder.Append("  ");
                            builder.Append(spreadEntry.To.Name);
                            builder.Append(" pop: ");
                            builder.Append(spreadEntry.Population);
                            builder.Append(" from: ");
                            builder.Append(spreadEntry.From.Name);
                        }

                        builder.Append("\n");
                    }
                }

                builder.Append(" population in patches:\n");

                foreach (var patchPopulation in entry.NewPopulationInPatches)
                {
                    var adjustedPopulation = patchPopulation.Value;

                    if (resolveMoves)
                    {
                        adjustedPopulation +=
                            CountSpeciesSpreadPopulation(entry.Species, patchPopulation.Key);
                    }

                    // Apply external effects
                    if (effects != null && previousPopulations != null &&
                        previousPopulations.CurrentPatch.ID == patchPopulation.Key.ID)
                    {
                        foreach (var effect in effects)
                        {
                            if (effect.Species == entry.Species)
                            {
                                adjustedPopulation += effect.Amount;
                            }
                        }
                    }

                    // As the populations are added to all patches, even when the species is not there, we remove those
                    // from output if there is currently no population in a patch and there isn't one in
                    // previousPopulations
                    bool include = false;

                    if (adjustedPopulation > 0)
                    {
                        include = true;
                    }
                    else if (previousPopulations != null)
                    {
                        if (previousPopulations.GetPatch(patchPopulation.Key.ID).GetSpeciesPopulation(entry.Species) >
                            0)
                        {
                            include = true;
                        }
                    }

                    if (include)
                    {
                        OutputPopulationForPatch(entry.Species, patchPopulation.Key, adjustedPopulation);
                    }
                }

                // Also print new patches the species moved to (as the moves don't get
                // included in newPopulationInPatches
                if (resolveMoves)
                {
                    foreach (var spreadEntry in entry.SpreadToPatches)
                    {
                        bool found = false;

                        var to = spreadEntry.To;

                        foreach (var populationEntry in entry.NewPopulationInPatches)
                        {
                            if (populationEntry.Key == to)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            OutputPopulationForPatch(entry.Species, to,
                                                     CountSpeciesSpreadPopulation(entry.Species, to));
                        }
                    }
                }

                if (playerReadable)
                {
                    builder.Append("\n");
                }
            }

            return(builder.ToString());
        }
Ejemplo n.º 14
0
        private static void ProcessMessage(byte[] message)
        {
            Console.WriteLine($"Message length = {message.Length} bytes");

            var header = new SystemExclusiveHeader(message);
            //Console.WriteLine("{0}", header);

            var functionNames = new Dictionary <SystemExclusiveFunction, string>()
            {
                { SystemExclusiveFunction.OneBlockDumpRequest, "One Block Dump Request" },
                { SystemExclusiveFunction.AllBlockDumpRequest, "All Block Dump Request" },
                { SystemExclusiveFunction.ParameterSend, "Parameter Send" },
                { SystemExclusiveFunction.TrackControl, "Track Control" },
                { SystemExclusiveFunction.OneBlockDump, "One Block Dump" },
                { SystemExclusiveFunction.AllBlockDump, "All Block Dump" },
                { SystemExclusiveFunction.ModeChange, "Mode Change" },
                { SystemExclusiveFunction.Remote, "Remote" },
                { SystemExclusiveFunction.WriteComplete, "Write Complete" },
                { SystemExclusiveFunction.WriteError, "Write Error" },
                { SystemExclusiveFunction.WriteErrorByProtect, "Write Error (Protect)" },
                { SystemExclusiveFunction.WriteErrorByMemoryFull, "Write Error (Memory Full)" },
                { SystemExclusiveFunction.WriteErrorByNoExpandMemory, "Write Error (No Expansion Memory)" }
            };

            var    function = (SystemExclusiveFunction)header.Function;
            string functionName;

            if (functionNames.TryGetValue(function, out functionName))
            {
                Console.Error.WriteLine("Function = {0}", functionName);
            }
            else
            {
                Console.Error.WriteLine("Unknown function: {0}", function);
            }

            switch (header.Substatus1)
            {
            case 0x00:
                Console.WriteLine("Single");
                break;

            case 0x20:
                Console.WriteLine("Multi");
                break;

            case 0x10:
                Console.WriteLine("Drum Kit");      // K5000W only
                break;

            case 0x11:
                Console.WriteLine("Drum Inst");      // K5000W only
                break;

            default:
                Console.Error.WriteLine(string.Format("Unknown substatus1: {0:X2}", header.Substatus1));
                break;
            }

            switch (header.Substatus2)
            {
            case 0x00:
                Console.WriteLine("Add Bank A");
                break;

            case 0x01:
                Console.WriteLine("PCM Bank B");      // K5000W
                break;

            case 0x02:
                Console.WriteLine("Add Bank D");
                break;

            case 0x03:
                Console.WriteLine("Exp Bank E");
                break;

            case 0x04:
                Console.WriteLine("Exp Bank F");
                break;

            default:
                Console.WriteLine("Substatus2 is first data byte");
                break;
            }

            switch (function)
            {
            case SystemExclusiveFunction.OneBlockDump:
                Console.WriteLine("One Block Dump");

                int toneNumber = message[8] + 1;
                Console.WriteLine($"Tone No = {toneNumber} ({message[8]})");
                break;

            case SystemExclusiveFunction.AllBlockDump:
                Console.WriteLine("All Block Dump");
                break;

            default:
                Console.WriteLine($"Unknown function: {function}");
                break;
            }

            if (function == SystemExclusiveFunction.AllBlockDump)
            {
                var patchMapData = new byte[PatchMap.Size];
                Array.Copy(message, SystemExclusiveHeader.DataSize, patchMapData, 0, PatchMap.Size);

                var patchMap = new PatchMap(patchMapData);

                Console.WriteLine("Patches included:");
                for (var i = 0; i < PatchMap.PatchCount; i++)
                {
                    if (patchMap[i])
                    {
                        Console.Write(i + 1);
                        Console.Write(" ");
                    }
                }
                Console.WriteLine();

                var dataLength = message.Length - SystemExclusiveHeader.DataSize - PatchMap.Size;
                var data       = new byte[dataLength];
                Array.Copy(message, SystemExclusiveHeader.DataSize + PatchMap.Size, data, 0, dataLength);
                //Console.WriteLine(Util.HexDump(data));

                var  offset   = 0;
                byte checksum = data[offset];
                Console.WriteLine($"checksum = {checksum:X2}");
                offset += 1;
            }

            // Single additive patch for bank A or D:
            if (header.Substatus1 == 0x00 && (header.Substatus2 == 0x00 || header.Substatus2 == 0x02))
            {
                var dataLength = message.Length - SystemExclusiveHeader.DataSize - PatchMap.Size;
                var data       = new byte[dataLength];
                Array.Copy(message, SystemExclusiveHeader.DataSize + PatchMap.Size, data, 0, dataLength);
                //Console.WriteLine(Util.HexDump(data));

                // Chop the data into individual buffers based on the declared sizes
                var  offset   = 0;
                byte checksum = data[offset];
                Console.WriteLine($"checksum = {checksum:X2}");
                offset += 1;
                var commonData = new byte[SingleCommonSettings.DataSize];
                Array.Copy(data, offset, commonData, 0, SingleCommonSettings.DataSize);
                //Console.WriteLine(Util.HexDump(commonData));
                offset += SingleCommonSettings.DataSize;

                var patch = new SinglePatch(data);
                Console.WriteLine($"Name = {patch.SingleCommon.Name}");
            }
        }
Ejemplo n.º 15
0
 public SimulationConfiguration(PatchMap initialConditions, int steps = 1)
 {
     OriginalMap = initialConditions;
     StepsLeft   = Math.Max(1, steps);
 }
Ejemplo n.º 16
0
    public static PatchMap Generate(WorldGenerationSettings settings, Species defaultSpecies)
    {
        // TODO: implement actual generation based on settings
        _ = settings;

        var map = new PatchMap();

        // Predefined patches
        var vents = new Patch("PATCH_PANGONIAN_VENTS", 0,
                              GetBiomeTemplate("aavolcanic_vent"))
        {
            Depth =
            {
                [0] = 2500,
                [1] = 3000,
            },
            ScreenCoordinates = new Vector2(100, 400),
        };

        vents.AddSpecies(defaultSpecies);
        map.AddPatch(vents);

        var mesopelagic = new Patch("PATCH_PANGONIAN_MESOPELAGIC", 1,
                                    GetBiomeTemplate("mesopelagic"))
        {
            Depth =
            {
                [0] = 200,
                [1] = 1000,
            },
            ScreenCoordinates = new Vector2(200, 200),
        };

        map.AddPatch(mesopelagic);

        var epipelagic = new Patch("PATCH_PANGONIAN_EPIPELAGIC", 2,
                                   GetBiomeTemplate("default"))
        {
            Depth =
            {
                [0] = 0,
                [1] = 200,
            },
            ScreenCoordinates = new Vector2(200, 100),
        };

        map.AddPatch(epipelagic);

        var tidepool = new Patch("PATCH_PANGONIAN_TIDEPOOL", 3,
                                 GetBiomeTemplate("tidepool"))
        {
            Depth =
            {
                [0] = 0,
                [1] = 10,
            },
            ScreenCoordinates = new Vector2(300, 100),
        };

        map.AddPatch(tidepool);

        var bathypelagic = new Patch("PATCH_PANGONIAN_BATHYPELAGIC", 4,
                                     GetBiomeTemplate("bathypelagic"))
        {
            Depth =
            {
                [0] = 1000,
                [1] = 4000,
            },
            ScreenCoordinates = new Vector2(200, 300),
        };

        map.AddPatch(bathypelagic);

        var abyssopelagic = new Patch("PATHCH_PANGONIAN_ABYSSOPELAGIC", 5,
                                      GetBiomeTemplate("abyssopelagic"))
        {
            Depth =
            {
                [0] = 4000,
                [1] = 6000,
            },
            ScreenCoordinates = new Vector2(300, 400),
        };

        map.AddPatch(abyssopelagic);

        var coast = new Patch("PATCH_PANGONIAN_COAST", 6,
                              GetBiomeTemplate("coastal"))
        {
            Depth =
            {
                [0] = 0,
                [1] = 200,
            },
            ScreenCoordinates = new Vector2(100, 100),
        };

        map.AddPatch(coast);

        var estuary = new Patch("PATCH_PANGONIAN_ESTUARY", 7,
                                GetBiomeTemplate("estuary"))
        {
            Depth =
            {
                [0] = 0,
                [1] = 200,
            },
            ScreenCoordinates = new Vector2(70, 160),
        };

        map.AddPatch(estuary);

        var cave = new Patch("PATCH_CAVE", 8,
                             GetBiomeTemplate("underwater_cave"))
        {
            Depth =
            {
                [0] = 200,
                [1] = 1000,
            },
            ScreenCoordinates = new Vector2(300, 200),
        };

        map.AddPatch(cave);

        var iceShelf = new Patch("PATCH_ICE_SHELF", 9,
                                 GetBiomeTemplate("ice_shelf"))
        {
            Depth =
            {
                [0] = 0,
                [1] = 200,
            },
            ScreenCoordinates = new Vector2(200, 30),
        };

        map.AddPatch(iceShelf);

        var seafloor = new Patch("PATCH_PANGONIAN_SEAFLOOR", 10,
                                 GetBiomeTemplate("seafloor"))
        {
            Depth =
            {
                [0] = 4000,
                [1] = 6000,
            },
            ScreenCoordinates = new Vector2(200, 400),
        };

        map.AddPatch(seafloor);

        // Connections
        LinkPatches(vents, seafloor);
        LinkPatches(seafloor, bathypelagic);
        LinkPatches(seafloor, abyssopelagic);
        LinkPatches(bathypelagic, abyssopelagic);
        LinkPatches(bathypelagic, mesopelagic);
        LinkPatches(mesopelagic, epipelagic);
        LinkPatches(mesopelagic, cave);
        LinkPatches(epipelagic, tidepool);
        LinkPatches(epipelagic, iceShelf);
        LinkPatches(epipelagic, coast);
        LinkPatches(coast, estuary);

        map.CurrentPatch = vents;
        return(map);
    }
Ejemplo n.º 17
0
 public CalculatePopulation(PatchMap map)
 {
     this.map = map;
 }
Ejemplo n.º 18
0
        public void SaveZone(bool backup)
        {
            if (BUSY && !backup)
            {
                if (
                    MessageBox.Show("Zone Edit is busy - save as backup?", "Warning!", MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Warning) !=
                    DialogResult.Yes)
                {
                    return;
                }


                backup = true;
            }
            BUSY = true;

            string path = (backup ? PATH + "_backup" : PATH);

            if (!backup)
            {
                //if (Directory.Exists(PATH + "_backup")) {
                //    Directory.Delete(PATH + "_backup", true);
                //}
                Loading.Update("Initiating save process..");
                Loading.ShowLoading(true);
            }
            else
            {
                if (Directory.Exists(PATH + "_backup"))
                {
                    if (Directory.Exists(PATH + "_backup_bak"))
                    {
                        Directory.Delete(PATH + "_backup_bak", true);
                    }

                    Directory.Move(PATH + "_backup", PATH + "_backup_bak");
                }
            }

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            #region datXXX.mpk

            int bwillow = 0;
            {
                string p  = string.Format("dat{0}.mpk", ZoneID.ToString("D3"));
                string pp = path + "\\" + p;
                Loading.Update("Saving " + p + "...");

                if (!Directory.Exists(pp))
                {
                    Directory.CreateDirectory(pp);
                }

                #region SECTOR.DAT

                {
                    Loading.Update("Saving " + p + "... - sector.dat");

                    var s = new INIStreamer(string.Format("{0}\\SECTOR.DAT" + (backup ? ".bak" : ""), pp));
                    s.ReadIni();
                    s.Header.Clear();

                    s.SetItem("terrain", "scalefactor", TerrainScaleFactor.ToString());
                    s.SetItem("terrain", "offsetfactor", TerrainOffsetFactor.ToString());

                    //Rivers
                    int rivers = 0;

                    foreach (Polygon pl in Polygon.Polygons)
                    {
                        if (pl.Type != ePolygon.Water)
                        {
                            continue;
                        }

                        //Save this river

                        string pre = string.Format("river{0:D2}", rivers);

                        if (s.GetTopic(pre) != null)
                        {
                            s.RemTopic(pre);
                        }

                        s.SetItem(pre, "texture", pl.WTexture);
                        s.SetItem(pre, "multitexture", pl.WMultiTexture);
                        s.SetItem(pre, "flow", pl.WFlow.ToString());
                        s.SetItem(pre, "height", pl.WHeight.ToString());
                        s.SetItem(pre, "Tesselation", pl.WTesselation.ToString());
                        s.SetItem(pre, "type", pl.WType.ToString().ToUpper());
                        s.SetItem(pre, "bankpoints", (pl.Points.Count / 2).ToString());
                        s.SetItem(pre, "name", pre);

                        for (int a = 0; a < pl.Points.Count; a += 2)
                        {
                            var x1 = (int)(pl.Points[a].X / 256);
                            var y1 = (int)(pl.Points[a].Y / 256);
                            var x2 = (int)(pl.Points[a + 1].X / 256);
                            var y2 = (int)(pl.Points[a + 1].Y / 256);

                            lock (pl.Points) {
                                pl.Points[a]     = new Vector2(x1 * 256, y1 * 256);
                                pl.Points[a + 1] = new Vector2(x2 * 256, y2 * 256);
                            }

                            s.SetItem(pre, string.Format("left{0:D2}", a / 2),
                                      string.Format("{0},{1},0", x1, y1));
                            s.SetItem(pre, string.Format("right{0:D2}", a / 2),
                                      string.Format("{0},{1},0", x2, y2));
                        }

                        rivers++;
                    }


                    s.SetItem("waterdefs", "num", rivers.ToString());

                    s.WriteIni();
                }

                #endregion

                #region terrain.pcx/offset.pcx

                {
                    Loading.Update("Saving " + p + "... - Heightmaps");

                    var terrain = new byte[256, 256];
                    var offset  = new byte[256, 256];

                    for (int x = 0; x <= 255; x++)
                    {
                        for (int y = 0; y <= 255; y++)
                        {
                            int o = HeightMap[x, y] / TerrainOffsetFactor;

                            if (o > 255)
                            {
                                o = 255;
                            }

                            int remaining = HeightMap[x, y] - o * TerrainOffsetFactor;

                            int t = remaining / TerrainScaleFactor;

                            if (t > 255)
                            {
                                t = 255; //some information may get lost
                            }
                            offset[x, y]  = (byte)(o);
                            terrain[x, y] = (byte)(t);
                        }
                    }

                    PCXImage.Save(string.Format("{0}\\terrain.pcx", pp), terrain);
                    PCXImage.Save(string.Format("{0}\\offset.pcx", pp), offset);
                }

                #endregion

                #region bound.csv

                {
                    Loading.Update("Saving " + p + "... - Bounds");

                    var rs = new StreamWriter(string.Format("{0}\\bound.csv", pp));

                    foreach (Polygon pl in Polygon.Polygons)
                    {
                        if (pl.Type != ePolygon.Bounding)
                        {
                            continue;
                        }

                        //?, count, x,y, x2,y2, x3, y3, ..
                        string vectors = "";

                        foreach (Vector2 v in pl.Points)
                        {
                            vectors += string.Format(",{0},{1}", (int)v.X, (int)v.Y);
                        }

                        rs.WriteLine("{0},{1}{2}", 0, pl.Points.Count, vectors);
                    }

                    rs.Flush();
                    rs.Close();
                }

                #endregion

                #region water.pcx

                {
                    Loading.Update("Saving " + p + "... - Water");

                    var data = new byte[256, 256];

                    for (int x = 0; x < 256; x++)
                    {
                        for (int y = 0; y < 256; y++)
                        {
                            int  height       = (HeightMap[x, y]);
                            bool isUnderwater = false;
                            int  n            = -1;

                            foreach (Polygon pl in Polygon.Polygons)
                            {
                                if (pl.Type != ePolygon.Water)
                                {
                                    continue;
                                }

                                if (!isUnderwater)
                                {
                                    n++;
                                }

                                if (pl.WHeight < height)
                                {
                                    continue;
                                }

                                //Check if point is inside
                                var pnt = new Vector2(x, y);

                                for (int idx = 0; idx < pl.Points.Count - 2; idx += 2)
                                {
                                    Vector2 l1 = pl.Points[idx];
                                    Vector2 r1 = pl.Points[idx + 1];
                                    Vector2 l2 = pl.Points[idx + 2];
                                    Vector2 r2 = pl.Points[idx + 3];

                                    var _l1 = new Vector3(l1.X, l1.Y, 0);
                                    var _r1 = new Vector3(r1.X, r1.Y, 0);
                                    var _l2 = new Vector3(l2.X, l2.Y, 0);
                                    var _r2 = new Vector3(r2.X, r2.Y, 0);

                                    var rayStart = new Vector3(pnt.X * 256, pnt.Y * 256, 1.0f);
                                    var rayDir   = new Vector3(0, 0, -1);

                                    IntersectInformation i;
                                    if (Geometry.IntersectTri(_l1, _r1, _l2, rayStart, rayDir, out i) ||
                                        Geometry.IntersectTri(_r1, _r2, _l2, rayStart, rayDir, out i))
                                    {
                                        isUnderwater = true;
                                        break;
                                    }
                                }
                            }

                            data[x, y] = (byte)(isUnderwater ? n : 255);
                        }
                    }

                    for (int i = 0; i < 2; i++)
                    {
                        WaterDilatation(data);
                    }
                    PCXImage.Save(string.Format("{0}\\water.pcx", pp), data);
                }

                #endregion

                #region nifs.csv

                {
                    Loading.Update("Saving " + p + "... - NIFs");

                    var rs = new StreamWriter(string.Format("{0}\\nifs.csv", pp));

                    rs.WriteLine("Grid Nifs,,,Ambient,Merlin Data");
                    rs.WriteLine(
                        "NIF,Textual Name,Filename,Only,Shadow,Color,Animate,Collide,Ground,MinAngle,MaxAngle,MinScale,MaxScale,Radius,LOD 1,LOD 2,LOD 3,LOD 4,Ref Height,Ref Width,Unique,Local,Terrain");


                    int id = 1;

                    var clones = new List <Objects.NIF>();
                    foreach (Objects.NIF n in Objects.NIFs.Values)
                    {
                        clones.Add(n);
                    }
                    Objects.NIFs.Clear();

                    foreach (Objects.NIF n in clones)
                    {
                        n.ID = id;
                        Objects.NIFs.Add(n.ID, n);

                        rs.Write(id);
                        rs.Write("," + n.FileName + "|" + n.Group); //name
                        rs.Write("," + n.FileName);                 //filename
                        rs.Write("," + 0);                          //ambient only
                        rs.Write("," + 0);                          //merlin shadow data
                        rs.Write("," + 0);                          //color
                        rs.Write("," + (n.IsDoor ? 1 : 0));         //animate
                        rs.Write("," + n.Collision);                //collide
                        rs.Write("," + 1);                          //on ground
                        rs.Write("," + 0);                          //min angle
                        rs.Write("," + 0);                          //max angle
                        rs.Write("," + n.MinScale);                 //min scale
                        rs.Write("," + n.MaxScale);                 //max scale
                        rs.Write("," + n.CollideRadius);            //radius
                        rs.Write("," + 0);                          //lod1
                        rs.Write("," + 0);                          //lod2
                        rs.Write("," + 0);                          //lod3
                        rs.Write("," + 0);                          //lod4
                        rs.Write("," + 16);                         //ref height
                        rs.Write("," + 16);                         //ref width
                        rs.Write("," + 0);                          //unique
                        rs.Write("," + 0);                          //local
                        rs.Write("," + 0);                          //terrain
                        rs.WriteLine();

                        id++;
                    }

                    rs.Flush();
                    rs.Close();
                }

                #endregion

                #region fixtures.csv

                {
                    Loading.Update("Saving " + p + "... - Fixtures");
                    var rs = new StreamWriter(string.Format("{0}\\fixtures.csv", pp));

                    rs.WriteLine("Fixtures,,,,,,,,NIF,Collide,,On,,,,,,,");
                    rs.WriteLine(
                        "ID,NIF #,Textual Name,X,Y,Z,A,Scale,Collide,Radius,Animate,Ground,Flip,Cave,Unique ID, 3D Angle, 3D Axis X, 3D Axis Y, 3D Axis Z");

                    var freeIDs = new List <int>();

                    int id = 1;
                    foreach (Objects.Fixture f in Objects.Fixtures)
                    {
                        if (f.NIF.FileName.ToLower().Contains("bwillow"))
                        {
                            bwillow++;
                        }

                        if (f.NIF.IsDoor) //lock ID
                        {
                            for (int i = id; i < f.ID; i++)
                            {
                                freeIDs.Add(i);
                            }
                            id = f.ID + 1;
                        }
                        else
                        {
                            if (freeIDs.Count > 0)
                            {
                                f.ID = freeIDs[0];
                                freeIDs.RemoveAt(0);
                            }
                            else
                            {
                                f.ID = id++;
                            }
                        }

                        rs.Write(f.ID);
                        rs.Write("," + f.NIF_ID);
                        rs.Write("," + f.Name);
                        rs.Write("," + f.X.ToString().Replace(',', '.'));
                        rs.Write("," + f.Y.ToString().Replace(',', '.'));
                        rs.Write("," + f.Z.ToString().Replace(',', '.'));
                        rs.Write("," + 0);                                       //A (angle?)
                        rs.Write("," + f.Scale);
                        rs.Write("," + f.NIF.Collision);                         //collide
                        rs.Write("," + f.NIF.CollideRadius);                     //radius
                        rs.Write("," + 0);                                       //animate
                        rs.Write("," + (f.OnGround ? 1 : 0));                    //ground
                        rs.Write("," + 0);                                       //flip
                        rs.Write("," + 0);                                       //cave
                        rs.Write("," + f.ID);                                    //uid
                        rs.Write("," + f.Rotation.ToString().Replace(',', '.')); //3d angle
                        rs.Write("," + f.AxisX.ToString().Replace(',', '.'));    //); //3d x
                        rs.Write("," + f.AxisY.ToString().Replace(',', '.'));    //3d y
                        rs.Write("," + f.AxisZ.ToString().Replace(',', '.'));    //3d z
                        rs.WriteLine();
                    }

                    rs.Flush();
                    rs.Close();
                }

                #endregion

                #region zonejump.csv

                {
                    Loading.Update("Saving " + p + "... - Zonejumps");

                    var rs    = new StreamWriter(string.Format("{0}\\zonejump.csv", pp));
                    int index = 1;

                    foreach (Zonejump j in Zonejump.Zonejumps)
                    {
                        //ID, Name, X, Y, X2, Y2, Z1, Z2, JID

                        rs.Write(index++);
                        rs.Write("," + j.Name);
                        rs.Write("," + (int)j.First.X);
                        rs.Write("," + (int)j.First.Y);
                        rs.Write("," + (int)j.Second.X);
                        rs.Write("," + (int)j.Second.Y);
                        rs.Write("," + (int)j.First.Z);
                        rs.Write("," + (int)j.Second.Z);
                        rs.Write("," + j.ID);

                        rs.WriteLine();
                    }

                    rs.Flush();
                    rs.Close();
                }

                #endregion

                #region lights.csv

                {
                    Loading.Update("Saving " + p + "... - Lights");

                    var rs = new StreamWriter(string.Format("{0}\\lights.csv", pp));

                    foreach (Light l in Light.Lights)
                    {
                        //46473, 54362, 2910, 3
                        //X, Y, Z, Intensity

                        rs.Write(l.X);
                        rs.Write(", " + l.Y);
                        rs.Write(", " + (l.Z + l.ZOffset));
                        rs.Write(", " + ((int)l.Color + ((l.Intensity - 1) * 10)));
                        rs.WriteLine();
                    }

                    rs.Flush();
                    rs.Close();
                }

                #endregion
            }

            #endregion

            #region terXXX.mpk

            {
                string p  = string.Format("ter{0}.mpk", ZoneID.ToString("D3"));
                string pp = path + "\\" + p;
                Loading.Update("Saving Textures..");

                if (!Directory.Exists(pp))
                {
                    Directory.CreateDirectory(pp);
                }

                PatchMap.Save(pp + "\\", backup);
            }

            #endregion

            Loading.Update("Saving Sounds...");
            SoundMgr.Save(path);

            if (!backup)
            {
                if (bwillow >= 2000)
                {
                    MessageBox.Show("For every bwillow you will now have to close one Messagebox..!");
                    Loading.Update("Annoying you...");

                    for (int i = bwillow; i <= bwillow; i++)
                    {
                        MessageBox.Show("bwillow " + bwillow);
                    }
                }
            }

            if (!backup)
            {
                LAST_SAVE = DateTime.UtcNow.Ticks;
            }

            GC.Collect();
            Loading.Update("Done.");
            Loading.CloseLoading();
            BUSY = false;
        }
Ejemplo n.º 19
0
        public int ListPatches()
        {
            // SysEx header at this point should be "F0 40 00 21 00 0A 00 00" followed by the tone map
            var offset = 8;               // skip to the tone map

            //Console.Error.WriteLine($"offset = {offset}");

            // For a block data dump, need to parse the tone map
            byte[] buffer;
            (buffer, offset) = Util.GetNextBytes(this.data, offset, PatchMap.Size);
            // now the offset has been updated to past the tone map
            //Console.Error.WriteLine($"offset = {offset}");
            var patchMap = new PatchMap(buffer);

            List <int> patchNumbers = new List <int>();

            //Console.WriteLine("Patches included:");
            var patchCount = 0;

            for (var i = 0; i < PatchMap.PatchCount; i++)
            {
                if (patchMap[i])
                {
                    patchCount += 1;
                    //Console.Write(i + 1);
                    //Console.Write(" ");

                    patchNumbers.Add(i);
                }
            }
            //Console.WriteLine($"\nTotal = {patchCount} patches");

            // Whatever the first patch is, it must be at least this many bytes (always has at least two sources)
            var minimumPatchSize = SingleCommonSettings.DataSize + 2 * KSynthLib.K5000.Source.DataSize;
            //Console.Error.WriteLine($"minimum patch size = {minimumPatchSize}");

            var totalPatchSize = 0;              // the total size of all the single patches

            var allPatchInfos = new List <PatchInfo>();

            var singlePatches = new List <SinglePatch>();

            foreach (var patchNumber in patchNumbers)
            {
                var startOffset = offset;                  // save the current offset because we need to copy more bytes later

                var sizeToRead = Math.Max(minimumPatchSize, this.data.Length - offset);
                //Console.WriteLine($"About to read {sizeToRead} bytes starting from offset {offset:X4}h");
                // We don't know yet how many bytes the patch is, but it is at least the minimum size
                (buffer, offset) = Util.GetNextBytes(this.data, offset, sizeToRead);
                // the offset has now been updated past the read size, so need to adjust it back later

                //Console.Error.WriteLine(Util.HexDump(buffer));
                //Console.Error.WriteLine($"checksum = {buffer[0]:X2}H");

                var patch = new SinglePatch(buffer);

                // Find out how many PCM and ADD sources
                var pcmCount = 0;
                var addCount = 0;
                foreach (var source in patch.Sources)
                {
                    if (source.IsAdditive)
                    {
                        addCount += 1;
                    }
                    else
                    {
                        pcmCount += 1;
                    }
                }

                // Figure out the total size of the single patch based on the counts
                var patchSize = 1 + SingleCommonSettings.DataSize                        // includes the checksum
                                + patch.Sources.Length * KSynthLib.K5000.Source.DataSize // all sources have this part
                                + addCount * AdditiveKit.DataSize;
                //Console.WriteLine($"{pcmCount}PCM {addCount}ADD size={patchSize} bytes");

                offset = startOffset;                  // back up to the start of the patch data
                // Read the whole patch now that we know its size
                //Console.WriteLine($"About to read {patchSize} bytes starting from offset {offset:X4}h");
                (buffer, offset) = Util.GetNextBytes(this.data, offset, patchSize);

                totalPatchSize += patchSize;

                singlePatches.Add(patch);

                var patchInfo = new PatchInfo
                {
                    Bank                = this.Header.Bank,
                    PatchNumber         = patchNumber + 1,
                    PatchName           = patch.SingleCommon.Name,
                    PCMSourceCount      = pcmCount,
                    AdditiveSourceCount = addCount,
                };
                Console.WriteLine($"{patchInfo.Bank}{patchInfo.PatchNumber:D3} | {patchInfo.PatchName,8} | {patchInfo.PCMSourceCount}PCM {patchInfo.AdditiveSourceCount}ADD");

                allPatchInfos.Add(patchInfo);
            }

            foreach (var patchInfo in allPatchInfos)
            {
                Console.WriteLine($"{patchInfo.Bank}{patchInfo.PatchNumber:D3} | {patchInfo.PatchName,8} | {patchInfo.PCMSourceCount}PCM {patchInfo.AdditiveSourceCount}ADD");
            }

            return(0);
        }