コード例 #1
0
 public NewMicrobeActionData(OrganelleLayout <OrganelleTemplate> oldEditedMicrobeOrganelles, int previousMP,
                             MembraneType oldMembrane)
 {
     OldEditedMicrobeOrganelles = oldEditedMicrobeOrganelles;
     PreviousMP  = previousMP;
     OldMembrane = oldMembrane;
 }
コード例 #2
0
 /// <summary>
 ///   Adds a new organelle to a mutation result
 /// </summary>
 private void AddNewOrganelle(OrganelleLayout <OrganelleTemplate> organelles,
                              OrganelleDefinition organelle)
 {
     try
     {
         organelles.Add(GetRealisticPosition(organelle, organelles));
     }
     catch (ArgumentException)
     {
         // Failing to add a mutation is not serious
     }
 }
コード例 #3
0
    private OrganelleTemplate GetRealisticPosition(OrganelleDefinition organelle,
                                                   OrganelleLayout <OrganelleTemplate> existingOrganelles)
    {
        var result = new OrganelleTemplate(organelle, new Hex(0, 0), 0);

        // Loop through all the organelles and find an open spot to
        // place our new organelle attached to existing organelles
        // This almost always is over at the first iteration, so its
        // not a huge performance hog
        foreach (var otherOrganelle in existingOrganelles.OrderBy(_ => random.Next()))
        {
            // The otherOrganelle is the organelle we wish to be next to
            // Loop its hexes and check positions next to them
            foreach (var hex in otherOrganelle.RotatedHexes)
            {
                // Offset by hexes in organelle we are looking at
                var pos = otherOrganelle.Position + hex;

                for (int side = 1; side <= 6; ++side)
                {
                    for (int radius = 1; radius <= 3; ++radius)
                    {
                        // Offset by hex offset multiplied by a factor to check for greater range
                        var hexOffset = Hex.HexNeighbourOffset[(Hex.HexSide)side];
                        hexOffset      *= radius;
                        result.Position = pos + hexOffset;

                        // Check every possible rotation value.
                        for (int rotation = 0; rotation <= 5; ++rotation)
                        {
                            result.Orientation = rotation;

                            if (existingOrganelles.CanPlace(result))
                            {
                                return(result);
                            }
                        }
                    }
                }
            }
        }

        // We didnt find an open spot, this doesn't make much sense
        throw new ArgumentException("Mutation code could not find a good position " +
                                    "for a new organelle");
    }
コード例 #4
0
    /// <summary>
    ///   Wipes clean the current cell.
    /// </summary>
    public void CreateNewMicrobe()
    {
        if (!FreeBuilding)
        {
            throw new InvalidOperationException("can't reset cell when not freebuilding");
        }

        var previousMP = MutationPoints;
        var oldEditedMicrobeOrganelles = new OrganelleLayout <OrganelleTemplate>();
        var oldMembrane = Membrane;

        foreach (var organelle in editedMicrobeOrganelles)
        {
            oldEditedMicrobeOrganelles.Add(organelle);
        }

        var action = new EditorAction(this, 0,
                                      redo =>
        {
            MutationPoints = Constants.BASE_MUTATION_POINTS;
            Membrane       = SimulationParameters.Instance.GetMembrane("single");
            editedMicrobeOrganelles.RemoveAll();
            editedMicrobeOrganelles.Add(new OrganelleTemplate(GetOrganelleDefinition("cytoplasm"),
                                                              new Hex(0, 0), 0));
            gui.UpdateMembraneButtons(Membrane.InternalName);
            gui.UpdateSpeed(CalculateSpeed());
        },
                                      undo =>
        {
            editedMicrobeOrganelles.RemoveAll();
            MutationPoints = previousMP;
            Membrane       = oldMembrane;
            gui.UpdateMembraneButtons(Membrane.InternalName);
            gui.UpdateSpeed(CalculateSpeed());

            foreach (var organelle in oldEditedMicrobeOrganelles)
            {
                editedMicrobeOrganelles.Add(organelle);
            }
        });

        EnqueueAction(action);
    }
