Пример #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;
    }
Пример #2
0
    public override IEnumerable <ISpawned> Spawn(Node worldNode, Vector3 location)
    {
        var chunk = SpawnHelpers.SpawnChunk(chunkType, location, worldNode, chunkScene,
                                            cloudSystem, random);

        yield return(chunk);
    }
Пример #3
0
    public override IEnumerable <ISpawned> Spawn(Node worldNode, Vector3 location)
    {
        SpawnHelpers.SpawnCloud(clouds, location, compound, amount);

        // We don't spawn entities
        return(null);
    }
Пример #4
0
 void spawnExpandWeapon()
 {
     if (weaponsActiveCount < maxAllowedWeapons)
     {
         weaponsActiveCount++;
         Vector3 pos = SpawnHelpers.GetRandomLocation(walls, player);
         Instantiate(expandWeapon, pos, Quaternion.Euler(Vector3.zero));
     }
 }
Пример #5
0
 void spawnShield()
 {
     if (weaponsActiveCount < maxAllowedWeapons)
     {
         weaponsActiveCount++;
         Vector3 pos = SpawnHelpers.GetRandomLocation(walls, player);
         Instantiate(shieldWeapon, pos, Quaternion.Euler(new Vector3(90, 0, 0)));
     }
 }
Пример #6
0
    public override IEnumerable <ISpawned> Spawn(Node worldNode, Vector3 location)
    {
        var chunk = SpawnHelpers.SpawnChunk(chunkType, location, worldNode, chunkScene,
                                            cloudSystem, random);

        yield return(chunk);

        ModLoader.ModInterface.TriggerOnChunkSpawned(chunk, true);
    }
Пример #7
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();
    }
Пример #8
0
    IEnumerator ShieldCoroutine()
    {
        yield return(new WaitForSeconds(SpawnHelpers.GetInitialShieldDelay()));

        while (true)
        {
            spawnShield();
            yield return(new WaitForSeconds(shieldSpawnDelay));
        }
    }
Пример #9
0
    IEnumerator ExpandCoroutine()
    {
        yield return(new WaitForSeconds(SpawnHelpers.GetInitialExpandDelay()));

        while (true)
        {
            spawnExpandWeapon();
            yield return(new WaitForSeconds(expandSpawnDelay));
        }
    }
Пример #10
0
    IEnumerator ExplosiveCoroutine()
    {
        yield return(new WaitForSeconds(SpawnHelpers.GetInitialExplosiveDelay()));

        while (true)
        {
            spawnExplosive();
            yield return(new WaitForSeconds(explosiveSpawnDelay));
        }
    }
Пример #11
0
    public override List <ISpawned> Spawn(Node worldNode, Vector3 location)
    {
        var entities = new List <ISpawned>();

        var chunk = SpawnHelpers.SpawnChunk(chunkType, location, worldNode, chunkScene,
                                            cloudSystem, random);

        entities.Add(chunk);
        return(entities);
    }
Пример #12
0
    void spawnEnemy()
    {
        Vector3    pos          = SpawnHelpers.GetRandomLocation(walls, player);
        GameObject spawnedEnemy = Instantiate(enemy, pos, Quaternion.Euler(Vector3.zero));

        if (DifficultyManager.difficulty == (int)Difficulty.EASY)
        {
            spawnedEnemy.GetComponent <EnemyMovement>().setSpeed(4f);
        }
        if (DifficultyManager.difficulty == (int)Difficulty.MEDIUM)
        {
            spawnedEnemy.GetComponent <EnemyMovement>().setSpeed(6f);
        }
    }
