Exemple #1
0
    /// <summary>
    ///   Spawns the player if there isn't currently a player node existing
    /// </summary>
    public void SpawnPlayer()
    {
        if (Player != null)
        {
            return;
        }

        Player = SpawnHelpers.SpawnMicrobe(GameWorld.PlayerSpecies, new Vector3(0, 0, 0),
                                           rootOfDynamicallySpawned, SpawnHelpers.LoadMicrobeScene(), false, Clouds,
                                           CurrentGame);
        Player.AddToGroup("player");

        Player.OnDeath = OnPlayerDied;

        Player.OnReproductionStatus = OnPlayerReproductionStatusChanged;

        Camera.ObjectToFollow = Player;

        if (spawnedPlayer)
        {
            // Random location on respawn
            var random = new Random();
            Player.Translation = new Vector3(
                random.Next(Constants.MIN_SPAWN_DISTANCE, Constants.MAX_SPAWN_DISTANCE), 0,
                random.Next(Constants.MIN_SPAWN_DISTANCE, Constants.MAX_SPAWN_DISTANCE));
        }

        TutorialState.SendEvent(TutorialEventType.MicrobePlayerSpawned, new MicrobeEventArgs(Player), this);

        spawnedPlayer      = true;
        playerRespawnTimer = Constants.PLAYER_RESPAWN_TIME;
    }
Exemple #2
0
    public MicrobeSpawner(Species species, CompoundCloudSystem cloudSystem, GameProperties currentGame)
    {
        this.species = species ?? throw new ArgumentException("species is null");

        microbeScene     = SpawnHelpers.LoadMicrobeScene();
        this.cloudSystem = cloudSystem;
        this.currentGame = currentGame;

        random = new Random();
    }
Exemple #3
0
    /// <summary>
    ///   Spawns the player if there isn't currently a player node existing
    /// </summary>
    public void SpawnPlayer()
    {
        if (Player != null)
        {
            return;
        }

        Player = SpawnHelpers.SpawnMicrobe(GameWorld.PlayerSpecies, new Vector3(0, 0, 0),
                                           rootOfDynamicallySpawned, SpawnHelpers.LoadMicrobeScene(), false, Clouds,
                                           CurrentGame);
        Player.AddToGroup("player");

        Player.OnDeath = (microbe) =>
        {
            GD.Print("The player has died");
            Player = null;
            Camera.ObjectToFollow = null;
        };

        Player.OnReproductionStatus = (microbe, ready) =>
        {
            if (ready)
            {
                HUD.ShowReproductionDialog();
            }
            else
            {
                HUD.HideReproductionDialog();
            }
        };

        Camera.ObjectToFollow = Player;

        if (spawnedPlayer)
        {
            // Random location on respawn
            var random = new Random();
            Player.Translation = new Vector3(
                random.Next(Constants.MIN_SPAWN_DISTANCE, Constants.MAX_SPAWN_DISTANCE), 0,
                random.Next(Constants.MIN_SPAWN_DISTANCE, Constants.MAX_SPAWN_DISTANCE));
        }

        spawnedPlayer      = true;
        playerRespawnTimer = Constants.PLAYER_RESPAWN_TIME;
    }
