/// <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; }
public override IEnumerable <ISpawned> Spawn(Node worldNode, Vector3 location) { var chunk = SpawnHelpers.SpawnChunk(chunkType, location, worldNode, chunkScene, cloudSystem, random); yield return(chunk); }
public override IEnumerable <ISpawned> Spawn(Node worldNode, Vector3 location) { SpawnHelpers.SpawnCloud(clouds, location, compound, amount); // We don't spawn entities return(null); }
void spawnExpandWeapon() { if (weaponsActiveCount < maxAllowedWeapons) { weaponsActiveCount++; Vector3 pos = SpawnHelpers.GetRandomLocation(walls, player); Instantiate(expandWeapon, pos, Quaternion.Euler(Vector3.zero)); } }
void spawnShield() { if (weaponsActiveCount < maxAllowedWeapons) { weaponsActiveCount++; Vector3 pos = SpawnHelpers.GetRandomLocation(walls, player); Instantiate(shieldWeapon, pos, Quaternion.Euler(new Vector3(90, 0, 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); }
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(); }
IEnumerator ShieldCoroutine() { yield return(new WaitForSeconds(SpawnHelpers.GetInitialShieldDelay())); while (true) { spawnShield(); yield return(new WaitForSeconds(shieldSpawnDelay)); } }
IEnumerator ExpandCoroutine() { yield return(new WaitForSeconds(SpawnHelpers.GetInitialExpandDelay())); while (true) { spawnExpandWeapon(); yield return(new WaitForSeconds(expandSpawnDelay)); } }
IEnumerator ExplosiveCoroutine() { yield return(new WaitForSeconds(SpawnHelpers.GetInitialExplosiveDelay())); while (true) { spawnExplosive(); yield return(new WaitForSeconds(explosiveSpawnDelay)); } }
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); }
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); } }
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()); } }
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); } } }
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); }
/// <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; }
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)); } } }
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; } }
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; }
/// <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"); }
/// <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"); } }
public ChunkSpawner(ChunkConfiguration chunkType, CompoundCloudSystem cloudSystem) { this.chunkType = chunkType; this.cloudSystem = cloudSystem; chunkScene = SpawnHelpers.LoadChunkScene(); }