コード例 #5
0
ファイル: Microbe.Interior.cs プロジェクト: Shupsta/Thrive
    /// <summary>
    ///   Resets the organelles in this microbe to match the species definition
    /// </summary>
    public void ResetOrganelleLayout()
    {
        // TODO: It would be much better if only organelles that need
        // to be removed where removed, instead of everything.
        // When doing that all organelles will need to be re-added anyway if this turned from a prokaryote to eukaryote

        if (organelles == null)
        {
            organelles = new OrganelleLayout <PlacedOrganelle>(OnOrganelleAdded,
                                                               OnOrganelleRemoved);
        }
        else
        {
            // Just clear the existing ones
            organelles.Clear();
        }

        foreach (var entry in Species.Organelles.Organelles)
        {
            var placed = new PlacedOrganelle
            {
                Definition  = entry.Definition,
                Position    = entry.Position,
                Orientation = entry.Orientation,
            };

            organelles.Add(placed);
        }

        // Reproduction progress is lost
        allOrganellesDivided = false;

        // Unbind if a colony's master cell removed its binding agent.
        if (Colony != null && Colony.Master == this && !organelles.Any(p => p.IsBindingAgent))
        {
            Colony.RemoveFromColony(this);
        }
    }
コード例 #6
0
    /// <summary>
    ///   Wipes clean the current cell.
    /// </summary>
    public void CreateNewMicrobe()
    {
        if (!FreeBuilding)
        {
            throw new InvalidOperationException("can't reset cell when not freebuilding");
        }

        var previousMP = MutationPoints;
        var oldEditedMicrobeOrganelles = new OrganelleLayout <OrganelleTemplate>();

        foreach (var organelle in editedMicrobeOrganelles)
        {
            oldEditedMicrobeOrganelles.Add(organelle);
        }

        var action = new EditorAction(this, 0,
                                      redo =>
        {
            MutationPoints = Constants.BASE_MUTATION_POINTS;
            editedMicrobeOrganelles.RemoveAll();
            editedMicrobeOrganelles.Add(new OrganelleTemplate(GetOrganelleDefinition("cytoplasm"),
                                                              new Hex(0, 0), 0));
        },
                                      undo =>
        {
            editedMicrobeOrganelles.RemoveAll();
            MutationPoints = previousMP;

            foreach (var organelle in oldEditedMicrobeOrganelles)
            {
                editedMicrobeOrganelles.Add(organelle);
            }
        });

        EnqueueAction(action);
    }
コード例 #7
0
ファイル: MicrobeSpecies.cs プロジェクト: xuxudefeng/Thrive
 public MicrobeSpecies(uint id)
     : base(id)
 {
     Organelles = new OrganelleLayout <OrganelleTemplate>();
 }