Exemple #4
0
    /// <summary>
    ///   Triggers reproduction on this cell (even if not ready)
    ///   Ignores security checks. If you want those checks, use <see cref="Divide"/>
    /// </summary>
    public void ForceDivide()
    {
        // Separate the two cells.
        var separation = new Vector3(Radius, 0, 0);

        // Create the one daughter cell.
        var copyEntity = SpawnHelpers.SpawnMicrobe(Species, Translation + separation,
                                                   GetParent(), SpawnHelpers.LoadMicrobeScene(), true, cloudSystem, CurrentGame);

        // Make it despawn like normal
        SpawnSystem.AddEntityToTrack(copyEntity);

        // Remove the compounds from the created cell
        copyEntity.Compounds.ClearCompounds();

        var keys = new List <Compound>(Compounds.Compounds.Keys);
        var reproductionCompounds = copyEntity.CalculateTotalCompounds();

        // Split the compounds between the two cells.
        foreach (var compound in keys)
        {
            var amount = Compounds.GetCompoundAmount(compound);

            if (amount <= 0)
            {
                continue;
            }

            // If the compound is for reproduction we give player and NPC microbes different amounts.
            if (reproductionCompounds.TryGetValue(compound, out float divideAmount))
            {
                // The amount taken away from the parent cell depends on if it is a player or NPC. Player
                // cells always have 50% of the compounds they divided with taken away.
                float amountToTake = amount * 0.5f;

                if (!IsPlayerMicrobe)
                {
                    // NPC parent cells have at least 50% taken away, or more if it would leave them
                    // with more than 90% of the compound it would take to immediately divide again.
                    amountToTake = Math.Max(amountToTake, amount - (divideAmount * 0.9f));
                }

                Compounds.TakeCompound(compound, amountToTake);

                // Since the child cell is always an NPC they are given either 50% of the compound from the
                // parent, or 90% of the amount required to immediately divide again, whichever is smaller.
                float amountToGive  = Math.Min(amount * 0.5f, divideAmount * 0.9f);
                var   addedCompound = copyEntity.Compounds.AddCompound(compound, amountToGive);

                if (addedCompound < amountToGive)
                {
                    // TODO: handle the excess compound that didn't fit in the other cell
                }
            }
            else
            {
                // Non-reproductive compounds just always get split evenly to both cells.
                Compounds.TakeCompound(compound, amount * 0.5f);

                var amountAdded = copyEntity.Compounds.AddCompound(compound, amount * 0.5f);

                if (amountAdded < amount)
                {
                    // TODO: handle the excess compound that didn't fit in the other cell
                }
            }
        }

        // Play the split sound
        PlaySoundEffect("res://assets/sounds/soundeffects/reproduction.ogg");
    }
Exemple #5
0
    private void RespawnEntitiesFromSave(MicrobeStage savedMicrobeStage)
    {
        if (savedMicrobeStage.Player != null && !savedMicrobeStage.Player.Dead)
        {
            SpawnPlayer();
            Player.ApplyPropertiesFromSave(savedMicrobeStage.Player);
        }

        if (savedGameEntities == null)
        {
            GD.PrintErr("Saved microbe stage contains no entities to load");
            return;
        }

        var microbeScene = SpawnHelpers.LoadMicrobeScene();
        var chunkScene   = SpawnHelpers.LoadChunkScene();
        var agentScene   = SpawnHelpers.LoadAgentScene();

        // This only should be used for things that get overridden anyway from the saved properties
        var random = new Random();

        foreach (var thing in savedGameEntities)
        {
            // Skip the player as it was already loaded
            if (thing == savedMicrobeStage.Player)
            {
                continue;
            }

            switch (thing)
            {
            case Microbe casted:
            {
                var spawned = SpawnHelpers.SpawnMicrobe(casted.Species, Vector3.Zero, rootOfDynamicallySpawned,
                                                        microbeScene, !casted.IsPlayerMicrobe, Clouds, CurrentGame);
                spawned.ApplyPropertiesFromSave(casted);
                break;
            }

            case FloatingChunk casted:
            {
                var spawned = SpawnHelpers.SpawnChunk(casted.CreateChunkConfigurationFromThis(),
                                                      casted.Translation, rootOfDynamicallySpawned, chunkScene, Clouds, random);
                spawned.ApplyPropertiesFromSave(casted);
                break;
            }

            case AgentProjectile casted:
            {
                var spawned = SpawnHelpers.SpawnAgent(casted.Properties, casted.Amount, casted.TimeToLiveRemaining,
                                                      casted.Translation, Vector3.Forward, rootOfDynamicallySpawned, agentScene, null);
                spawned.ApplyPropertiesFromSave(casted);

                // TODO: mapping from old microbe to recreated microbe to set emitter here
                break;
            }

            default:
                GD.PrintErr("Unknown entity type to load from save: ", thing.GetType());
                break;
            }
        }

        // Clear this to make saving again work
        savedGameEntities = null;
    }