/// <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"); } }
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; }