Пример #13
0
    void SpawnRandomObstacle()
    {
        int   rand             = Random.Range(0, 11);
        float timeSinceStarted = Time.time - TimeElapsed.initialTime;

        if (rand == 1 || rand == 5 || rand == 8)
        {
            StartCoroutine(spawnCircle(Random.Range(4f, 8f)));
        }
        else if (rand == 2 && (timeSinceStarted > 60 || GameManager.score > 7000))
        {
            Debug.Log("spawned double vertical wall at time: " + timeSinceStarted + " and score: " + GameManager.score);
            spawnDoubleVerticalWall(0.7f);
            obstacleSpawnDelay += 2f;
            enemySpawnDelay    += 0.5f;
            spawnExplosive();
        }
        else if (rand == 7 && (timeSinceStarted > 60 || GameManager.score > 7000))
        {
            Debug.Log("spawned double horizontal wall at time: " + timeSinceStarted + " and score: " + GameManager.score);
            spawnDoubleHorizontalWall(0.7f);
            obstacleSpawnDelay += 2f;
            enemySpawnDelay    += 0.5f;
            spawnExplosive();
        }
        else if (rand == 6 && (timeSinceStarted > 90 || GameManager.score > 10000))
        {
            Debug.Log("spawned 4 walls at time: " + timeSinceStarted + " and score: " + GameManager.score);
            spawnDoubleVerticalWall(0.5f);
            spawnDoubleHorizontalWall(0.5f);
            obstacleSpawnDelay += 5f;
            enemySpawnDelay    += 1f;
            spawnShield();
        }
        else if (rand == 3 && (timeSinceStarted > 45 || GameManager.score > 3000))
        {
            spawnVerticalWall(Random.Range(0, 2) == 0 ? "right" : "left", 1.5f, (DifficultyManager.difficulty == 2) ? 1.5f : 1f);
        }
        else if (rand == 4 && (timeSinceStarted > 45 || GameManager.score > 3000))
        {
            spawnHorizontalWall(Random.Range(0, 2) == 0 ? "up" : "down", (DifficultyManager.difficulty == 2) ? 1.5f : 1f);
        }
        else
        {
            instantSpawnEnemies(SpawnHelpers.GetRangeForInstantSpawn());
        }
    }
Пример #14
0
    public override IEnumerable <ISpawned> Spawn(Node worldNode, Vector3 location)
    {
        // The true here is that this is AI controlled
        var first = SpawnHelpers.SpawnMicrobe(species, location, worldNode, microbeScene, true, cloudSystem,
                                              currentGame);

        yield return(first);

        if (first.Species.IsBacteria)
        {
            foreach (var colonyMember in SpawnHelpers.SpawnBacteriaColony(species, location, worldNode, microbeScene,
                                                                          cloudSystem, currentGame, random))
            {
                yield return(colonyMember);
            }
        }
    }
Пример #15
0
    public override List <ISpawned> Spawn(Node worldNode, Vector3 location)
    {
        var entities = new List <ISpawned>();

        // The true here is that this is AI controlled
        var microbe = SpawnHelpers.SpawnMicrobe(species, location, worldNode, microbeScene,
                                                true, cloudSystem, currentGame);

        if (microbe.Species.IsBacteria)
        {
            SpawnHelpers.SpawnBacteriaColony(species, location, worldNode, microbeScene,
                                             cloudSystem, currentGame, random, entities);
        }

        entities.Add(microbe);
        return(entities);
    }
Пример #16
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;
    }
Пример #17
0
    IEnumerator spawnCircle(float radius = 8.0f)
    {
        if (player.activeInHierarchy)
        {
            Vector3 pos;

            for (int i = 0; i < 360; i += 45)
            {
                pos.x = player.transform.position.x + radius * Mathf.Sin(i * Mathf.Deg2Rad);
                pos.y = 0f;
                pos.z = player.transform.position.z + radius * Mathf.Cos(i * Mathf.Deg2Rad);

                if (SpawnHelpers.InsideTheWall(pos, walls))
                {
                    Instantiate(enemy, pos, Quaternion.Euler(Vector3.zero));
                }
                yield return(new WaitForSeconds(0.1f));
            }
        }
    }