コード例 #8
0
    /// <summary>
    ///   Creates a mutated version of parentOrganelles in organelles
    /// </summary>
    private void MutateMicrobeOrganelles(OrganelleLayout <OrganelleTemplate> parentOrganelles,
                                         OrganelleLayout <OrganelleTemplate> organelles, bool isBacteria)
    {
        var nucleus = SimulationParameters.Instance.GetOrganelleType("nucleus");

        organelles.Clear();

        // Delete or replace an organelle randomly
        for (int i = 0; i < parentOrganelles.Count; i++)
        {
            bool copy = true;

            var organelle = parentOrganelles[i];

            if (parentOrganelles.Count < 2)
            {
                // Removing last organelle would be silly
            }
            else if (organelle.Definition != nucleus)
            {
                // Chance to replace or remove if not a nucleus

                if (random.Next(0.0f, 1.0f) < Constants.MUTATION_DELETION_RATE)
                {
                    copy = false;
                }
                else if (random.Next(0.0f, 1.0f) < Constants.MUTATION_REPLACEMENT_RATE)
                {
                    copy = false;

                    var replacer = new OrganelleTemplate(GetRandomOrganelle(isBacteria),
                                                         organelle.Position, organelle.Orientation);

                    // The replacing organelle might not fit at the same position
                    try
                    {
                        organelles.Add(replacer);
                    }
                    catch (ArgumentException)
                    {
                        // Couldn't replace it
                        copy = true;
                    }
                }
            }

            if (!copy)
            {
                continue;
            }

            // Copy the organelle
            try
            {
                organelles.Add((OrganelleTemplate)organelle.Clone());
            }
            catch (ArgumentException)
            {
                // Add the organelle randomly back to the list to make
                // sure we don't throw it away
                AddNewOrganelle(organelles, organelle.Definition);
            }
        }

        // Can add up to 6 new organelles (Which should allow AI to catch up to player more
        // We can insert new organelles at the end of the list
        if (random.Next(0.0f, 1.0f) < Constants.MUTATION_CREATION_RATE)
        {
            AddNewOrganelle(organelles, GetRandomOrganelle(isBacteria));
        }

        /*
         * Probability of mutation occuring 5 time(s) = 0.15 = 1.0E-5
         * Probability of mutation NOT occuring = (1 - 0.1)5 = 0.59049
         * Probability of mutation occuring = 1 - (1 - 0.1)5 = 0.40951
         */

        // We can insert new organelles at the end of the list
        for (int n = 0; n < 5; ++n)
        {
            if (random.Next(0.0f, 1.0f) < Constants.MUTATION_EXTRA_CREATION_RATE)
            {
                AddNewOrganelle(organelles, GetRandomOrganelle(isBacteria));
            }
        }

        if (isBacteria)
        {
            if (random.Next(0.0f, 100.0f) <= Constants.MUTATION_BACTERIA_TO_EUKARYOTE)
            {
                AddNewOrganelle(organelles, nucleus);
            }
        }

        // Disallow creating empty species as that throws an exception when trying to spawn
        if (organelles.Count < 1)
        {
            // Add the first parent species organelle
            AddNewOrganelle(organelles, parentOrganelles[0].Definition);

            // If still empty, copy the first organelle of the parent
            if (organelles.Count < 1)
            {
                organelles.Add((OrganelleTemplate)parentOrganelles[0].Clone());
            }
        }
    }
コード例 #9
0
    /// <summary>
    ///   Creates a mutated version of parentOrganelles in organelles
    /// </summary>
    private void MutateMicrobeOrganelles(OrganelleLayout <OrganelleTemplate> parentOrganelles,
                                         OrganelleLayout <OrganelleTemplate> mutatedOrganelles, bool isBacteria)
    {
        var nucleus = SimulationParameters.Instance.GetOrganelleType("nucleus");

        for (var iteration = 0; iteration < 10; iteration++)
        {
            mutatedOrganelles.Clear();

            // Chance to replace each organelle randomly
            foreach (var parentOrganelle in parentOrganelles)
            {
                var organelle = (OrganelleTemplate)parentOrganelle.Clone();

                // Chance to replace or remove if not a nucleus
                if (organelle.Definition != nucleus)
                {
                    if (random.Next(0.0f, 1.0f) < Constants.MUTATION_DELETION_RATE / Math.Sqrt(parentOrganelles.Count))
                    {
                        // Don't copy over this organelle, removing this one from the new species
                        continue;
                    }

                    if (random.Next(0.0f, 1.0f) < Constants.MUTATION_REPLACEMENT_RATE)
                    {
                        organelle = new OrganelleTemplate(GetRandomOrganelle(isBacteria),
                                                          organelle.Position, organelle.Orientation);
                    }
                }

                // Copy the organelle
                try
                {
                    mutatedOrganelles.Add(organelle);
                }
                catch (ArgumentException)
                {
                    // Add the organelle randomly back to the list to make
                    // sure we don't throw it away
                    AddNewOrganelle(mutatedOrganelles, organelle.Definition);
                }
            }

            // We can insert new organelles at the end of the list
            for (int i = 0; i < 6; ++i)
            {
                if (random.Next(0.0f, 1.0f) < Constants.MUTATION_CREATION_RATE)
                {
                    AddNewOrganelle(mutatedOrganelles, GetRandomOrganelle(isBacteria));
                }
            }

            if (isBacteria)
            {
                if (random.Next(0.0f, 1.0f) <= Constants.MUTATION_BACTERIA_TO_EUKARYOTE)
                {
                    AddNewOrganelle(mutatedOrganelles, nucleus);
                }
            }

            // Disallow creating empty species as that throws an exception when trying to spawn
            if (mutatedOrganelles.Count < 1)
            {
                // Add the first parent species organelle
                AddNewOrganelle(mutatedOrganelles, parentOrganelles[0].Definition);

                // If still empty, copy the first organelle of the parent
                if (mutatedOrganelles.Count < 1)
                {
                    mutatedOrganelles.Add((OrganelleTemplate)parentOrganelles[0].Clone());
                }
            }

            // If the mutation has no islands, we can use this iteration
            if (mutatedOrganelles.GetIslandHexes().Count == 0)
            {
                return;
            }
        }

        GD.PrintErr("Could not create a valid mutation after 10 retries.");
    }