Пример #18
0
        private static void HandleRunLevelChanged(object sender, RunLevelChangedEventArgs args)
        {
            switch (args.NewLevel)
            {
            case ServerRunLevel.PreGame:
                var timing = IoCManager.Resolve <IGameTiming>();

                IoCManager.Resolve <IPlayerManager>().FallbackSpawnPoint = new LocalCoordinates(0, 0, GridId.DefaultGrid, new MapId(2));

                var mapLoader = IoCManager.Resolve <IMapLoader>();
                var mapMan    = IoCManager.Resolve <IMapManager>();

                var startTime = timing.RealTime;
                {
                    var newMap = mapMan.CreateMap(new MapId(2));

                    mapLoader.LoadBlueprint(newMap, new GridId(4), "Maps/Demo/DemoGrid.yaml");

                    var grid = newMap.GetGrid(new GridId(4));
                    SpawnHelpers.SpawnLightTurret(grid, new Vector2(-15, 15));
                }
                var timeSpan = timing.RealTime - startTime;
                Logger.Info($"Loaded map in {timeSpan.TotalMilliseconds:N2}ms.");

                IoCManager.Resolve <IChatManager>().DispatchMessage(ChatChannel.Server, "Gamemode: Round loaded!");
                break;

            case ServerRunLevel.Game:
                IoCManager.Resolve <IPlayerManager>().SendJoinGameToAll();
                IoCManager.Resolve <IChatManager>().DispatchMessage(ChatChannel.Server, "Gamemode: Round started!");
                break;

            case ServerRunLevel.PostGame:
                IoCManager.Resolve <IChatManager>().DispatchMessage(ChatChannel.Server, "Gamemode: Round over!");
                break;
            }
        }
Пример #19
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;
    }
Пример #20
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");
    }
Пример #21
0
    /// <summary>
    ///   Tries to fire a toxin if possible
    /// </summary>
    public void EmitToxin(Compound agentType = null)
    {
        if (AgentEmissionCooldown > 0)
        {
            return;
        }

        // Only shoot if you have an agent vacuole.
        if (AgentVacuoleCount < 1)
        {
            return;
        }

        agentType ??= SimulationParameters.Instance.GetCompound("oxytoxy");

        float amountAvailable = Compounds.GetCompoundAmount(agentType);

        // Emit as much as you have, but don't start the cooldown if that's zero
        float amountEmitted = Math.Min(amountAvailable, Constants.MAXIMUM_AGENT_EMISSION_AMOUNT);

        if (amountEmitted < Constants.MINIMUM_AGENT_EMISSION_AMOUNT)
        {
            return;
        }

        Compounds.TakeCompound(agentType, amountEmitted);

        // The cooldown time is inversely proportional to the amount of agent vacuoles.
        AgentEmissionCooldown = Constants.AGENT_EMISSION_COOLDOWN / AgentVacuoleCount;

        float ejectionDistance = Membrane.EncompassingCircleRadius +
                                 Constants.AGENT_EMISSION_DISTANCE_OFFSET;

        if (Species.IsBacteria)
        {
            ejectionDistance *= 0.5f;
        }

        var props = new AgentProperties();

        props.Compound = agentType;
        props.Species  = Species;

        // Find the direction the microbe is facing
        var direction = (LookAtPoint - Translation).Normalized();

        var position = Translation + (direction * ejectionDistance);

        var agent = SpawnHelpers.SpawnAgent(props, amountEmitted, Constants.EMITTED_AGENT_LIFETIME,
                                            position, direction, GetStageAsParent(),
                                            SpawnHelpers.LoadAgentScene(), this);

        ModLoader.ModInterface.TriggerOnToxinEmitted(agent);

        if (amountEmitted < Constants.MAXIMUM_AGENT_EMISSION_AMOUNT / 2)
        {
            PlaySoundEffect("res://assets/sounds/soundeffects/microbe-release-toxin-low.ogg");
        }
        else
        {
            PlaySoundEffect("res://assets/sounds/soundeffects/microbe-release-toxin.ogg");
        }
    }
Пример #22
0
 public ChunkSpawner(ChunkConfiguration chunkType, CompoundCloudSystem cloudSystem)
 {
     this.chunkType   = chunkType;
     this.cloudSystem = cloudSystem;
     chunkScene       = SpawnHelpers.LoadChunkScene();
 }