コード例 #10
0
ファイル: MicrobeSpecies.cs プロジェクト: Generatoror/Thrive
 public MicrobeSpecies(uint id, string genus, string epithet) : base(id, genus, epithet)
 {
     Organelles = new OrganelleLayout <OrganelleTemplate>();
 }
コード例 #11
0
    /// <summary>
    ///   Combined old editor init and activate method
    /// </summary>
    private void InitEditor()
    {
        // For now we only show a loading screen if auto-evo is not ready yet
        if (!CurrentGame.GameWorld.IsAutoEvoFinished())
        {
            ready = false;
            gui.SetLoadingStatus(true);
            gui.SetLoadingText("Loading Microbe Editor", CurrentGame.GameWorld.GetAutoEvoRun().Status);
        }
        else
        {
            OnEditorReady();
        }

        MutationPoints          = Constants.BASE_MUTATION_POINTS;
        editedMicrobeOrganelles = new OrganelleLayout <OrganelleTemplate>(
            OnOrganelleAdded, OnOrganelleRemoved);

        organelleRot = 0;

        Symmetry = 0;
        gui.ResetSymmetryButton();

        UpdateUndoRedoButtons();

        // The world is reset each time so these are gone
        placedHexes  = new List <MeshInstance>();
        placedModels = new List <SceneDisplayer>();

        // Check generation and set it here.

        CurrentGame.SetBool("edited_microbe", true);

        if (CurrentGame.FreeBuild)
        {
            GD.Print("Editor going to freebuild mode because player has activated freebuild");
            FreeBuilding = true;
        }
        else
        {
            // Make sure freebuilding doesn't get stuck on
            FreeBuilding = false;
        }

        // Sent freebuild value to GUI
        gui.NotifyFreebuild(FreeBuilding);

        playerPatchOnEntry = CurrentGame.GameWorld.Map.CurrentPatch;

        // Send info to the GUI about the organelle effectiveness in the current patch
        CalculateOrganelleEffectivenessInPatch();

        // Reset this, GUI will tell us to enable it again
        ShowHover   = false;
        targetPatch = null;

        canStillMove = true;

        UpdatePatchBackgroundImage();

        gui.SetMap(CurrentGame.GameWorld.Map);

        var playerSpecies = CurrentGame.GameWorld.PlayerSpecies;

        SetupEditedSpecies(playerSpecies as MicrobeSpecies);

        gui.UpdateGlucoseReduction(Constants.GLUCOSE_REDUCTION_RATE);
    }